zipmap different ordering in 1.7

327 views
Skip to first unread message

Jo Geraerts

unread,
Jul 1, 2015, 3:54:03 PM7/1/15
to clo...@googlegroups.com
Hey,

I when i tried to run my program with the shiny new 1.7, it broke. I have traced it down to the fact that zipmap (https://github.com/clojure/clojure/blame/master/src/clj/clojure/core.clj#L2940) does returns the keys in a different order than i'm used to.

e.g clojure 1.6:

nREPL server started on port 52315 on host 127.0.0.1 - nrepl://127.0.0.1:52315
REPL-y 0.3.5, nREPL 0.2.7
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b26
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (zipmap [:a :b] [:c :d])
{:b :d, :a :c}

Whereas clojure 1.7 does:

nREPL server started on port 52193 on host 127.0.0.1 - nrepl://127.0.0.1:52193
REPL-y 0.3.5, nREPL 0.2.7
Clojure 1.7.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b26
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (zipmap [:a :b] [:c :d])
{:a :c, :b :d}

As i'm using the keys function later on these values as a multimethod dispatch function, things break. 

It's rather trivial to change my program with the new ordering, but i was wondering if the ordering of the keys of the returned map is part of the contract.

When one would need more context about the actual code, the usage of the zipmap can be found here at https://github.com/jgeraerts/imageresizer/blob/master/src/net/umask/imageresizer/urlparser.clj#L19.

The tests break with these kinds of exceptions:

ERROR in (test-resizer) (MultiFn.java:156)
expected: (= [200 [200 200]] (run-resizer "size/200x200/rose-cmyk.tiff"))
20:31:05.179 [main] WARN  net.umask.imageresizer.resizer - image not found for uri size/200x200/nonexisting
  actual: java.lang.IllegalArgumentException: No method in multimethod 'scale' for dispatch value: (:width :height)
 at clojure.lang.MultiFn.getFn (MultiFn.java:156)
    clojure.lang.MultiFn.invoke (MultiFn.java:233)

I'm glad to hear your feedback. 

Kr,

Jo



Andy Fingerhut

unread,
Jul 1, 2015, 3:55:25 PM7/1/15
to clo...@googlegroups.com
Unsorted hash maps changed their seq order from Clojure 1.5.1 to Clojure 1.6.0, and some unsorted maps changed their seq order from Clojure 1.6.0 to Clojure 1.7.0.  If you are relying on the seq order of unsorted maps, your program is at risk of breaking across Clojure versions.

Andy

--
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/d/optout.

Fluid Dynamics

unread,
Jul 1, 2015, 9:06:00 PM7/1/15
to clo...@googlegroups.com

Key order for (non-sorted) maps is not guaranteed, but there is an easy fix: pour the result of keys into a set, e.g. (into #{} (keys my-map)), and use #{:width :height} e.g. as your dispatch values. Then it will work independently of the vagaries of key ordering.

Jo Geraerts

unread,
Jul 2, 2015, 2:44:32 AM7/2/15
to clo...@googlegroups.com
That was exactly what i'm doing to fix it. I didnt care about the actual order but assumed the order was going to stay the same. Bad assumption. 

Thank you all for the feedback. 

Op donderdag 2 juli 2015 03:06:00 UTC+2 schreef Fluid Dynamics:

dmic...@gmail.com

unread,
Jul 6, 2015, 4:42:43 AM7/6/15
to clo...@googlegroups.com
The semantics of a set doesn't guarantee an order either (even though it's implementation might), I'd sort over the keys and use the resulting collection as hash-map key so you are independent of any clojure-intrinsic behavior.

Timothy Baldridge

unread,
Jul 6, 2015, 8:03:43 AM7/6/15
to clo...@googlegroups.com
But with a set, the ordering doesn't matter, since #{:foo :bar} = #{:bar :foo}, so a set as a dispatch value should work just fine. 



--
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/d/optout.



--
“One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.”
(Robert Firth)

Jo Geraerts

unread,
Jul 7, 2015, 9:17:20 AM7/7/15
to clo...@googlegroups.com

Op maandag 6 juli 2015 10:42:43 UTC+2 schreef dmic...@gmail.com:
The semantics of a set doesn't guarantee an order either (even though it's implementation might), I'd sort over the keys and use the resulting collection as hash-map key so you are independent of any clojure-intrinsic behavior

I only cared if those keys were present and i used the keys function as a dispatch function and used the ordering it returned. Now suddenly the ordering changed in 1.7 and my program broke, but the exact ordering didn't really matter. 

Anyhow it is fixed now and my unit tests run happily again. 
Reply all
Reply to author
Forward
0 new messages