new, macros and "Can't eval locals"

211 views
Skip to first unread message

AtKaaZ

unread,
Feb 14, 2013, 4:27:29 PM2/14/13
to clo...@googlegroups.com
The goal is to can write this form:
=> (let [a java.lang.RuntimeException]
     (new a)
     )

CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: a, compiling:(NO_SOURCE_PATH:2:3)

attempt with macro:
=> (defmacro mew [cls & restt]
     `(new ~(eval cls) ~@restt)
     )

#'runtime.q/mew
=> (let [a java.lang.RuntimeException]
     (mew a)
     )

CompilerException java.lang.UnsupportedOperationException: Can't eval locals, compiling:(NO_SOURCE_PATH:2:3)

attempt with function:
=> (defn mew [cls & restt]
     (new cls)
     )

CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: cls, compiling:(NO_SOURCE_PATH:2:3)

attempt with a macro inside the function:
=> (defn mew [cls & restt]
     (mew cls)
     )

CompilerException java.lang.UnsupportedOperationException: Can't eval locals, compiling:(NO_SOURCE_PATH:2:3)

Ok, i give up, how? impossible ?

--
Please correct me if I'm wrong or incomplete,
even if you think I'll subconsciously hate it.

Andy Fingerhut

unread,
Feb 14, 2013, 4:34:07 PM2/14/13
to clo...@googlegroups.com
On Feb 14, 2013, at 1:27 PM, AtKaaZ wrote:

The goal is to can write this form:
=> (let [a java.lang.RuntimeException]
     (new a)
     )

CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: a, compiling:(NO_SOURCE_PATH:2:3)

attempt with macro:
=> (defmacro mew [cls & restt]
     `(new ~(eval cls) ~@restt)
     )

#'runtime.q/mew

This is probably your closest attempt.  Try this variation on the above:

(defmacro mew [cls & args]
  `(new ~cls ~@args))

user=> (macroexpand-1 '(mew java.lang.RuntimeException))
(new java.lang.RuntimeException)

Andy

AtKaaZ

unread,
Feb 14, 2013, 4:40:24 PM2/14/13
to clo...@googlegroups.com
thanks for the reply,

=> (defmacro mew [cls & args]
     `(new ~cls ~@args))

#'runtime.q/mew
=> (let [a java.lang.RuntimeException]
     (mew a)
     )

CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: a, compiling:(NO_SOURCE_PATH:2:3)

that would be the equivalent macro of what new is doing
it's like
(new a)
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: a, compiling:(NO_SOURCE_PATH:2:3)


This is the goal:

The goal is to can write this form:
=>  (let [a java.lang.RuntimeException]
         (new a))


but I think it's impossible, at least by using "new" it is


--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

AtKaaZ

unread,
Feb 14, 2013, 4:53:35 PM2/14/13
to clo...@googlegroups.com
I figure since new is expecting a class at compiletime, we can never pass it a class that we evaluate at runtime(those locals), ergo => impossible to macro around "new" like that

like this => impossible:
(let [a java.lang.RuntimeException]
         (macro-that-eventually-calls-new a))


maybe someone could suggest another way? clojure.reflect ?

AtKaaZ

unread,
Feb 14, 2013, 4:58:39 PM2/14/13
to clo...@googlegroups.com
ok looks like it's not impossible:
=> (defmacro mew [cls & restt]
     (let [c a]
       `(eval (new ~a ~@restt))
       )
     )

#'runtime.q/mew
=> (let [a java.lang.RuntimeException]
     (mew a)
     )

#<RuntimeException java.lang.RuntimeException>

AtKaaZ

unread,
Feb 14, 2013, 5:01:03 PM2/14/13
to clo...@googlegroups.com
ah I tricked myself... I used "~a"  inside the macro instead of "~c" or "~cls"
so back to still impossible

=> (defmacro mew [cls & restt]
     (let [c cls]
       `(eval (new ~c ~@restt))

       )
     )
#'runtime.q/mew
=> (let [a java.lang.RuntimeException]
     (mew a)
     )
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: a, compiling:(NO_SOURCE_PATH:2:3)
=> (defmacro mew [cls & restt]
     `(eval (new ~cls ~@restt))

     )
#'runtime.q/mew
=> (let [a java.lang.RuntimeException]
     (mew a)
     )
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: a, compiling:(NO_SOURCE_PATH:2:3)

AtKaaZ

unread,
Feb 14, 2013, 5:01:58 PM2/14/13
to clo...@googlegroups.com
and I forgot to mention that I already had another "a" defined
=> a
java.lang.RuntimeException

hence why it worked

Aaron Cohen

unread,
Feb 14, 2013, 5:02:11 PM2/14/13
to clo...@googlegroups.com
Yes, since this is runtime you should use reflection.

(let [a java.lang.RuntimeException]
   (.newInstance a))

Alternatively, you can use eval:

(let [a java.lang.RuntimeException]
  (eval (list 'new a)))

AtKaaZ

unread,
Feb 14, 2013, 5:08:57 PM2/14/13
to clo...@googlegroups.com
Thank you! I didn't know you could do .newInstance

oh that's a nice trick with eval and list 'new

So it's not impossible after all, thanks Aaron!

Here's what I got from what you said:
=>
(defmacro mew [cls & restt]
       `(eval (list 'new ~cls ~@restt))
     )

#'runtime.q/mew
=> (let [a java.lang.RuntimeException]
       (mew a)
     )

#<RuntimeException java.lang.RuntimeException>

it makes sense now, using eval at runtime not at compile time as I was trying

and also the newInstance variant:
=> (defmacro mew [cls & restt]
       `(.newInstance ~cls ~@restt)
     )

#'runtime.q/mew
=> (let [a java.lang.RuntimeException]
       (mew a)
     )

#<RuntimeException java.lang.RuntimeException>


Really, thank you Aaron,

Jacob Goodson

unread,
Feb 17, 2013, 12:12:17 AM2/17/13
to clo...@googlegroups.com
You need to know something... it's a dialect of LISP, the only limitation is you.

AtKaaZ

unread,
Feb 17, 2013, 1:37:33 AM2/17/13
to clo...@googlegroups.com
On Sun, Feb 17, 2013 at 6:12 AM, Jacob Goodson <submissio...@gmx.com> wrote:
You need to know something... it's a dialect of LISP, the only limitation is you.
though it is certainly exerting its limitations on me

 
Reply all
Reply to author
Forward
0 new messages