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

Reply via email to