Value Objects in Newspeak

This is a quick dump of a rough design sketch for Value objects in Newspeak, which builds upon section 3.1.1 of the current version of the Newspeak language specification.

  1. Value classes allow explicit intent. The class declaration is automatically annotated with metadata that expresses the intent for instances to be value objects.
  2. Value classes use special syntax that introduces the said metadata annotation (e.g. valueclass X instead of class X).
  3. Value classes can only be mixed in with other Value classes.
  4. Value classes can only have immutable slots.
  5. The root of the value classes is Value, which extends from Object. The Value class overrides the ==  method and delegates it to =. The Value class overrides = to compare all the slots recursively using =. The Value class overrides the asString method to give a neat stringified representation of the Value object in a JSON-like format. Value class computations for =, asString bottom out on built-in Value classes, like Number, Character, String etc. (overriding = and asString is explicitly inspired by the behavior of case classes in Scala).
  6. The Value class overrides the identityHash method to delegate to the hash method, and overrides the hash methods with some simple, yet-to-be-determined, recursive hashing algorithm (e.g. XOR-ing the hashes of all the slots).
  7. Value objects can only point to other Value objects.
  8. Value class declarations can only be nested inside other Value class declarations.
    Update 2/10/2012: Another option that seems very attractive right now would be to allow value class declarations to be lexically nested inside non-value class declarations but cut off from the non-value part of their lexical scope (the enclosing object chain stops at the outermost value class, excluding all enclosing non-value classes).
  9. This implies the enclosing object of a Value class is always a value object.
  10. Simply annotating a class declaration as “<Value>” is not enough. Syntax is required for valueclass declarations in order to ensure that Value classes always extend other Value classes. This allows a Value class with no explicit superclass clause to implicitly extend the built-in Value class, instead of Object, which is the default superclass for regular classes.
  11. The constraints on Value objects and Value classes are verified at mixin application time (the superclass is a Value class), and object construction time (all slots contain other Value objects).
  12. The enclosing object does not need to be verified at mixin application time, because the enclosing scope of a Value class declaration can be verified at compile time.
  13. Value classes are also Value objects.
  14. nil is a Value object.
  15. Value class declarations can contain nested non-value (regular) class declarations. More generally speaking, Value objects can produce (act as factories for) non-value objects.
    Update 2/10/2012: An important corollary of the above is that non-value classes enclosed in a value object are value objects themselves.
  16. Value objects are awesome! They are containers for data and the unit of data transfer between Actors in Newspeak, and also the building block for immutable data structures.
  17. Update 11/24/2011:
  1. Every class whose enclosing object is a value object is also a value object (but not necessarily a value class!).
    Update 11/27/2011:
    Justification for the above is: if multiple equivalent instances of a value class are indistinguishable, then all of the instances’ constituent parts, nested classes included, must be indistinguishable as well. Think (a == b), but (a NestedClass == b NestedClass) not – this is unacceptable!
  2. We must determine rules for when closure and activation objects are value objects, so we can safely deal with simultaneous slots in value classes (at construction time, the closure object that captures each simultaneous slot initializer must be a value object, then at lazy evaluation time, the result must be a value object, otherwise an exception is thrown and the simultaneous slot is not resolved).
    Update  2/10/2012: One alternative that comes to mind but does not seem very attractive would be to have special syntax for closures that are value objects, say {{ … }} denotes a closure that is always a value object and has no access to enclosing mutable state.
    A more attractive alternative would be to extend the syntax for object literals to support value object literals. All of a sudden object literals appear much more important than before. For example, value-object closures and/or object literals make it possible to build  a Scala-like parallel collections library on top of actors.
    Actually the above is not quite correct: a Scala-like parallel collections library in newspeak would benefit more from value class literals that can be nested inside non-value classes