
On Fri, Apr 23, 2010 at 3:21 AM, Barak A. Pearlmutter
... An invalid comparison evaluating to _|_ is arguably more correct, but I personally find the idea of introducing more bottoms rather distasteful.
Too late! NaN is pretty much the _|_ of IEEE Floating Point.
Yes, of course. But I don't have to like it... What annoys me is that, conceptually, the silently-propagating NaNs more strongly resemble Nothing, with the arithmetic functions lifted into Maybe, Applicative-style. Likewise, comparisons could sensibly be interpreted as returning Maybe Bool or Maybe Ordering. But there's no good way to work that into Haskell without making floats incredibly awkward to use.
In the context of Haskell, which does not have the issue of needing to relax strictness just for NaN, I think the "right thing" would be to have compare give _|_, and maybe also <, >, ==. After all, NaN is outside the carefully defined total ordering of all other IEEE floating point values including +/- Infinity.
The reason this makes me unhappy is that evaluating bottoms is a terrible way to deal with error conditions in pure code. It also makes using floating point values in generic code written for Ord dangerous, because the generic code won't (and can't) do anything to check whether calling compare will produce _|_ even if both arguments are already known to be fully evaluated.
(By the stringent criteria some people are giving for allowing something to be Eq and Ord, Char would also be stripped of them, since after all Char includes _|_. Sort of.)
The difference, of course, is that getting _|_ as a result of using _|_ is tolerable; getting _|_ as a result of using only non-_|_ values makes me sad. To my mind, the fewer ways there are to accidentally introduce _|_, the better. - C.