On Tue, Feb 8, 2011 at 12:31 AM, CuppoJava <patrickli_2...@hotmail.com> wrote: > Thanks for the reply Ken. > > "While the macro is executing "body" will be bound to an > s-expression (basically, source code parsed to an AST but no further; > source code as processed by the reader). " > > This is the part where it falls apart. "body" is actually bound to a > single symbol. > > For example in the destructuring-let macro: > (def a [1 2 3]) > (let ((x y z) a) > (println x y z)) > > "body" refers to the single symbol "a".
What? No. The syntax for let is a vector, so it'd be something like (def a [1 2 3]) (let [[x y z] a] (println x y z)) and we would have: binding-forms '[[x y z] a] body '(println x y z) Furthermore I don't see what you need the body for. In the binding-forms, it's true that the destructured input is not known yet. The macro must emit something like (let* [x (first a) xxx (rest a) y (first xxx) yyy (rest xxx) z (first yyy)] (println x y z)) in cases like this. In short, the code it emits into the let* bindings does the destructuring. This code could be made to do double duty as follows. First, whenever it can emit an s-expression like '(first a) or '(rest a) it can check a flag and decide to either emit the s-expression or do the equivalent thing, e.g. (first a), immediately on its argument a. Second, the let macro can generate the let* binding vector by calling the function with the flag set to emit-s-expressions. Third, the user-usable function can generate input to (into {} (partition 2 ...)) by calling the function with the flag set to do-it. It boils down to a few cases, like replacing `(first ~sym) with (if emit-sexps? `(first ~sym) (first sym)) and similarly elsewhere in the code that gets abstracted out into the helper-fn. Then let becomes (defmacro let [bindings & body] `(let* ~(helper-fn bindings true) ~@body)) or something similar and the user destructure function is (defn destructure [bindoids] (into {} (partition 2 (helper-fn bindoids false)))) -- 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