4

In Caml, the operator == tests the physical equality between two values of a same type. It can be used in particular to compare functions in this way.

One has for instance

# print_string == print_string;;
- : bool = true

but, surprisingly,

# (==) == (==);;
- : bool = false

This expression should be evaluated into true.

Can you explain this behavior?

Samuele Giraudo
  • 409
  • 2
  • 14
  • 6
    `(==)` does not exist as a closure ready to be, say, passed to a high-order function. Its applications are created directly in inlined form. A closure is allocated each time one is needed, and two such closures are allocated, at different addresses, when you write `(==) == (==)`. If you want similar properties to `print_string`, with current OCaml implementations, give a name to a single closure that you will force yourself to use everywhere: `let phys_equal x y = x == y;;`. This might also be more memory-efficient than allocating closures for an unapplied `(==)` every time. – Pascal Cuoq Jun 12 '16 at 17:47

1 Answers1

6

The behavior of == is defined in the Pervasives module:

e1 == e2 tests for physical equality of e1 and e2. On mutable types such as references, arrays, byte sequences, records with mutable fields and objects with mutable instance variables, e1 == e2 is true if and only if physical modification of e1 also affects e2. On non-mutable types, the behavior of ( == ) is implementation-dependent; however, it is guaranteed that e1 == e2 implies compare e1 e2 = 0

Since functions aren't mutable, the only guarantee is that if they compare equal with == they will also compare equal with compare. Since functions aren't guaranteed to be be comparable with compare, this essentially means that == isn't useful at all for comparing functions.

# compare (==) (==);;
Exception: Invalid_argument "equal: functional value".

If == returns false for immutable values, there are no guarantees at all. This means that == is free to return false at any time for any immutable values. So it's not improper to return false in your second example.

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108