unboxed primitives and *print-dup* odd exception!

241 views
Skip to first unread message

Jim - FooBar();

unread,
Jan 20, 2013, 1:58:35 PM1/20/13
to clo...@googlegroups.com
Hi everyone,

I came back to a project of mine after a couple of months only to be
surprised by some cryptic exception! Imagine a 2d vector:

(def coords [[0 0] [0 1] [1 0] [1 1]]) ;;vector of vectors of longs

;;but let's try ints which are cached:

(def coords
(mapv #(apply vector-of :int %) [[0 0] [0 1] [1 0] [1 1]]))
;;vector of vectors of ints


everything seems great right? well, now my namespaces don't even
compile! This is my representation of the 'board' in a game which means
that I'm only reading from this vector nothing else! I am getting
CompilerException java.lang.RuntimeException: Can't embed object in
code, maybe print-dup not defined: clojure.core$reify__6184@1eb42164,
compiling:(Clondie24/games/chess.clj:244:1) where line 244 is just a
'defn' with its argument vector...as soon as I comment out the
conversion to unboxed int primitives everything works again! doing (pst)
does not help at all! Look at this:

user=> (pst)
CompilerException java.lang.RuntimeException: Can't embed object in
code, maybe print-dup not defined: clojure.core$reify__6186@61c28cfb,
compiling:(Clondie24/games/chess.clj:244:1)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6566)
clojure.lang.Compiler.analyze (Compiler.java:6360)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6547)
clojure.lang.Compiler.analyze (Compiler.java:6360)
clojure.lang.Compiler.access$100 (Compiler.java:37)
clojure.lang.Compiler$DefExpr$Parser.parse (Compiler.java:528)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6559)
clojure.lang.Compiler.analyze (Compiler.java:6360)
clojure.lang.Compiler.analyze (Compiler.java:6321)
clojure.lang.Compiler.eval (Compiler.java:6622)
clojure.lang.Compiler.load (Compiler.java:7062)
clojure.lang.RT.loadResourceScript (RT.java:361)
Caused by:
RuntimeException Can't embed object in code, maybe print-dup not
defined: clojure.core$reify__6186@61c28cfb
clojure.lang.Util.runtimeException (Util.java:219)
clojure.lang.Compiler$ObjExpr.emitValue (Compiler.java:4570)
clojure.lang.Compiler$ObjExpr.emitValue (Compiler.java:4496)
clojure.lang.Compiler$ObjExpr.emitListAsObjectArray
(Compiler.java:4392)
clojure.lang.Compiler$ObjExpr.emitValue (Compiler.java:4529)
clojure.lang.Compiler$ObjExpr.emitConstants (Compiler.java:4609)
clojure.lang.Compiler$ObjExpr.compile (Compiler.java:4072)
clojure.lang.Compiler$FnExpr.parse (Compiler.java:3808)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6557)
clojure.lang.Compiler.analyze (Compiler.java:6360)
nil

this is clearly not my code! everything is clojure.lang.Compiler related!
what is happening exactly? can anyone explain? I'm not doing anything
'weird' in the function reported in the exception just reading the vector.

Jim





AtKaaZ

unread,
Jan 20, 2013, 4:10:13 PM1/20/13
to clo...@googlegroups.com




Jim





--
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+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en



--
I may be wrong or incomplete.
Please express any corrections / additions,
they are encouraged and appreciated.
At least one entity is bound to be transformed if you do ;)

Jim - FooBar();

unread,
Jan 20, 2013, 6:03:02 PM1/20/13
to clo...@googlegroups.com
yes exactly! In the commit that github shows last line 238 is line 244 in my current branch...Since you're looking into it i can commit everything now so we're all on the same page...

Jim

For more options, visit this group at
http://groups.google.com/group/clojure?hl=en



--
I may be wrong or incomplete.
Please express any corrections / additions,
they are encouraged and appreciated.
At least one entity is bound to be transformed if you do ;)
--
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

AtKaaZ

unread,
Jan 20, 2013, 7:17:13 PM1/20/13
to clo...@googlegroups.com
I've managed to reduce this to:
(ns Clondie24.games.xx1)

(def ^:const
mappings-8x8

  (mapv #(apply vector-of :int %)
        [[0 0] [1 0] [2 0]])
  )


(defn translate [mappings]
  (let [list-loc
        (.indexOf mappings [0 1])]
    ))


(translate mappings-8x8);throws



----
=> (pst *e 121312)
CompilerException java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: clojure.core$reify__6186@77771028, compiling:(Clondie24\games\xx1.clj:16:1)

    clojure.lang.Compiler.analyzeSeq (Compiler.java:6566)
    clojure.lang.Compiler.analyze (Compiler.java:6360)
    clojure.lang.Compiler.eval (Compiler.java:6615)
    clojure.lang.Compiler.load (Compiler.java:7062)
    Clondie24.games.chess/eval19634 (NO_SOURCE_FILE:1)
    clojure.lang.Compiler.eval (Compiler.java:6618)
    clojure.lang.Compiler.eval (Compiler.java:6581)
    clojure.core/eval (core.clj:2852)
    clojure.main/repl/read-eval-print--6625 (main.clj:251)
    clojure.main/repl/fn--6630/fn--6631 (main.clj:269)
    clojure.main/repl/fn--6630 (main.clj:269)
    clojure.main/repl (main.clj:267)
    clojure.tools.nrepl.middleware.interruptible-eval/evaluate/fn--988 (interruptible_eval.clj:58)
    clojure.core/apply (core.clj:617)
    clojure.core/with-bindings* (core.clj:1788)
    clojure.tools.nrepl.middleware.interruptible-eval/evaluate (interruptible_eval.clj:43)
    clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval/fn--1029/fn--1032 (interruptible_eval.clj:173)
    clojure.core/comp/fn--4173 (core.clj:2330)
    clojure.tools.nrepl.middleware.interruptible-eval/run-next/fn--1022 (interruptible_eval.clj:140)
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1110)
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:603)
    java.lang.Thread.run (Thread.java:722)
Caused by:
RuntimeException Can't embed object in code, maybe print-dup not defined: clojure.core$reify__6186@77771028

    clojure.lang.Util.runtimeException (Util.java:219)
    clojure.lang.Compiler$ObjExpr.emitValue (Compiler.java:4570)
    clojure.lang.Compiler$ObjExpr.emitValue (Compiler.java:4496)
    clojure.lang.Compiler$ObjExpr.emitListAsObjectArray (Compiler.java:4392)
    clojure.lang.Compiler$ObjExpr.emitValue (Compiler.java:4529)
    clojure.lang.Compiler$ObjExpr.emitConstants (Compiler.java:4609)
    clojure.lang.Compiler$ObjExpr.compile (Compiler.java:4072)
    clojure.lang.Compiler$FnExpr.parse (Compiler.java:3808)
    clojure.lang.Compiler.analyzeSeq (Compiler.java:6557)
    clojure.lang.Compiler.analyze (Compiler.java:6360)

to fix this, just comment out the "^:const" part, like so:
(def ;^:const
now, doesn't throw.


---------

///some extra stuff(ignore this):
(def xam0 (translate mappings-8x8));works
(println xam0)

(let [ xam (translate 1 2 mappings-8x8) ]);this one throws: can't embed even before Wrong number of args (3)

///end ignore

Maybe someone can explain...

This was enjoyable ;)

AtKaaZ

unread,
Jan 20, 2013, 7:20:33 PM1/20/13
to clo...@googlegroups.com
Actually, it's even simpler:

(def ^:const
mappings-8x8
  (mapv #(apply vector-of :int %)
        [[0 0] [1 0] [2 0]])
  )

(class mappings-8x8) ;throws
CompilerException java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: clojure.core$reify__6186@77771028, compiling:

AtKaaZ

unread,
Jan 20, 2013, 7:33:53 PM1/20/13
to clo...@googlegroups.com
Caused by:
RuntimeException Can't embed object in code, maybe print-dup not defined: clojure.core$reify__6186@4e5db277
    clojure.lang.Util.runtimeException (Util.java:223)
    clojure.lang.Compiler$ObjExpr.emitValue (Compiler.java:4571)

    clojure.lang.Compiler$ObjExpr.emitValue (Compiler.java:4496)
    clojure.lang.Compiler$ObjExpr.emitListAsObjectArray (Compiler.java:4392)
    clojure.lang.Compiler$ObjExpr.emitValue (Compiler.java:4529)
    clojure.lang.Compiler$ObjExpr.emitConstants (Compiler.java:4610)

    clojure.lang.Compiler$ObjExpr.compile (Compiler.java:4072)
    clojure.lang.Compiler$FnExpr.parse (Compiler.java:3808)
    clojure.lang.Compiler.analyzeSeq (Compiler.java:6558)
    clojure.lang.Compiler.analyze (Compiler.java:6361)
Caused by:
IllegalArgumentException No method in multimethod 'print-dup' for dispatch value: class clojure.core$reify__6186
    clojure.lang.MultiFn.getFn (MultiFn.java:160)
    clojure.lang.MultiFn.invoke (MultiFn.java:231)
    clojure.core/pr-on (core.clj:3321)
    clojure.lang.Var.invoke (Var.java:419)
    clojure.lang.RT.print (RT.java:1739)
    clojure.lang.RT.printString (RT.java:1718)
    clojure.lang.Compiler$ObjExpr.emitValue (Compiler.java:4566)

to see this I had to edit clojure code /clojure/src/jvm/clojure/lang/Compiler.java line 4571
by adding the cause to the throw (that ",e"):
throw Util.runtimeException(
                        "Can't embed object in code, maybe print-dup not defined: " +
                        value,e);

any reason why that isn't there already?(I guess this was added later: the ability to pass the cause)


Jim - FooBar();

unread,
Jan 20, 2013, 8:08:15 PM1/20/13
to clo...@googlegroups.com
wow! nice job AtKaaZ...so if I understood correctly there is no issue with my code yes? translate-position sits at the bottom of my API (cannot live without it)...

Jim

AtKaaZ

unread,
Jan 20, 2013, 8:24:52 PM1/20/13
to clo...@googlegroups.com
yes, your code works if you don't use the "^:const", but why doesn't it work with ^:const when you just use the return of mapv (something with reify?)? It's either some clojure bug or missing feature, or something inherent that I don't understand(ie. maybe it doesn't make sense to def ^:const the return of (mapv #(apply vector-of :int %) - I don't know really since I'm a clojure noob)
 I'm really hoping for someone who actually knows to tell us what's going on and they can use that above to reproduce it in repl, ie. this:

(def ^:const
mappings-8x8
  (mapv #(apply vector-of :int %)
        [[0 0] [1 0] [2 0]])
  )

(class mappings-8x8) ;throws
;or replace class with whatever ie. print or ifn? etc.

Can you actually cast mappings-8x8 to clojure.lang.PersistentVector ? I noticed that you used type hints. The actual class to be casted to it would be this: clojure.core$reify__6186
I'm actually unable to tell what's the class of mappings-8x8 but it seems reified, maybe this is why print doesn't know how to print it (whatever this means)
 By the way, if you don't use ^:const the class is: clojure.lang.PersistentVector (just as you'd expect), so probably ^:const is doing some reifying (which maybe disallows changes to the vector?) and yielding a different class - my guess (I don't really know what reify does btw - just what I remember)

Jim - FooBar();

unread,
Jan 21, 2013, 11:38:29 AM1/21/13
to clo...@googlegroups.com
On 21/01/13 01:24, AtKaaZ wrote:
yes, your code works if you don't use the "^:const", but why doesn't it work with ^:const when you just use the return of mapv (something with reify?)?

Well, I just came home and tried a couple of things out...It appears that my code doesn't work if I don't use the ^:const tag regardless of whther I've got boxed/unboxed values. It appears to be working (at least it compiles) but as soon as I do something related to reducers i get this from the JVM:

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f8f3d079b1b, pid=5643, tid=140252974098176
#
# JRE version: 7.0_06-b24
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.2-b09 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# v  ~BufferBlob::vtable chunks
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/sorted/clooJWorkspace/Clondie24/hs_err_pid5643.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp


This seems utterly alien and weird to me!!! I've never ever had that before! I don't know what it means and of course I don't even know where to look...My only option is to keep ^:const...

Jim

ps: now the project has an entry point for chess....just 'git clone' and then 'lein2 run'....start a new game and ask for a hint after a couple of moves (you move by clicking twice - one to select a piece and one to its new position)

AtKaaZ

unread,
Jan 21, 2013, 11:47:57 AM1/21/13
to clo...@googlegroups.com
Could you retry using this
-XX:-UseCompressedOops
jvm arg, or use a newer jre (I think it's some bug in the jvm)

I don't have time right now to test but I'll get back on it soon


--
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

Jim - FooBar();

unread,
Jan 21, 2013, 12:07:08 PM1/21/13
to clo...@googlegroups.com
On 21/01/13 16:47, AtKaaZ wrote:
> Could you retry using this
> -XX:-UseCompressedOops


surprisingly this worked! I don't get that error anymore... I used to
have it but i thought it was completely unnecessary...I don't understand
how this affects the runtime of my program!

Jim

Jim - FooBar();

unread,
Jan 21, 2013, 12:17:03 PM1/21/13
to clo...@googlegroups.com
also I Just tried eval-ing the call to mapv and it compiles and runs
just fine!!!! I'm totally baffled...

So to sum up:

this fails:

(def ^:const mappings-8x8
(mapv #(apply vector-of :int %) [[0 0] [1 0] [2 0]]))

this succeeds:

(def ^:const mappings-8x8
(eval (mapv #(apply vector-of :int %) [[0 0] [1 0] [2 0]])))


this is beyond me!

Jim




AtKaaZ

unread,
Jan 21, 2013, 12:26:20 PM1/21/13
to clo...@googlegroups.com
Very nice find! Thank you for that!

I'm thinking maybe it has something to do with lazy or delayed evaluation. I don't really understand most clojure things but I imagine if the call to mapv would not be evaluated right when the def is read but instead only when the mappings-8x8 is first being used (sort of like a `delay` or lazy init) then it would make some sense why ^:const would fail however this theory doesn't seem to hold when using something like (def ^:const mappings-8x8 ((fn [] [[0 0] [1 0]])) because it would have to act like the call to mapv does, unless there's something extra introduced by mapv but the returned class seems to be the same that PersistenVector - anyway I'm just guessing around, doesn't help :)




On Mon, Jan 21, 2013 at 6:17 PM, Jim - FooBar(); <jimpi...@gmail.com> wrote:
On 21/01/13 17:07, Jim - FooBar(); wrote:
On 21/01/13 16:47, AtKaaZ wrote:
Could you retry using this
-XX:-UseCompressedOops


surprisingly this worked! I don't get that error anymore... I used to have it but i thought it was completely unnecessary...I don't understand how this affects the runtime of my program!

Jim

also I Just tried eval-ing the call to mapv and it compiles and runs just fine!!!! I'm totally baffled...

So to sum up:

this fails:


(def ^:const mappings-8x8
  (mapv #(apply vector-of :int %) [[0 0] [1 0] [2 0]]))

this succeeds:

(def ^:const mappings-8x8
  (eval (mapv #(apply vector-of :int %) [[0 0] [1 0] [2 0]])))


this is beyond me!


Jim




--
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

For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Jim - FooBar();

unread,
Jan 21, 2013, 1:19:02 PM1/21/13
to clo...@googlegroups.com
our  happiness was short-lived...I still get the aformentioned jvm error even with the latest jdk/jre and 'COMPRESSED-OPS' flag, when using ^:const. This is new - I don't remember having this a month ago...it is definitely new and I'm thinking it's the rc1 version of clojure...

At the moment to avoid any problems I have to remove the ^:const flag completely. Then and only then it works as expected regardless of whether the numbers inside are unboxed ints or boxed longs.

Jim

For more options, visit this group at
http://groups.google.com/group/clojure?hl=en



--
I may be wrong or incomplete.
Please express any corrections / additions,
they are encouraged and appreciated.
At least one entity is bound to be transformed if you do ;)
--
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

AtKaaZ

unread,
Jan 21, 2013, 1:22:11 PM1/21/13
to clo...@googlegroups.com
Just making sure, but when you say " and 'COMPRESSED-OPS' flag" you mean disabling compressed-oops aka -XX:-UseCompressedOops (note the minus) or the enabled(as is the default) compressed oops aka -XX:+UseCompressedOops

Does it happen even if you use eval ?

Jim - FooBar();

unread,
Jan 21, 2013, 1:26:54 PM1/21/13
to clo...@googlegroups.com
yes yes I meant 'disabling compressed oops' sorry about that! Yes it happens when I use eval as well. If i try to go to depth 6 at once it will crash...if i try to go to level 4 then it might not the first time but it will at some subsequent point...very strange! anyway I've removed the ^:const flag altogether so i can at least work...but from what I understand it does offer a small performance improvement...

Jim
Reply all
Reply to author
Forward
0 new messages