int or long as map key

959 views
Skip to first unread message

daigo

unread,
Mar 25, 2011, 9:18:46 PM3/25/11
to Clojure
I have just started learning Clojure.
Thank you for developing a wonderful language.

Is this behavior by design?
If so, how can I loosely use numerical values as keys?

Clojure 1.2.0
user=> (def m {1 10 2 20})
#'user/m
user=> (m 2)
20
user=> (m (long 2))
nil

Regards,
Daigo

David Nolen

unread,
Mar 25, 2011, 9:30:50 PM3/25/11
to clo...@googlegroups.com
This is resolved in the upcoming version of Clojure (1.3.0). The alphas are stable enough to develop with in my experience.

David 

Stuart Sierra

unread,
Mar 26, 2011, 3:40:08 PM3/26/11
to clo...@googlegroups.com
Through version 1.2.0, Clojure used Java's Object.equals method for map lookups.  Java specifies Object.equals to be false for numbers of different types.

Clojure 1.3.0-alpha* uses its own = function for map lookups specifically to avoid this problem.  The = function is true for numbers of different types but the same value.  Note that Java code dealing with Clojure maps using the java.util.Map interface will still get the standard Java behavior using Object.equals.

Clojure 1.3.0-alpha* also uses longs by default for all integer literals.

    Clojure 1.3.0-master-SNAPSHOT

    user=> (def m {1 10 2 20})
    #'user/m
    user=> (m 2)
    20
    user=> (m (long 2))
    20
    user=> (type 2)
    java.lang.Long

Stuart Sierra
clojure.com

Jason Wolfe

unread,
Mar 28, 2011, 4:35:01 PM3/28/11
to Clojure

> Clojure 1.3.0-alpha* uses its own = function for map lookups specifically to
> avoid this problem.  The = function is true for numbers of different types
> but the same value.  Note that Java code dealing with Clojure maps using the
> java.util.Map interface will still get the standard Java behavior using
> Object.equals.

Shouldn't this return nil then?

user=> *clojure-version*
{:major 1, :minor 3, :incremental 0, :qualifier "alpha6"}
user=> (.get {1 2} (Integer. 1))
2

Also, if the above is the intended behavior, there are some weird
consequences with the current record equality semantics. For example,

user=> (defrecord P [])
user.P
user=> (defrecord Q [])
user.Q
user=> (= (P.) (Q.))
false
user=> (.equals (P.) (Q.))
true
user=> {(P.) 1 (Q.) 2}
{#:user.P{} 1, #:user.Q{} 2}
user=> (java.util.HashMap. *1)
#<HashMap {user.P@0=2}>

Stuart Sierra

unread,
Mar 30, 2011, 8:58:07 AM3/30/11
to clo...@googlegroups.com
Looks like that bit is not finished yet.  See http://dev.clojure.org/display/doc/Enhanced+Primitive+Support under "hash maps and sets now use = for keys"

-S
Reply all
Reply to author
Forward
0 new messages