Hi,
im just porting Chapter 19 to clojure (my objective is to learn
macros). (For those that do not know the book: A database system is
introduced that can hold and query painters). It goes nicely until the
macro with-answer, which generate bindings on-the-fly so that one can
say
(with-answer (painter ?a ?b english) (prn ?a))
and the system will print the names of the english painters. So with-
answer has two arguments, the first is the query and the second is a
block of code which is then evaluated using the bindings that are
generated by the query. I thought it would be possible to write a
macro that generates something like (let [?a name1] (prn ?a)), but I
was not able to do so. Why is that? Is there a trick?
The problem boils down to this: Write a macro dynlet that can be
called like this
(def bds '[a 42])
(dynlet bds (prn a))
and will print 42.
I came up with
(defmacro dynlet [bvec body]
`(let ~bvec
~body))
but this only works if the vector with the bindings is given directly
to the macro like this:
(dynlet [a 42] (prn a))
How does one do this in clojure?
I was able to solve the original problem by doing a string-replace of
the variables in the body with the generated values like this:
(defmacro with-answer [query body]
`(do
~@(map
(fn [x]
(let [rbody# (walk/postwalk-replace x body)]
rbody#)
)
(interpret-query query)))
)
but of cause this is not the same as the original thing. It has to be
called like this
(with-answer (painter ?a ?b english) (prn '?a))
and the last quote is sadly necessary.
I would greatly appreciate some help here!
TIA,
Michael
--
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