On Fri, Apr 9, 2010 at 11:26 AM, Douglas Philips <d...@mac.com> wrote:
> On 2010 Apr 8, at 11:48 PM, Per Vognsen wrote:
>>
>> The body of fn is still compiled in an expression context. When the
>> compiler sees (fn [...] ...), it will introduce the bindings into the
>> local environment and recursively compile the body in that
>> environment. Note that I said compile rather than evaluate. If you
>> make a phase distinction between compile time and run time, all this
>> should be easier to understand.
>
> Yes, I knew there was another "time" involved, but not now to get access to
> that in my own code. :)
>
>
>> If you're still confused, check out Compiler.java. The code is very
>> simple and everything is right there.
>
> I've come to clojure with Lisp, C, C++, Python, Forth... roots.
> Java, not so much. But I'll look. Thank you for the explanations.

I didn't really do any Java programming before coming to Clojure.
Rich's Java coding style is so unorthodox (mostly in a good way) that
you probably have an advantage over Java programmers in reading his
code. When I started learning Clojure last month, one of my points of
confusion was indeed symbol resolution, and I cleared it up to my own
satisfaction by reading Compiler.java.

>
>> Macro expansion happens (and has to happen) before everything I
>> described above. Your macro will see symbols, not vars.
>
> Yes, I understood that part.
>
>> If the macro splices some of the symbols into places that after all macro
>> expansion
>> are in expression context, they will be resolved into vars. You
>> generally don't have to invoke the resolution machinery yourself as
>> long as you do that.
>
> Understood. The macro is going to store the unevaluated form (probably into
> a list, maybe into a map), and then other code is going to walk and mutate
> it before it (eventually) gets evaluated. I'd like to check the form before
> any further processing happens on it, so it sounds like what I need is a
> tree walker that just checks resolve's return value as a side effect.

I'm not convinced you need to do that. Macro expansion is interleaved
with compilation. I'm very doubtful you need resolution to happen at
macro expansion time rather than compile time proper. Anyway, I'll let
you learn by trial and error. Maybe you'll prove me wrong. :)

There was something I had wanted to mention previously but forgot. If
you're ever confused about whether something counts as expression
context, think about whether macro expansion would take place there.
Clearly the arguments to quote are not macro expanded, so they are not
in expression context. Similarly for the left-hand sides in let and
the bindings in fn. Your initial heuristic about "delaying execution"
was too vague. You could say that the branches of the if form have
their execution delayed; all the same, they are macro expanded ahead
of time.

-Per

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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

Reply via email to