Re: Macros, namespaces, and lexical scope

2009-09-26 Thread Meikel Brandmeyer

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

2009-09-26 Thread Meikel Brandmeyer

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

2009-09-26 Thread Constantine Vetoshev

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

2009-09-26 Thread Chouser

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

2009-09-25 Thread John Harrop
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

2009-09-25 Thread Constantine Vetoshev

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

2009-09-25 Thread John Harrop
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
-~--~~~~--~~--~--~---