3 ms·
Basically, it doesn't work for sorting. https://pkg.go.dev/golang.org/x/exp/slices#Sort https://pkg.go.dev/golang.org/x/exp/slices#Sort mentions this explicitly
by jerf 4y ago
Basically, it doesn't work for sorting. https://pkg.go.dev/golang.org/x/exp/slices#Sort https://pkg.go.dev/golang.org/x/exp/slices#Sort mentions this explicitly and has a suggested alternative solution. You can see this in action here: https://go.dev/play/p/6GuDa8ziU0L https://go.dev/play/p/6GuDa8ziU0L
Note in the second case, that's not "Go" sorting NaNs to the front, that's the requested result from the passed-in function. You could create any result you wanted with a suitable choice of such function.
This isn't particularly special to Go. Most languages have "quirks", to put it charitably, around floats. Even Haskell would have similar behavior. It's really the IEEE standard that is broken, arguably; defining an entity that is not equal to itself proceeds to effectively break a huge swathe of things that you may not have even realized was based on the presumption that the identity property holds, because... why would you think about what is based on that? It's so foundational. As anyone who has dealt with NaNs for any period of time can attest, it's really difficult to work with such entities.
(Similarly, while I understand what they were trying to get at, I think SQL NULL should be equal to itself. I could be down with NULL < 1 being false and NULL > 1 being false but I'm not a huge fan of how it's NULL either. We've had many languages written since then with more conventional ideas about "invalid" values and how they participate in operators and I think the modern way almost everything else works is better, even if it arguably less "correct".)
- jeffbee 4y agoThe entire C++ STL is a huge footgun for this very reason. None of the algorithms work on floats unless you guarantee the absence of NaN (which the STL assumes without being terribly vocal about it).
- nerdponx 4y agoThis is problematic even in dependently-typed languages like Idris, because while you can require a proof that something is not (or does not contain) NaN, it's pretty easy to call a function that is allowed to return NaN, which means that you actually cannot satisfy that proof after calling one of those functions unless you actually check again.
- dinosaurdynasty 4y agoRust handles this in a "correct", if annoying way: the stdlib sort requires its elements to have a "totally ordered" trait, and floating point doesn't have that trait. You have to either give a custom comparison function, or use a "non-NaN and totally orderable floating point" type some non-stdlib crates have.
- majewsky 4y agoThis perfectly illustrates the cultural difference between Rust and Go: Rust wants to be "correct", Go wants to be "good enough".