-
Notifications
You must be signed in to change notification settings - Fork 21
Default implementation of immutable.Set has non-deterministic iteration order #8184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Imported From: https://issues.scala-lang.org/browse/SI-8184?orig=1 |
Adam Voss (vossad01) said: |
David North (dtnox) said: My point is that it would be useful if the default implementation did have a deterministic iteration ordering. Non-determinism is bad - it makes bugs harder to reproduce. My company came to this conclusion for Java a long time ago. Again, though the 'Set' interface does not guarantee any sort of ordering, we found it best to ban the use of HashSet and force people to use LinkedHashSet. |
lvfangmin (alan) said: |
David North (dtnox) said: (1) I can only make that choice in my own code, so I'm left having to force an arbitrary ordering on any Set coming out of a third-party library which I want to have a deterministic order (2) Scala does not have an immutable Set implementation with guaranteed iteration order. |
Adam Voss (vossad01) said: Recall that I thought |
David North (dtnox) said (edited on Feb 4, 2014 2:06:00 PM UTC): immutable.ListSet does give a consistent iteration order, but inspection suggests that its contains() method appears to be O( n ) for an n-sized set, which is undesirable. What I'd really like is an immutable LinkedHashSet or similar, with near-constant contains performance. |
@odersky said: collection.immutable.LinkedSet which is analogous to the mutable.LinkedHashSet in that it preserves ordering. Contributions would be very much welcome here, |
Run the following code in the Scala REPL:
val o1 = new Object()
val o2 = new Object()
val o3 = new Object()
val o4 = new Object()
val o5 = new Object()
val items = Set(o1, o2, o3, o4, o5)
items.foreach(println)
Observe that the order the items are printed is not the order they were inserted into the set constructor. Further observe that the order is not consistent across multiple invocations of the REPL (i.e. different JVM runs).
This non-deterministic ordering can make bugs harder to reproduce and can lead to confusion if it impacts user-visible output or behaviour. It's also easy to miss this when writing tests, since sets of size < 5 are special implementations Set1...Set4 which do have deterministic iteration order.
The text was updated successfully, but these errors were encountered: