On Fri, Feb 13, 2009 at 11:17 PM, samppi <rbysam...@gmail.com> wrote:
>
> I'm trying to write a macro that expands from this:
>
> (product-context [n rule0, m rule1)]
>  (rule-maker2 (+ n m)) rule3))
>
> Into this (assume that conc-fn and conc-products are functions):
>
> (fn [tokens]
>  (if-let [[remainder# n m] (conc-products [rule0 rule1] tokens)]
>    (conc-fn [(rule-maker2 (+ n m)) rule3] remainder#)))

> ...but I can't figure out how to change [n rule0 m rule1] to (if-let
> [[remainder# n m] (conc-products [rule0 rule1] tokens)] ...).

Try working it out outside of the macro context.

(def bindvec '[n rule0, m rule1])

Now you've got something to work with.  There are plenty of acceptible
answers.  Maybe you want to think of the vector as key/value pairs:

(apply array-map bindvec)  ==> {n rule0, m rule1}
(keys (apply array-map bindvec))  ==> (n m)
(vals (apply array-map bindvec))  ==> (rule0 rule1)

Or just use some seq function:

(take-nth 2 bindvec)  ==> (n m)
(take-nth 2 (rest bindvec))  ==> (rule0 rule1)

Once you've got the pieces you need, try sticking them into a
syntax-quote:

user=> `(if-let [[r# ~(take-nth 2 bindvec)] (cp ~(take-nth 2 (rest
bindvec)))] ...)
(clojure.core/if-let [[r__215__auto__ (n m)] (user/cp (rule0 rule1))] ...)

Well, that's close by there are extra parens around (n m) and you want
a vector not a list for the rules.  So play with it until it looks
right:

user=> `(if-let [[r# ~@(take-nth 2 bindvec)] (cp ~(vec (take-nth 2
(rest bindvec))))] ...)
(clojure.core/if-let [[r__219__auto__ n m] (user/cp [rule0 rule1])] ...)

Then you're ready to build the macro:

(defmacro product-context [bindvec & body]
  `(fn [tokens#]
     (if-let [[remainder# ~@(take-nth 2 bindvec)]
                (conc-products [~@(take-nth 2 (rest bindvec))] tokens#)]
       (conc-fn [...@body] remainder#))))

--Chouser

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