Re: Macros, namespaces, and lexical scope
Hi, Am 26.09.2009 um 17:06 schrieb Constantine Vetoshev: This seems indeed useless at a first glance, but looking down the cause trace usually shows the real problem. Full stack trace follows, although I still don't know what it means. No message. [Thrown class java.lang.ExceptionInInitializerError] Backtrace: 0: sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 1: sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:39) 2: sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:27) 3: java.lang.reflect.Constructor.newInstance(Constructor.java:513) 4: java.lang.Class.newInstance0(Class.java:355) 5: java.lang.Class.newInstance(Class.java:308) 6: clojure.lang.Compiler$FnExpr.eval(Compiler.java:3428) 7: clojure.lang.Compiler.eval(Compiler.java:4531) 8: clojure.core$eval__3990.invoke(core.clj:1728) No. This is a *stack*trace. I meant the *cause* trace. That is, the chain of wrapped exceptions. You should look in the trace for lines like Caused by The last should point to the real problem. Of course, that might be something obscure, eg. in the case Chouser mentioned. However I found it to be something in my code in 99.9% of the cases. :] From what you print, it seems you use SLIME. This maybe hides the Caused by... lines and only prints the stracktrace. Not sure, though. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: Macros, namespaces, and lexical scope
Hi, Am 25.09.2009 um 22:49 schrieb Constantine Vetoshev: (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#)) The problem is, that you quote the symbol you inject into the inner defmacro. Hence it does not get resolved. The solution in this case seems to be to syntax-quote the symbol correctly before injection. Replace the two ~'~ with ~~ and call the macro as (def-with-db-macro with-foo `open-foo `close-foo). This correctly resolves the symbols in the namespace calling def-with-db-macro and injects them into the with- foo expansion. I haven't really tested this, but it seems to be consistent with the macro machinery. 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] This seems indeed useless at a first glance, but looking down the cause trace usually shows the real problem. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: Macros, namespaces, and lexical scope
On Sep 26, 7:35 am, Meikel Brandmeyer m...@kotka.de wrote: The problem is, that you quote the symbol you inject into the inner defmacro. Hence it does not get resolved. The solution in this case seems to be to syntax-quote the symbol correctly before injection. Replace the two ~'~ with ~~ and call the macro as (def-with-db-macro with-foo `open-foo `close-foo). This correctly resolves the symbols in the namespace calling def-with-db-macro and injects them into the with- foo expansion. I haven't really tested this, but it seems to be consistent with the macro machinery. Thank you. That works. I had tried ~~ by itself, and it didn't fly. I didn't think to syntax-quote the symbol in its place of expansion. So referring back to http://paste.lisp.org/display/87734, the solution is: user (defmacro make-myfoo [foo] `(defmacro ~'myfoo [s#] `(~~foo ~s#))) = #'user/make-myfoo user (ns tmp) tmp (user/make-myfoo `foo) = #'tmp/myfoo tmp (macroexpand '(tmp/myfoo bar)) = (tmp/foo bar) As expected, in the tmp namespace. This seems indeed useless at a first glance, but looking down the cause trace usually shows the real problem. Full stack trace follows, although I still don't know what it means. No message. [Thrown class java.lang.ExceptionInInitializerError] Backtrace: 0: sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 1: sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:39) 2: sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:27) 3: java.lang.reflect.Constructor.newInstance(Constructor.java:513) 4: java.lang.Class.newInstance0(Class.java:355) 5: java.lang.Class.newInstance(Class.java:308) 6: clojure.lang.Compiler$FnExpr.eval(Compiler.java:3428) 7: clojure.lang.Compiler.eval(Compiler.java:4531) 8: clojure.core$eval__3990.invoke(core.clj:1728) --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Re: Macros, namespaces, and lexical scope
On Fri, Sep 25, 2009 at 4:49 PM, Constantine Vetoshev gepar...@gmail.com wrote: Chris Houser has summarized the problem here more succinctly than I can: http://paste.lisp.org/display/87734 This is a syntax-quote expansion-timing issue, which is why Meikel's solutions works. I think it would work the way you want for all the actual examples you gave, including the literal anonymous function. 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] This a separate issue having to do with support for AOT compilation. It actually worked fine with an older version of Clojure, specifically 043093bd670d4981a3136294941831c4cfcb7bae from Sun Oct 12 14:47:24 2008. The next commit removed support for that feature: first step towards AOT compilation - constants now read from strings in classfiles instead of hand-off from classloader --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 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 -~--~~~~--~~--~--~---
Re: Macros, namespaces, and lexical scope
On Fri, Sep 25, 2009 at 4:49 PM, Constantine Vetoshev gepar...@gmail.comwrote: (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? I don't think you can use things like defmacro in a let. Macros are used at macroexpansion time and I don't think a let's bindings will exist yet. So you probably need something like (defmacro m1 [x] (let [f1 #(inc %)] `(~f1 ~x))) instead. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Re: Macros, namespaces, and lexical scope
On Sep 25, 6:02 pm, John Harrop jharrop...@gmail.com wrote: I don't think you can use things like defmacro in a let. This works: (let [y 10] (defmacro m1 [] `(list ~y))) (m1) = (10) --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Re: Macros, namespaces, and lexical scope
On Fri, Sep 25, 2009 at 8:48 PM, Constantine Vetoshev gepar...@gmail.comwrote: On Sep 25, 6:02 pm, John Harrop jharrop...@gmail.com wrote: I don't think you can use things like defmacro in a let. This works: (let [y 10] (defmacro m1 [] `(list ~y))) (m1) = (10) Well, that's weirdly inconsistent. It shouldn't work just *some* of the time. Either it should work, or it shouldn't work. According to the language semantics, it should work if let bindings wrapping def forms are in effect during any side effects of the def form, and should fail otherwise. Anyone knowledgeable about clojure internals have any idea why it would work sometimes, but only sometimes? Did you get a detail message or stack trace from the exception you saw? --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---