Arc Forumnew | comments | leaders | submitlogin
6 points by absz 6018 days ago | link | parent

The problem lies in the split between how Arc and mzscheme represent lists. Arc essentially uses iso to compare table keys (iso compares lists by structure, so while (isnt (list 'cons) (list 'cons)), (iso (list 'cons) (list 'cons))). Thus both your examples should work.

The problem lies in the definition of lists. (I'm explaining this from the beginning because I don't know what your skill level is; if you know how lists work, then please skip the rest of this paragraph.) Lists are composed of cons cells, each of which is essentially an ordered pair of a car and a cdr. The car holds the value, and in a list, the cdr must be another list. So what do you use to represent the empty list?

This is where the problem lies: in mzscheme, () is the empty list, and 'nil is just a symbol. In Arc, nil is a symbol that is also the empty list. Thus, we get

  arc> vtable
  #hash(((cons) . a-method))
  arc> (= (vtable '(cons)) 'another-method)
  another-method
  arc> vtable
  #hash(((cons) . a-method) ((cons . nil) . another-method))
Note that the two keys are different: the first key is a Scheme list, ending in (), whereas the second is an Arc list, ending in nil. What's happening becomes clearer when we look at the definition of list (Anarki docstring omitted for clarity):

  (def list args
    args)
So as far as I understand it, when an Arc function with a variadic parameter (like list) is called, the arguments are passed to it as a Scheme list instead of an Arc list. Usually this is transparent, since Arc tries to convert () to nil on the Arc side, and nil to () on the mzscheme side.[1] However, it's not perfect, and here's one of the places where that shows up.

I didn't see an easy fix inside ac.scm, and don't have the time to keep looking. However, now I'm worried that that's going to trip me up sometime in the future... The only solution I can think of is to explicitly call ac.scm's ac-nil function, which performs the translation from () to nil, but this is (a) very ugly, and (b) only works on Anarki. For what it's worth, though, here it is (where $ is Anarki's macro for accessing mzscheme):

  arc> (= vtable (table))
  #hash()
  arc> (= (vtable ($.ac-niltree (list (type '(1))))) 'a-method)
  a-method
  arc> vtable
  #hash(((cons . nil) . a-method))
  arc> (vtable '(cons))
  a-method
  arc> (vtable ($.ac-niltree (list 'cons)))
  a-method
  arc> (vtable (list 'cons))
  nil
I hope that helps, but I hope even more that this bug gets fixed. (I, unfortunately, have external obligations and can't continue chasing it down.)

[1]: It also tries to convert #f and nil, but that's not relevant for your problem.



2 points by zhtw 6018 days ago | link

Thanks for the detailed explanation. I got the idea. Well, in my case this is going to stay deep inside the library. So any workaround would be fine.

But I solved this by adding (join ... nil).

-----

2 points by absz 6018 days ago | link

That is a much nicer in-Arc solution than mine; good catch. In any case, I'm glad I could be of assistance.

-----