Version française
Home     About     Download     Resources     Contact us    

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at

Browse thread
[Caml-list] Strange physical equality behavior
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2003-11-10 (08:29)
From: Jacques Garrigue <garrigue@k...>
Subject: Re: [Caml-list] Strange physical equality behavior
From: Oleg Trott <>

> So returning "true" for "sin == sin" and "sin = sin" wouldn't break
> the above guarantee.

Of course.
And returning true for "sin = (fun x -> cos (x -. acos (-1.) /. 2))"
wouldn't break it either.
The specification is just designed to avoid having to do that: to
allow the compiler to choose the most efficient runtime
representation. It might actually just return "false" when you compare
any two functions, but even this would require some more computation.

> Here are my reasons for wanting such behavior (not just for "sin" of course, 
> but also "(+)" , etc., and especially for "compare"):
> As was discussed lately [1], the functorial interfaces (as used in the 
> standard library) are somewhat clumsy. One solution could be to pass the 
> necessary ordering and hashing functions as optional parameters to "emtpy" or 
> "create". However, in this case, functions would need to be compared at 
> runtime
> compare_functions f g = try f = g with _ -> false
> So e.g. "compare == compare" returning true would be a lot more convenient

The problem is that compare has several implementations, depending on
the type of its argument, to be more efficient. One may imagine tricks
to make sure that any one of these implementations is shared between
all its occurences (but even this may be complicated while keeping
inlining). But generic compare cannot be equal to float compare, while
they are just separated by their types.

The functorial approach offers a much cleaner solution.
Alternatively, you can think of a system of registered comparison
  type 'a comparison = {id: int; compare: 'a -> 'a -> int}
  let count = ref 0
  let make_compare f = incr count; {id = !count; compare = f}
  let same f1 f2 = ( =
If comparison is kept abstract, you can then safely check for
A lighter way would be to combine this registration with the "empty"
function: two sets can be combined if they were created from the same
empty set.

The last solution is not to bother about that: I'm yet to see code
mixing two sets of the same type but with different comparison
functions. Sounds silly.

Jacques Garrigue

To unsubscribe, mail Archives:
Bug reports: FAQ:
Beginner's list: