[erlang-questions] learning Erlang: factoring primes

Tue May 8 04:27:09 CEST 2007

On 7 May 2007, at 9:29 pm, Richard Carlsson wrote:

> ok wrote:
>> In Prolog, == means "exact identity" and
>> =:= means "numerically equal after evaluation".  I cannot imagine why
>> Erlang swapped them.  I keep on tripping up over this.

> For two terms X and Y, one of X < Y, X == Y, or X > Y is always true.
> If you substitute =:= for ==, none of them is true if e.g. X is 0 and
> Y is 0.0. I haven't programmed in Prolog in a long time, so I don't
> recall how this is handled there. Isn't there a :< and :> or somesuch?

Prolog has two sets of comparison operators:

     Term comparison:
	@< @=< ==
	@> @>= \==
     Arithmetic comparison:
	<  =<  =:=
	>  >=  =\=

There are three major differences:
(1) The arithmetic comparison predicates evaluate their arguments
     as arithmetic expressions; term comparison ones don't.
(2) Arithmetic comparisons regard numerically equal numbers as
     equal, even when they are of different types.  So 0 =:= 0.0
     (even though 0 \== 0.0) and 0.0 =:= -0.0 (even though 0.0 \== -0.0)
(3) Term comparison is a total order; even restricted to numbers
     arithmetic comparison is only a partial order (thanks to IEEE
     arithmetic) even when restricted to numbers.

Apparently thinking that the only significant difference was (1),
and noting that Erlang evaluates function arguments, the Erlang
designers started out by identifying term comparison and arithmetic
comparison.  When floating point was added, they noticed difference (2)
and, to put it bluntly, wrecked term comparison.  Note that
	2 < 2.0
	2 > 2.0
are both false; this means that the "term comparison" operators now
completely fail to discriminate terms that are observably different.
Worse still, it is downright EASY to find three terms X, Y, Z such
	X == Y
	Y == Z
	X < Z

	W = 1 bsl 66,
	X = W - 1,
	Z = W + 1,
	Y = float(W),
	{X == Y, Y == Z, X < Z}.
The answer is {true,true,true}.  Whatever happened to "things which are
equal to the same thing are equal to each other"?

THIS WRONG?  Not me, or at any rate only when very carefully and
explicitly limited to date where it works.

(The same problem shows up in other languages.  The problem is that
the 'floating point contagion' rule which is appropriate when
COMBINING values is not appropriate for COMPARING them.  When you
compare a floating-point number with a large integer, you should
act AS IF you converted the floating point number to an exact rational,
rather than converting the integer.)

The result is unsatisfactory in yet a third way.  EITHER < conforms
to IEEE rules, in which case term ordering is NOT a total order, or
it doesn't, in which case it's not what we want as an arithmetic order,
or you forbid IEEE infinities and NaNs, in which case you have a
really terrible time interfacing with other people's code which does
NOT forbid those things (which were, after all, put in the standard for
excellent reasons).  If you want to ship floating point numbers around
the net (and we have some people here who like to do that kind of thing)
you DON'T want some strange language refusing to pass your data through!

Term order and arithmetic order really are different, and it's NOT just
in the equality comparison that the differences show up.

> Here's a mistake I've seen in code that partitions elements:
>   if X > Y -> ...;
>      X =:= Y -> ...;
>      X < Y -> ...
>   end

This is where Prolog and Haskell shine:
       case compare x y of
         LT -> ...
         EQ -> ...
         GT -> ...

More information about the erlang-questions mailing list