Arc Forumnew | comments | leaders | submitlogin
2 points by sjs 6121 days ago | link | parent

I think it's important to distinguish between what's read and what's executed. The reader translates [] into (make-br-fn '()), which expands to (fn (_) ()). I am totally stumped as to what (fn (_ (fn (_) nil)) (_ 'bar (fn (_) nil))) could or should mean. It seems as if you are thinking about [] as a symbol in [_ 'bar []] => (fn (_ []) (_ 'bar [])), but that is confusing. When thinking about [...] on this level we should be thinking in terms of the actual sexps evaluated. Translating [] to (fn (_) nil) outside [...] and to something else inside them is a road to madness and some serious reader hacking.

[] never expands to a function of zero arguments. ([]) is an error, too few arguments.

[nil] is not the always nil function. I had the same misconception at first, that the ... in [...] is the body of the fn, but (...) is the real body. The [] are simply replaced with (), so the body is always a function application and never an atom, save for the special case of [] -> () -> nil. [] and [idfn nil] are 2 always-nil functions, but the fact that [] is always nil is a consequence of [] expanding to (fn (_) ()) and nil being the empty list in Arc.

  arc> (macex '[nil])
  (fn (_) (nil))
  arc> ([nil] 3)
  Error: "Function call on inappropriate object nil ()"


2 points by absz 6121 days ago | link

I agree with your general premise, but I have one correction--in arc0.tar, [...] expands directly to (fn (_) (...)). It's only in the git repository that it expands to (make-br-fn (...)) (which (semi-incidentally :P) I added, but that's not the point). Regardless, your point still stands, and I agree.

-----

1 point by sjs 6121 days ago | link

Thank you for the correction. While spouting all that I forgot about the extra stuff that make-br-fn does.

-----

1 point by almkglor 6121 days ago | link

make-br-fn allows you to use _1 _2 ... _n (it searches for the n AFAIK) as well as __. If you use _n you get a n-arity function. If you use _n and __, you get a >=n-arity function, with __ containing the rest. I have a few reservations about whether it handles checking of free variables properly but I haven't actually dived into the code.

-----

1 point by absz 6121 days ago | link

make-br-fn doesn't search for a literal _n, but it searches for anything matching the regexp /_(\d+|_)?/, except for anything of the form /_0+/. The free-variable checking code is based off of problems I did while working through Essentials of Programming Languages by Friedman, Wand, and Haynes, and it certainly shouldn't break in most common cases (especially since most common cases won't bind any extra variables). A second set of eyes is probably a good idea, though.

-----