I hit a minor grammar snag today that has driven me into an interesting
question. I wrote a type:

  mutable(char)[]

intending to build a vector of mutable characters. Instead, I got a mutable
vector reference:

  mutable ((char))[]

because [] bound tighter than mutable. The error* per se* is simple, and
it's tempting to imagine that it's just a matter of fixing the binding of
"mutable", but it actually raises some interesting issues.

In previous discussions, we've concluded that mutable "fields" are the wrong
model - what we want/need there is a way for objects to preserve their
integrity by some form of access control. Unfortunately this leaves simple
sequence types (array, vector) in a confused position, because we need to be
able to state whether we intend the element type to be mutable or not. For
arrays, this isn't so bad, because the mutability of the elements and the
mutability of the aggregate are the same. But what about vectors?

With the benefit of hindsight, vectors simply should never have been a
primitive type at all. Once we have the nat kind, the payload data structure
is simply:

  struct VecPayload('a, 'len) {
    length : 'len
    elements : 'a['len]
  }

and the vector type itself merely serves to existentially hide the 'len
parameter. If this view is correct, then what we are saying is that
VecPayload is actually an *object*, and when we talk about the mutability of
the elements we're talking about an option on the object's behavior. Or more
precisely: on the *instance*  behavior. The object implementation of vector
clearly supports mutability. Certain instances do not agree to be mutated.

So I'm wondering, tentatively and uncomfortably, whether this confusion
about vector payload mutability does not have, at its heart, a confusion
about what mutability means for objects, and how (indeed *whether*) the
mutable keyword is relevant here at all.

One other point while I'm stirring the pot here: a non-mutable vector is an
example of a mutability constraint that is neither fully shallow nor fully
transitive. The elements may be immutable, but they may be references to
objects that *are* in turn mutable. This takes us head on into challenging
territory that we have visited (unsatisfactorily) before: how to state the
scope (coverage?) of contract in an object graph? Alternatively, how to
capture the relationship between the programmer notion of "object" as a
coherent functional unit, and the runtime notion of object as a collection
of primitive data structures.

mutability isn't the first contract where we've run into this issue, and it
won't be the last.

Help!


shap
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to