Clojure seqs over iterators to provide a stable immutable view of them. But the nastiness of an IdentityHashMap is deeper. It isn't just the iterator that is mutable. The thing *returned* by the iterator is also mutable. (In fact, the iterator returns itself.)
So the process of consuming the iterator wrecks the objects returned by the iterator.
To patch this up on the Clojure side would require special casing for IdentityHashMap (and more special casing for any other classes that behave like this).
I am tempted to lay the blame with IdentityHashMap, document, and move on. What do others think?
Stu
Did you draw your conclusions from looking at docs/behavior/code?
Pointers please.
Thanks,
Rich
Behavior, code, and comments:
Behavior:
(-> (java.util.IdentityHashMap. {:a true :b true})
(.entrySet)
(.iterator)
(.next))
=> #<EntryIterator :a=true> ;; returns the iterator! yikes!
I don't have a link into JDK source (will look after I hit send), but the OpenJDK source for the nested class has the following comment above the EntryInterator nested class of IdentityHashMap:
/**
* Since we don't use Entry objects, we use the Iterator
* itself as an entry.
*/
The behavior is *not* documented in the javadoc http://download.oracle.com/javase/6/docs/api/java/util/IdentityHashMap.html.
Stu