[erlang-questions] strictly less-than (Re: [erlang-questions] Ordered set and DETS)
Tue Sep 7 08:27:35 CEST 2010
On Sep 7, 2010, at 11:04 AM, Nicholas Frechette wrote:
> Incidentaly, matching would then work with numbers:
> case 1.0 of
> 1 -> currently_doesnt_match;
> _ -> currently_always_matches
Trust me, you *really* don't want to go there.
To start with, while -0.0 and +0.0 compare equal under
IEEE rules, they also BEHAVE DIFFERENTLY. But both of
them are numerically equal to the integer 0.
I've seen what happened in VM/PROLOG, where they had a
"feature" of allowing fuzzy matching in clause heads.
It made trivial cases look kewl, but it made
reasoning about programs incredibly hard, because
X = Y and Y = Z did not imply X = Z. Heck, even the
order in which you wrote the arguments could matter.
Floats have the property that there is an number X
such that X = X+1. Integers do not. Let's *never*
(One of the things I just *love* about Ada and Haskell
is that they do not allow 'mixed mode arithmetic'.)
> Thus imo, when ordering things in erlang, one should use the comparison
> operators that coerce
Oh no, no, no. Please NO! That way lies failure of transitivity,
which is a DISASTER for sorting. More precisely, there is a way to
do comparison-by-coercion that works, and there's one that doesn't,
and the one language designers tend to pick is the one that doesn't.
Suppose there are two kinds of numbers: Q and F.
Q numbers are exact (integers, rationals).
F numbers are inexact (floats).
If you compare Q1 <= Q2, no problem.
If you compare F1 <= F2, no problem.
What happens if you compare Q1 <= F2
or F1 <= Q2?
The popular technique is what Fortran, Pascal, and C do:
convert the Q number to F format, and do F comparison:
Q1 <= F2 iff uglify(Q1) <= F2
F1 <= Q2 iff F1 <= uglify(Q2).
The problem with that is that it is possible to find
numbers X Y Z such that
X <= Y
Y <= Z
*and* X > Z
Like I said, disastrous for sorting.
The right way to do it is
Q1 <= F2 iff Q1 <= make_exact(F2)
F1 <= Q2 iff make_exact(F1) <= Q2
This is not particularly easy, and it requires
some care. Arguably we want
(1 bsl 8000) < 1.0/0.0
-infinity < all finite numbers < +infinity
More information about the erlang-questions