On 2010 Apr 9, at 12:41 AM, Per Vognsen wrote:
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.

Perhaps. I think my biggest disadvantage is lack of familiarity
with the zillions of Java libraries. I think it was a huge win
to put Clojure on the JVM for all that leverage. Lisp background
helps the Clojure learning curve, but doesn't ease the Java Library burden.
So it goes.


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. :)

My main concern is that I don't start writing output files only to get part-way through and then find a broken form. (I trust that the reader's meta-data will properly track the original source location of the forms in the input file(s).)


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.

If I take that quoted expression and eval it in the context of appropriate bindings?
  user=> (defmacro m1 [a b] (list 'println a b))
  #'user/m1
  user=> (m1 "foo" "bar")
  foo bar
  nil

Ok, then:
  user=> (binding [m1 (fn [p1 p2] (println "fun version of m1"))]
                  (m1 "foo" "bar"))
  foo bar
  nil

So the macro is getting expanded before binding can shadow m1.



However, in my case, the original code (my DSL) will be quoted, so it'll be evaled in a way that is something like this:

  user=> (binding [m1 (fn [p1 p2] (println "fun version of m1"))]
                  (eval '(m1 "foo" "bar")))
  fun version of m1
  nil

Now, I am not planning to implement my DSL with macros, but I am curious.
http://clojure.org/macros does not say when macros are expanded...

Eval does it, though:
  user=> (eval '(m1 "foo" "bar"))
  foo bar
  nil



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.

Odd:
  user=> (binding [m1 (fn [a b] (println "m1 from binding" a b))]
(eval '(if true (m1 "true" "here") (m1 "false" "there"))))
  m1 from binding true here
  m1 from binding false there
  nil

and yet:
  user=> (binding [m1 (fn [a b] (println "m1 from binding" a b))]
(eval '(if true (println "true" "here") (println "false" "there"))))
  true here
  nil


Why does the "Odd:" form evaluate both branches of the if, but the 'and yet:' form does not?

--Doug

--
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