On 18 Sep 2010, at 07:15, Stuart Campbell wrote:
In the following contrived example, I get an error when
macroexpanding (defn foo ...):
(defmacro special-fn-spec []
'([bar baz] (println bar baz)))
(defn foo
([bar] (foo bar :default))
(special-fn-spec))
The error is:
Parameter declaration special-fn-spec should be a vector
[Thrown class java.lang.IllegalArgumentException]
I'm a bit confused about the order in which things are happening
here. My assumption was that (special-fn-spec) would be evaluated
before the fn definition. Is there a way to do something like this?
Macroexpansion is part of the expression evaluation mechanism. In your
example
(defn foo
([bar] (foo bar :default))
(special-fn-spec))
the whole defn-form is macroexpanded first, yielding something like
(def foo (fn ([bar] (foo bar :default)) (special-fn-spec))
Then the fn form is evaluated, yielding a compiled function. At that
point, the compiler checks its syntax, and finds two bodies, one well-
formed (arg list followed by expression) and a second ill-formed one
(just an expression). The function bodies are *not* macroexpanded
because they are not evaluated either. The only other subform of your
example that is ever macroexpanded is (foo bar :default).
There are a couple of ways to generate function bodies
programmatically, but it is difficult to give useful advice without
knowing what you need this for.
Konrad.
--
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