Hi Colin, as far as I can tell, your solution looks fine... here are a couple of comments on your step-by-step analysis
cheers, Gianluca 1(defmacro form [state & elements] > 2 (let [m-state (gensym)] > 3 `(let [~m-state ~state] > 4 [:div.form.horizontal > 5 ~@(map (fn [[f m & rest]] > 6 `[~f (assoc ~m > 7 :value (get @(:values ~m-state) (:id ~m)) > 8 :on-change #(swap! (:values ~m-state) assoc > (:id ~m) "UPDATED")) > 9 ~@rest]) > 10 elements)]))) > > 0 - ` means "emit, don't evaluate", ~@ means "splice, e.g. remove the > outer sequence so [a ~@[1 2]] becomes [a 1 2] and ' means 'the symbol of > rather than the value of'. > ~@ means "evaluate and splice", i.e., it overrides the "don't evaluate" of ` and splices the result in the outer sequence ~ means just "evaluate" without the splicing > 2 - declare m-state, which is lexically scoped to the macro and is bound > to a random identifier created by gensym > 3 - the back-tick (syntax-quote) returns the form rather than evaluating > the form, so the macro will return (let* [m-8_324230_ ....]) The [~m-state > ~state] is just bewildering though. > 3 - in addition, the 'state' argument appears to be destructured, but only > to one level so if the state contains an atom it is the var of the atom > 'state' is evaluated due to ~, not sure what you mean by 'destructured, but only to one level' > 4 - literal text emitted in-line > 5 - splice the results of the map (i.e. rather than [:div.form.horizontal > [child1 child2]] return [:div.form.horizontal child1 child2]) > 5 - also destructure each element assuming [f m(ap) and 0 or more other > args] > yes, the destructuring is just a normal destructuring of the args passed to the fn by map > 6 - emit [<f> where <f> is the first symbol, 'f' l in each element. Also > prevent this being evaluated in the macro with the syntax-quote as (5) has > introduced some new scope because of the ~@ - not sure. > as said above, rather than introducing a new scope, ~@ just overrides the "don't evaluate" of back-tick > 6 - also associate onto the symbol m (which is assumed to be associative, > e.g. a map)... > 7/8 - extract data out of the 'run-time' (e.g. not macro-time) value of > the provided state (magically captured under ~m-state) > 9 - splice in the rest of the arguments, if any, that were part of the > element > 10 - and do that magic for each element > -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.