Hello, I have been toying with arc and lurking on the forum for a while now and over the holidays decided to take a really close look. From that, I have a few questions which I hope some of you can answer. I hope none of them are too stupid :-) Here goes: 1. I'm not fully understanding the distinction between functions and macros. Take for example the definition of when:
(mac when (test . body)
`(if ,test (do ,@body))) Easily comprehensible if you have read the tutorial. However, my naive mind thinks the same effect should also be able to be achieved with a function. My fisrt attempt was simply (def when1 (test . body)
`(if ,test (do ,@body))) but of course, since functions by definition return the result of evaluating the last expression in their body, this simply returns the list starting with "if" which the macro would have inserted into the code. However, when you do this (def when2 (test . body)
(if test (do body))) you get a function when2 which does the same thing as the macro when, but gives different return values: >(when2 1 (= a 3) (= b 2))
(3 2)
>a
3
>b
2
whereas >(when 1 (= r 3) (= p 2))
2
>r
3
>p
2
I'm probably missing something or using a bad example, but from this, I can't see the magic of lisp macros.. Maybe an experienced lisper can show me the light.. is there a fundamental (or practical) difference between the two approaches outlined above? (or is the fact that they have different return values more important than I seem to realize)?Why was a macro used to define when and not a function? Similarly in defining in, why can't we use something like >(def in (x . choices)
(some x choices))
instead of the more complicated (to me at least) macro used now?2. In the definition of pair, I think (list (f (car xs))) would produce more consistent behavior than the current (list (list (car xs))). Currently, if you do something like >(pair '(1 3 5 7 9) +)
(4 12 (9))
where one (or at least I) would expect (4 12 9) to be returned. Of course, this would give errors if the passed function requires two arguments, but I would say you should just watch out not to call it on a list with an odd number of elements. Any thoughts?3. In the definition of w/uniq, why is + used instead of join? It seems strange to define join when + can do the same job. 4. In the definition of reclist, wouldn't it be easier to put f:car in the definition, and save some :car's in the definitions of some, mem, and find? 5. I'm new to lisp, and don't have a CS background, but I thought the whole point of trying to get tail recursion was so that a compiler can take a recursive definition and transform it into a more efficient loop. Given that, isn't it a little backwards to define the loop macro using an anonymous, recursive function? Or is efficiency not the primary goal here? (I would also think an imperative implementation would be more readable, but perhaps I just haven't read enough lisp yet :-) ). 6. In many of the .arc files, there are names appended with asterisks, often things that would remain constant. Is there any specific significance to this? [edit: code formatting] |