On this page:
Equatable
Equatable.hash
Equatable.now_  hash
Equatable.identity_  hash
Equatable.hash_  code_  combine
Equatable.hash_  code_  combine_  unordered
0.45+9.1

9.1 Equatables🔗ℹ

Any value is equatable. Implementing the Equatable interface customizes the way that instances of a class are compared for == or is_now and hashed for maps and sets that use == or is_now.

Provided only in the class space, not the annot space.

An interface that a class can implement (publicly or privately) to customize the way its objects are compared for == or is_now and hashed for maps and sets that use == or is_now. The interface has two methods that must be overridden for ==, and two methods for is_now whose default implementations use the methods for ==:

  • equals(other, recur): Takes another object that is an instance of the same class (or a subclass), and returns a non-#false value if the objects are equal in the sense of ==, #false otherwise. Use the given recur function to compare components of the two objects, instead of using == on the components.

    If a class has mutable fields whose state is externally observable, take care not to treat objects as == if they should be equivalent only by is_now. Override both the equals and now_equals to distinguish == and is_now equality.

    If two objects are equal in the sense of ===, then they are automatically also equal by ==. An equals method implementation is never called on an obejct with itself as other.

  • hash_code(recur): Returns a hash code for the object, which is an exact integer. The hash code should be consistent with equality via ==. Use recur to compute hash code for components of the object, and use the functions Equatable.hash_code_combine and Equatable.hash_code_combine_unordered to combine component hash codes.

    If a class has mutable fields, the hash code produced by hash_code normally should return the same result as Equatable.identity_hash. Override now_hash_code to implement hashing consistent with is_now.

  • now_equals(other, recur): Like equals, but for equality in the sense of is_now. The default implementation of this method calls the equals method; it passes along the given recur function, which means that is_now will used for nested comparisons (assuming that the called equals method uses recur as it should).

  • now_hash_code(recur): Like hash_code, but for equality in the sense of is_now. The default implementation of this method calls the hash_code method; it passes along the given recur function, which means that nested hashing will create is_now-compatible results (assuming that the called hash_code method uses recur as it should).

A class gets a default equality implementation that recurs to compare fields for == only if the class has no mutable fields. When the class has mutable fields, is default equality implementation for == uses === comparisons. The default equality implementation always recurs to fields for is_now comparisons.

The Equatable interface normally should be implemented privately, so that the methods do not have to check what class other instantiates or whether recur is a function.

class Posn(x, y):

  private field cache = #false

  method dist():

    cache || (block:

                def v = math.sqrt(x*x + y*y)

                cache := v

                v)

  // since `cache` is mutable, the default equality

  // comparison would only make `===` objects equal

  private implements Equatable

  private override equals(other :: Posn, recur):

    recur(x, other.x) && recur(y, other.y)

  private override hash_code(recur):

    Equatable.hash_code_combine(recur(x), recur(y))

> Posn(3, 4) == Posn(3, 4)

#true

function

fun Equatable.hash(v :: Any) :: Int

Returns a hash code for v that is consistent with ==.

function

fun Equatable.now_hash(v :: Any) :: Int

Returns a hash code for v that is consistent with is_now.

Returns a hash code for v that is consistent with ===.

function

fun Equatable.hash_code_combine(hc :: Int, ...)

  :: Int

 

function

fun Equatable.hash_code_combine_unordered(hc :: Int, ...)

  :: Int

Combines hash codes to produce a new one. Information is generally lost in the combination, but this combining function mixes integers in a suitable way to produce good results for hashing.

See Equatable for an example.