[erlang-questions] strictly less-than (Re: [erlang-questions] Ordered set and DETS)

Richard O'Keefe ok@REDACTED
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
> end.

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*
confuse them.

(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
so that
-infinity < all finite numbers < +infinity



More information about the erlang-questions mailing list