5 ms·
They say that, and then turn around and show an example using IEEE-754 Doubles. You've got two infinities and two "not a number" values. What your type system
by ken 7y ago
They say that, and then turn around and show an example using IEEE-754 Doubles. You've got two infinities and two "not a number" values. What your type system thinks is a number isn't even necessarily a number. Maybe.
Better be sure to call the "isNaN()" and "isInfinite()" methods all over the place, because those are the worst edge cases of all and your language provides no help in detecting or avoiding them. It's like having 3 or 4 other None values, where they don't even use the same system as your standard Option type.
If I had a nickel for every time I saw "NaN" appear on a webpage or a web browser console log ... We throw up our hands and say, yeah, well, JS is terrible -- but no static functional language I know of is any better.
- JoelMcCracken 7y agoHaskell is so much better, and you would learn that with about 5 minutes learning about the number types
- eru 7y agoHaskell still doesn't track NaN in the type system.
- JoelMcCracken 7y agoYou're right, it does, and it exists at the value level if you are using floating point. But in Haskell you have, for example, Rational numbers to avoid many such problems. I was, however, surprised to not see any kind of a (significant) `safeDiv` function on hackage, and no NonZero newtype (outside of quickcheck). But, for this kind of thing its so easy to roll yourself, I am guessing this is what people do (and I have seen).
- ska 7y ago> But in Haskell you have, for example, Rational numbers to avoid many such problems. Hey, it's for sure nice to have a rich numeric stack (see also some lisps), but in numeric work "use something else" is very rarely a practical answer to issues with IEEE-754.
- JoelMcCracken 7y agoSure, it is, but the thing is that a hugely significant amount of the time I've seen those NaNs happen is because of a lack of understanding/care on the part of the devs, and not because they are doing scientific computing. There seem to be a large disconnect here. A big chunk of people don't need the speed that FP math brings, what they need is exactness. And, for most languages with a C-based lineage, actually correct floating point math support seems to fit in the "someday/maybe" categories.
- eru 7y agoYes, rational numbers are the better default choice. You should get floats only when you ask for them.
- JoelMcCracken 7y agoUnfortunately, for many languages, its the only real choice (without introducing some new significant dependency!)
- ridiculous_fish 7y agoHaskell's intro page starts with the infamous minimalist quicksort, which mishandles NaN! https://wiki.haskell.org/Introduction#Quicksort_in_Haskell https://wiki.haskell.org/Introduction#Quicksort_in_Haskell
- saagarjha 7y agoHow should it handle NaN? It's not clear where an incomparable value should go when sorting.
- ken 7y agoWhy is NaN even a concept in modern languages? We don’t have a special “not a string” that all string functions return when they have no useful value to return.
- saagarjha 7y agoBecause it's part of IEEE 754.
- ken 7y agoSo? There’s lots of old standards that don’t fit well with modern programming languages, so we abandoned them, or only use the parts that still make sense.
- saagarjha 7y agoIEEE 754 is one of the standards like two's complement arithmetic which are widely used and have a number of clear advantages, so we continue to use them.
- mac01021 7y agoBecause what is the CPU supposed to do if you divide zero by zero or take the square root of -1? It's actually not exactly a decision being made by the language designers. The IEEE standard governs the floating point logic embedded in ALU hardware. Programming languages tend to expose floating point math in its rawest form for performance reasons.
- adamch 7y agoYou can always use a fixed-precision numeric type. You might be thinking "what about libraries that require floating-point", and that's a good concern. Luckily in Haskell there's the Num typeclass, so your libraries can let users use whatever fractional number type they'd like.
- a1369209993 7y agoFun fact, Num basically requires inf and nan unless you're willing to tolerate either terrible overflow (non-)handling (eg Int,SatInt) or memory blowup (eg Integer,BaireReal). # where R is some r such that Num r let huge = <the largest (finite) value in R> let inf = huge * huge # can't be finite unless you # truncate or saturate or something let nan = inf - inf # can't be either of # infinite (infinitely < +inf and > -inf), or # finite (catastrophic rounding errors) Num doesn't allow inf or nan to be Maybe R, so you're stuck filtering out in-band errors from a bare R.
- eru 7y agoThere are some research languages that deal with this.