On Fri, Apr 9, 2010 at 10:35 AM, Douglas Philips <d...@mac.com> wrote: > On 2010 Apr 8, at 11:16 PM, Per Vognsen wrote: >> >> It's not a defn thing. If you write (do (a) (b) (c)) at the REPL, you >> should see the same exception. > > Yes, I would expect that since at the REPL I am asking to have the > expression evaluated immediately. > Same with let. > > Yet, if I say: '(do (a) (b) (c)) > I do not get such an error, because quote is protecting me. > defn/fn are quoting in the sense that their body's expression is not > immediately evaluated,
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. Quoting is a special form. When the compiler sees (quote ...), it does not recursively compile the argument forms. If you're still confused, check out Compiler.java. The code is very simple and everything is right there. > yet they are doing more than quote because they're resolving the symbols. > >> When the compiler sees a symbol in expression context, it first checks >> whether it is bound in the local environment: >> >> (let [x 42] x) >> >> In this case, x is bound in the local environment. >> >> If a symbol isn't bound in this way, the compiler will call (resolve >> ...) on the symbol at compile time. This yields some var v. The code >> will then be evaluated as (deref v) at run time. > > So how do I invoke that resolution machinery myself? > > (my-do-later (a) (b 23) (c d e)) > while the forms in the body of my-do-later will be spliced into other places > for later evaluation, I want to know that they're valid symbols when > my-do-later is called (which has to be a macro to delay evaluation). I don't > necessarily need or care to know what they are resolved to (even regular > code in clojure can be affected by binding forms, which is what I'm planning > to inject the bodies of my-do-later forms into eventually). Macro expansion happens (and has to happen) before everything I described above. Your macro will see symbols, not vars. 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. But you can of course do it if you want, in which case you should call resolve at macro expansion time and have the macro expand to something that calls derefs on the resolved var: (defmacro symbol-eval [x] (let [v (resolve x)] `(deref ~v))) -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 To unsubscribe, reply using "remove me" as the subject.