stackoverflow exception in printing meta with :type

Description

Hi, after expose the problem in clojure irc and the help of @chouser, we thought my problem must be a bug.
Here the console session

user> (with-meta {:value 2} {:type Object})

No message. [Thrown class java.lang.StackOverflowError]

0: clojure.lang.PersistentHashMap$BitmapIndexedNode.index(PersistentHashMap.java:485)
1: clojure.lang.PersistentHashMap$BitmapIndexedNode.find(PersistentHashMap.java:571)
2: clojure.lang.PersistentHashMap$ArrayNode.find(PersistentHashMap.java:355)
3: clojure.lang.PersistentHashMap.entryAt(PersistentHashMap.java:129)
4: clojure.lang.Var.getThreadBinding(Var.java:334)
5: clojure.lang.Var.deref(Var.java:137)
6: clojure.lang.Var.get(Var.java:133)
7: clojure.core$pr_on.invoke(core.clj:2810)
8: clojure.lang.Var.invoke(Var.java:369)
9: clojure.lang.RT.print(RT.java:1270)
10: clojure.lang.RT.printString(RT.java:1249)
11: clojure.lang.APersistentMap.toString(APersistentMap.java:20)

Chouser pointed that is a print error, creation and use of map with meta works fine

Thank for your help!

Environment

None

Attachments

1

Activity

Show:

Stuart Halloway April 22, 2011 at 3:13 PM

I chose to make the minimal change to print-method, rather than changing the type function, which would have been a breaking change to documented behavior.

Aside: Should type be deprecated?

Meikel Brandmeyer March 21, 2011 at 7:53 PM

Maybe one could check that (= (type thing) (class thing)) if the result of type is a Class? Types in meta data should normally be Keywords, no?

import October 8, 2010 at 4:36 PM

Comment made by: importer

chouser@n01se.net said: The problem is the print-method for Object calls .toString on the object, clearly expecting some nice tame Java default implementation. But in this case, the object is actually APersistentMap, which has a .toString that uses print-method. Oops.

One possible resolution is simply to say: when you lie about an object's type, bad things can happen. :type Object is essentially claiming that the map's concrete type is Object and that's simply not true. Perhaps breakage should be expected.

On the other hand, if we want to fail more gracefully either with a clearer error or "pre-initialized" print defined in RT.print, I'm not sure I see a solution other than explicit recursion detection. In this case it could take the form of a private Var set to the object being printed. If the Var is already equal to the object you're supposed to print, you're recursing on a single object and need to break out somehow.

Can anyone think of a cleaner way to catch this?

import October 8, 2010 at 4:36 PM

Comment made by: importer

Converted from http://www.assembla.com/spaces/clojure/tickets/435

Completed

Details

Assignee

Reporter

Approval

Ok

Priority

Fix versions

Created September 14, 2010 at 11:29 PM
Updated April 29, 2011 at 4:34 PM
Resolved April 29, 2011 at 4:34 PM