3 ms·
> It was stable for any one run :D Not even that, because if you iterate multiple times you get random order in each different iteration: package main
by kokada 2y ago
> It was stable for any one run :D
Not even that, because if you iterate multiple times you get random order in each different iteration:
package main
func main() {
m := map[string]bool{"foo": true, "bar": false, "baz": true, "qux": false, "quux": true}
for range 5 {
for k := range m {
println(k)
}
println()
}
}
$ go run ./main.go
bar
baz
qux
quux
foo
foo
bar
baz
qux
quux
qux
quux
foo
bar
baz
baz
qux
quux
foo
bar
quux
foo
bar
baz
qux
> You say you don't care about order, but then you clarify that you do want them to be stable between runs.
Being stable between runs doesn't mean I want a specific order. Slightly different things.
> Those are not the same thing. To a computer without judgement, any order is fine. The first run is somehow blessed by you, so any runs after seem off or weird. If it didn't actually matter to a computer, it wouldn't care if it was different each run.
If you want to argue about how computers work, remember that computers are bad at doing random things, this is why they need special hardware to do so.
The fact that Go goes as far to actually randomise each iteration is the surprising thing here, making iteration unstable, and not the fact that iterating between hash maps values are random.
- lelanthran 2y ago> The fact that Go goes as far to actually randomise each iteration is the surprising thing here, I gotta be honest, having come to Go after having first programmed professionally for around 25 years, I have never run into this problem. My expectation for hashmaps was set decades ago, and it was set as "Thou Shalt Not Depend On The Order Of Hashmaps!" :-) Having used hashmaps via some obscure C library in the 90s, I quickly came to realise that I couldn't rely on the order - simply adding an element and then immediately removing it with no lines of code in between those two calls was enough, in some cases, to completely mess up whatever order I thought there was. My own OSS hashmap library, on github, specifically doesn't mention order, because I (maybe naively) assumed that everyone reaching for a hashmap already knows that the order isn't guaranteed to be stable at all, even if the hashmap is never modified by the caller in between reads.
- kokada 2y ago> simply adding an element and then immediately removing it with no lines of code in between those two calls was enough, in some cases, to completely mess up whatever order I thought there was. Yes, this is what I expect too. But this is NOT what Go is doing here. Go is actually randomising the order EVERY time you try to iterate, even if you do NO manipulation of the items inside the map. See this comment thread for more details: https://news.ycombinator.com/item?id=41274850#41276274 https://news.ycombinator.com/item?id=41274850#41276274. This is the surprising part, not that the iteration order may change if you add/remove items. > My own OSS hashmap library, on github Does your hashmap library, say, have a `iterate()` method that randomises the order of items every time it is called? If yes, ok, we are talking about the same thing here. But I am almost sure that it does not, and this is what Go is doing here.
- lelanthran 2y ago> Go is actually randomising the order EVERY time you try to iterate Which is 100% perfectly within specification of the hashmap concept. It may not match your expectation of what a hashmap is, but it is what it is, and that's what a hashmap is. IOW, there is no guarantee, and a library that randomises the order that it returns hashmap elements when iterating is perfectly correct!
- kokada 2y agoI never said once that the implementation is incorrect, just that it is weird and uncommon.
- coldtea 2y agoYes, but the expectation for non-weirdness is not based on the actual specs a hashmap must have, just on contingencies ("but no other language I know does it like this") that apply to quite narrow criteria (iterating over statically added hashmap entries, if you added entries from a dynamic source, or added them in parallel, etc, they could very well change for every run without the language randomizing anything explicitly).