(I asked these questions on #clojure, and the friendly locals
suggested I open the question up for a wider audience.)
I'm trying to write a macro-writing-macro. My code has a bunch of
resources which have -open and -close type of calls, and they could
all benefit from with- wrappers. The with- wrappers all have similar
structure, and I thought I would be better off defining them with
another macro:
(defmacro def-with-db-macro [macro-name open-fn close-fn]
`(defmacro ~macro-name [[var# & open-args#] & body#]
`(let [~var# (apply ~'~open-fn [...@open-args#])]
(try
~...@body#
(finally (~'~close-fn ~var#))))))
Sample use:
(def-with-db-macro with-db-env db-env-open db-env-close)
(def-with-db-macro with-db db-open db-close)
(def-with-db-macro with-db-txn db-txn-begin
(fn [txn] (when (= @(txn :status) :open) (db-txn-commit txn))))
This mostly works. It breaks if I try using, e.g., with-db-env in a
namespace which does not import db-env-open or db-env-close.
Chris Houser has summarized the problem here more succinctly than I
can: http://paste.lisp.org/display/87734
While searching for a workaround, I thought maybe I could capture the
functions I need during expansion of def-with-db-macro, but kept
getting a useless exception. I ended up reducing that problem to this:
(let [f1 #(inc %)]
(defmacro m1 [x]
`(~f1 ~x)))
(m1 12)
=> No message.
[Thrown class java.lang.ExceptionInInitializerError]
The equivalent works in Common Lisp (Allegro CL and SBCL):
(let ((f1 (lambda (y) (1+ y))))
(defmacro m1 (x)
`(funcall ,f1 ,x)))
(m1 12)
=> 13
Thoughts on either of these brain teasers?
Thanks!
PS: To read the IRC discussion, see
http://clojure-log.n01se.net/date/2009-09-25.html
and scroll down to the discussion starting at 15:16.
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---