The issues of hash codes, equals methods, and what object identity really means is quite fundamental, and quite fraught. Certainly the Java solution of programmers defining equals and hash methods – according to some rather strict guidelines – has proven to have many problems in practice, and James has found it an annoying two lectures to teach for Java or C++.
William Cook (OOPSLA 2009) has argued that if objects are truly abstractions, equals and hash-code should be left up to each object to implement: there should be “no built-in notion of equality” because this would break the abstractions offered by objects. On the other hand, it’s not clear a language would be useful without some kind of equals for at least some kind of objects. Haskell offers another option: make an explicit interface (like the Eq type class) and only objects that provide equality should confirm to that interface. Hashcodes could be treated in the same way. While this would mean not every object had to participate in equality, we would still have to teach students about the necessarily difficult contracts of those methods. We could be more extreme: following Derek Rayside & Daniel Jackson and generate equality methods automatically based on explicit class invariants. But that seems a little far for a practical language today.
We propose that Grace will adopt a much more straightforward approach. Grace’s equals will be based on Henry Baker’s Egal predicate – structural equality of immutable state – thus making it similar to Clojure. Any mutable object (an object with at least one field) will only equal itself. Immutable objects (comprising only constants and methods, but no writeable fields) will be equal to other objects with the same structure (constants and methods) and the same values for all of those constants. Grace will provide just one equality predicate, written = (or !=) using this definition, and programmers will not be able to override it. Compatible hashcodes will also be provided.
Compared with Java or Smalltalk, this is hopefully much simpler, “does the right thing” for many common cases, and encourages immutable objects. The two main difficulties are first, that it cannot cope with objects whose abstract state may be equal but their “concrete” state is not. A linked list and an array list with identical contents will not be =, even if they are immutable. The second difficulty is that two mutable objects, two array lists, say, will never be = even if they have identical contents and are two instances of the same class. = in Grace is stable, if e1 = e2 is ever true, it will always be true. This cannot apply to mutable objects (unless e1 and e2 are actually the same object) . To compare or index using collections of objects, programmers will need use some kind of immutable objects: Grace will provide immutable tuple literals and methods to convert collections into tuples.
A key advantage of this definition of = is that immutable objects can act as pure values. Especially for (so-called) value objects — immutable objects containing only other immutable objects — Grace programs cannot distinguish between different instances with the same value, just as in most languages integers are compared by value, not by reference (you can’t tell the difference between the integer “1” even at different memory addresses). A Grace implementation can support value objects using whatever implementation is most efficient: either passing by reference always, by passing some types by value, or even by inlining fields into their containing objects, and doing a field-update if the containing object assigns in a new value.
In this way, Grace hopes to support a simple and stable definition of object equality, hashcodes, and value types – all without requiring Grace programmers to write any code.
Some references:
- William Cook’s essay http://www.cs.utexas.edu/~wcook/Drafts/2009/essay.pdf
- http://c2.com/cgi/wiki?ValueObjectHypotheses
- http://c2.com/cgi/wiki?CanValueObjectsContainReferenceObjects
- Dirk Riehle’s Value Objects http://dirkriehle.com/computer-science/research/2006/plop-2006-value-object.pdf
- Value Objects in Smalltalk http://www.esug.org/data/ESUG2009/IWST/iwst09_submission_3.pdf
- Henry Baker’s Equal Rights for Functional Objects http://home.pipeline.com/~hbaker1/ObjectIdentity.html
- Derek Rayside & Daniel Jackson on generating equals and hashes from abstraction functions in Java http://sdg.csail.mit.edu/pubs/2009/icse09-object-contract.pdf
- Stephen Nelson’s study of Java equals and collections: http://ecs.vuw.ac.nz/~stephen/papers/tools10-paper.pdf