Thanks for all your help everyone!
So I came up with an elegant solution. It was a combination of
Meikel's codwalker solution gave me the idea to bootstrap off of
Clojure's macroexpand system to get it to work.
;;This is a convenience method for expanding macros. It recursively
;;macroexpands every subform within a form.
(defn macroexpand-full [expression]
(let [expanded (macroexpand expression)]
(cond
;;Normal Form
(or (seq? expanded) (list? expanded))
(doall (map macroexpand-full expanded))
;;Vector Form
(vector? expanded)
(vec (map macroexpand-full expanded))
;;Map Form
(map? expanded)
(into {} (map macroexpand-full expanded))
;;Set Form
(set? expanded)
(into #{} (map macroexpand-full expanded))
;;Atom
:else
expanded)))
;;After that convenience function, the macro that I actually wanted to
write is trivial!
(def *bindings*)
(defmacro do-binding [& body]
`(let ~*bindings* ~@body))
(defmacro bind-later [bindings & body]
(binding [*bindings* bindings]
(macroexpand-full `(do ~@body))))
Thanks for all your ideas!
-Patrick
On Feb 10, 2:19 am, Mike Meyer <[email protected]> wrote:
> On Wed, 9 Feb 2011 20:34:56 -0800 (PST)
>
>
>
>
>
> CuppoJava <[email protected]> wrote:
> > Description: (bind-later bindings & body) and (do-binding & body)
> > (bind-later) is used like a let-form, except that it doesn't
> > *immediately* make the bindings available.
> > The bindings become available only within (do-binding).
> > (do-binding) is always used within a (bind-later).
>
> > Here's some sample code showing how it works.
>
> > (def a "outer a")
> > (bind-later (a "inner a")
> > (println a) <-- this prints out "outer a" still.
> > (do-binding
> > (println a))) <-- this will print out "inner a"
>
> > Is such a macro possible?
>
> Yes. It's just - as you say - tricky. You need to create a
> "do-binding" macro for each bind-later macro, meaning it should be
> part of the macros lexical space. First trick - use
> clojure.contrib.macro-utils/macrolet to do that sanely. Then comes the
> really tricky part - figuring out the correct unquoting for everything.
> But this does it:
>
> (defmacro bind-later [bindings & body]
> `(macrolet [(~'do-binding [& body#]
> `(let ~'~bindings
> ~@body#))]
> ~@body))
>
> Oh, one thing - since let requires a vector for binding, your example
> has to be written as (bind-later [a "inner a"] .... But that's the
> standard clojure idiom for bindings, so you should do it that way
> anyway ;-).
>
> <mike
> --
> Mike Meyer <[email protected]> http://www.mired.org/consulting.html
> Independent Network/Unix/SCM consultant, email for more information.
>
> O< ascii ribbon campaign - stop html mail -www.asciiribbon.org
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en