Hi Daniel, On Jan 16, 6:54 pm, Daniel Jomphe <danieljom...@gmail.com> wrote: > I'll tell you my current understanding of how Clojure works, so you > can correct me where I may be wrong: > > - The compiler has for target a living environment; thus, it's > dynamic. > - There's no interpreter; thus, the following points will be easier to > reason about. > - When code is sent for evaluation, it's first read. > - The reader performs a few substitutions, then gives the resulting > code to the compiler. > - The compiler starts by expanding macros into their substitution. > --- Thus, for functions, there's no such thing as macros. > --- Thus, all that functions see of macros is what came out of macros' > complete expansion. > --- Therefore, like Timothy Pratley wrote so well, a function can have > for parameter a macro call, but not a macro itself.
All correct up to this point. > - After macro expansion, the compiler starts compiling all functions > in need of being compiled, including the functions modified during > macro expansion. Sort of. What's really getting compiled are just the function calls. The functions themselves were compiled back when they were defined. > - Then, code is ready for evaluation. Yes, and at this point, Clojure has done its job and the Java Virtual Machine takes over. > Ok, so although it's a live system, when a new bunch of code is sent > for evaluation, all macros inside it must be expanded before runtime > evaluation can occur. Thus, functions can't act on macros. I thought > that somehow my code could still work because what would have happened > is 'reduce' would have acted on 'and's expansion, but I see and's > expansion couldn't be done because it would have to wait for reduce's > evaluation. > > If we were speaking of concurrency, wouldn't this be a deadlock issue? Not really, because macro expansion is not happening concurrently with compilation or evaluation. > ...I also thought it could be possible that 'and' expands to a partial > application that waits for 'reduce' to provide it its arguments. > Wouldn't this make sense? No, because "and" doesn't know how many arguments it's going to get. If you look at the definition of "and", you'll see that it takes a variable number of arguments and it is recursive. So if you tried to expand it before knowing the length of the argument list, you would get an infinite loop. > Konrad Hinsen said: > > > The universal workaround is to define a > > function that contains nothing but the macro, such as > > > (fn [x y] (and x y)) > > > which can also be written in Clojure using the shorthand notation > > > #(and %1 %2) > > > Here the macro gets expanded inside the function *body*, but what you > > pass around is the function *object*. > > Wouldn't this defeat the purpose of having 'and's arguments short- > circuited when false is found? Yes, but there is no alternative if you want a function. > > Now, why is this workaround possible? For sure, the wrapper function > is ok as a parameter of a function call. And in the called function's > body, when it's going to call the wrapper function, the arguments for > the macro wrapped in the wrapper function will be ready. And the > wrapper function contains the macro's substitution anyways. So if > we're willing to sacrifice macros' lazy parameters evaluation, we can > wrap them inside functions to achieve this effect. We could also say > that as long as macros are either called or wrapped in any function, > they can go anywhere. In other words, the only limitation seems to be > that runtime code can't use the symbol to which a macro is binded. Again, sort of. Some macros examine their arguments to decide what kind of code to produce, and some depend on lazy evaluation, like "and" or "cond". These macros cannot simply be wrapped in functions. -Stuart Sierra --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---