<< Back to previous view

[CLJ-820] int coercion doesn't work in clojure 1.3 Created: 14/Jul/11  Updated: 20/Jul/12  Resolved: 20/Jul/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.3
Fix Version/s: Release 1.5

Type: Defect Priority: Major
Reporter: Tassilo Horn Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: None
Environment:

Gentoo GNU/Linux



 Description   

Using the clojure git head as of 2011-07-14 (commit f704853751d02faf72bd53be599ee0be6c1da63e), int coercion doesn't work:

user> (class (int 1))
java.lang.Long

byte, short, double, and float coercion work fine, though:

user> (class (byte 1))
java.lang.Byte
user> (class (short 1))
java.lang.Short
user> (class (double 1))
java.lang.Double
user> (class (float 1))
java.lang.Float

Also creating integers directly works fine:

user> (class (Integer. "100"))
java.lang.Integer
user> (class (Integer/valueOf 1))
java.lang.Integer
user> (class (Integer. 100))
java.lang.Integer

This is probably related to CLJ-439.



 Comments   
Comment by Sebastián Bernardo Galkin [ 15/Jul/11 2:33 PM ]

Related documentation here: http://dev.clojure.org/display/doc/Enhanced+Primitive+Support

all long-or-smaller integers are boxed as Long
You can't use primitive coercions to force specific box types
Your code was broken if you were relying on that

So, apparently (int) has the correct behavior. It's byte and short which should be also boxed into Longs

Comment by Sebastián Bernardo Galkin [ 15/Jul/11 2:34 PM ]

See also this topic in clojure-dev: https://groups.google.com/d/topic/clojure-dev/fXQAYv8s0tQ/discussion

Comment by Tassilo Horn [ 15/Jul/11 3:00 PM ]

So to call some Java method that requires an int you have to use Integer/valueOf?

Comment by Sebastián Bernardo Galkin [ 15/Jul/11 3:46 PM ]

Yes, I think so

Comment by Tassilo Horn [ 15/Jul/11 4:16 PM ]

But for what are the coercion functions now good for? I mean, http://clojure.org/java_interop#Java Interop-Coercions states:

"At times it is necessary to have a value of a particular primitive type. These coercion functions yield a value of the indicated type as long as such a coercion is possible: bigdec bigint boolean byte char double float int long num short"

That's exactly my use case which is not supported anymore.

Comment by Sebastián Bernardo Galkin [ 15/Jul/11 11:09 PM ]

(int) (char) etc. are not intended to return boxed types, they always return primitive types. If you want boxed types you can use (num). When you do (class (int 42)) you are casting the long 42 to a int and then boxing it into a Long to get its class.

For short and byte, I don't know, I think there is a bug, (class (short 42)) should be Short.

Comment by Tassilo Horn [ 16/Jul/11 7:13 AM ]

(int) (char) etc. are not intended to return boxed types, they always return primitive types.

Thank you, Sebastián, that made it clear and unveiled the problem at my side. When I did

(set-value! foo :position (int 17))

I got the exception "java.lang.Long cannot be cast to java.lang.Integer". set-value! is a protocol function extended on the java types of the java library I'm interacting with. Eventually, it'll call (doto foo (.setAttribute "position" (mutable <providedVal>)), where mutable is yet another protocol function that converts clojure collections to the libraries counterparts and does nothing for primitive types.

Now, although (int 17) returns an unboxed int, these two indirections box it into a Long again and the java setter is called with that leading to the error.

(set-value! foo :position (Integer/intValue 17))

circumvents the issue, because here you directly get an int boxed as Integer.

If you want boxed types you can use (num).

Well, I want a boxed value of a certain type, like Integer.

For short and byte, I don't know, I think there is a bug, (class (short 42)) should be Short.

Should or should not? Currently, for all primitive types <primType>, the call (class (<primType> <val>)) returns the wrapper class corresponding to <primType> with the exception of int where you get a Long instead of an Integer. That's totally surprising and caused me to file this bug report.

Comment by Michel Alexandre Salim [ 26/May/12 12:55 PM ]

This is fixed in 1.4.0 – could one of the screeners confirm this, and maybe close the issue?

Generated at Wed Apr 23 15:46:10 CDT 2014 using JIRA 4.4#649-r158309.