[Grace-core] Values / Traits / Purity / Const / Static...

James Noble kjx at ecs.vuw.ac.nz
Sat Mar 9 00:06:16 PST 2013


We've talked a bit about value types, purity, stateless traits,
and static computations.  All these things seem inter-related.

The Newspeak spec defines values as:

> Values: Deeply Immutable Objects
> 
> Some objects can not change after they are created. They are deeply
> immutable and known as value objects. A value object is globally
> unique, in the sense that no other object is equal to it. An object o
> is a value object iff, under the assumption that o is a value object,
> it can be shown that:
> 
>  * All its slots are immutable and contain value objects.
>  * Its enclosing objects (3.3) are all value objects.
>  * Its class inherits from class Value and does not override its identity method (==).
> The class Value declares an identity method that returns the same
> results as its equality method

In Newspeak part of the point is that you can pass Values between
different VMs (different Isolates, different Actors) *without* any
links back to their defining VMs.  

That seems quite good as far as it goes. For us, its probably too
strong, because Newspeak modules are stateless classes, and thus
values, but our modules are objects and aren't values.  (Or perhaps
can values only be declared in modules that are themselves values?).
We could adopt a similar definition, but rather than saying its
enclosing objects must all be values, we can say that: 
  * it doesn't close over any vars
  * it doesn't invoke any "outer" methods that (transitively) access any vars...
and either require or provide an "is value" annotation on objects to
capture the programmer's intention, and perhaps a matching "is pure"
annotation on methods.

Generally, pure methods can only call other pure methods. All methods
on a value are pure by the definition of a value, but statefull objects
could also have pure methods. Again this can be checked statically or
dynamically. Statically we're familiar with this, Michael Ernst has
had a cottage industry working on definitions of "reference
immutability". Dynamically there have been a few papers published on
e.g. read-only-objects in Smalltalk. Once brutal way to check for
purity is to set a bit (in the interpreter, or in the execution
context of the formalism) that whenever a pure method starts executing
--- this is preserved going down method calls.  If any mutable state
is accessed (technically: read) while that bit is set, then you throw
an error.  Any method called on a value would set the same bit.

Read-only-ness is closely related to purity --- you have a slightly
different bit, and you throw an error whenever you *write* to any
state.

Then finally there is staticness or const.  (Dart is big on const
http://www.dartlang.org/docs/spec/latest/dart-language-specification.html#id.hzs87hup8wb
to minimise startup time). This is different to but related to values:
a value may not be a const (Random.nextInteger) and I think a constant
doesn't have to be a value (say a mutable object bound to a top-level
def..?).  In our case we want things (like factory methods) to be
const so that we can precompute / inline them ahead of time.
Perhaps a more sophisticated VM would still be able to do that even if
things weren't const?  but even Self separated consts from variables, 
and operations that set variables from meta-operations that changed
the value of constants, so we probably do too...



More information about the Grace-core mailing list