Combining Capabilities

When a field of an object is read, its reference capability depends both on the reference capability of the field and the reference capability of the origin, that is, the object the field is being read from.

This is because all the guarantees that the origin reference capability makes have to be maintained for its fields as well.

Viewpoint adaptation

The process of combining origin and field capabilities is called viewpoint adaptation. That is, the origin has a viewpoint, and can "see" its fields only from that viewpoint.

Let's start with a table. This shows how fields of each capability "look" to origins of each capability.

iso field trn field ref field val field box field tag field
iso origin iso tag tag val tag tag
trn origin iso trn box val box tag
ref origin iso trn ref val box tag
val origin val val val val val tag
box origin tag box box val box tag
tag origin n/a n/a n/a n/a n/a n/a

For example, if you have a trn origin and you read a ref field, you get a box result:

class Foo
  var x: String ref

class Bar
  fun f() =>
    var y: Foo trn = get_foo_trn()
    var z: String box = y.x

Explaining why

That table will seem totally natural to you, eventually. But probably not yet. To help it seem natural, let's walk through each cell in the table and explain why it is the way it is.

Reading from an iso variable

Anything read through an iso origin has to maintain the isolation guarantee that the origin has. The key thing to remember is that the iso can be sent to another actor and it can also become any other reference capability. So when we read a field, we need to get a result that won't ever break the isolation guarantees that the origin makes, that is, read and write uniqueness.

An iso field makes the same guarantees as an iso origin, so that's fine to read. A val field is globally immutable, which means it's always ok to read it, no matter what the origin is (well, other than tag).

Everything else, though, can break our isolation guarantees. That's why other reference capabilities are seen as tag: it's the only type that is neither readable nor writable.

Reading from a trn variable

This is like iso, but with a weaker guarantee (write uniqueness as opposed to read and write uniqueness). That makes a big difference since now we can return something readable when we enforce our guarantees.

An iso field makes stronger guarantees than a trn origin, and a trn field makes the same guarantees, so they're fine to read. A val field is globally immutable, so that's fine too. A box field is readable, and we only guarantee write uniqueness, so that's fine too.

A ref field, though, would allow writing. So instead we return a box.

Reading from a ref variable

A ref origin doesn't modify its fields at all. This is because a ref origin doesn't make any guarantees that are incompatible with its fields.

Reading from a val variable

A val origin is deeply and globally immutable, so all of its fields are also val. The only exception is a tag field. Since we can't read from it, we also can't guarantee that nobody can write to it, so it stays tag.

Reading from a box variable

A box variable is locally immutable. This means it's possible that it may be mutated through some other variable (a trn or a ref), but it's also possible that our box variable is an alias of some val variable.

When we read a field, we need to return a reference capability that is compatible with the field but is also locally immutable.

An iso field is returned as a tag because no locally immutable reference capability can maintain its isolation guarantees. A val field is returned as a val because global immutability is a stronger guarantee than local immutability. A box field makes the same local immutability guarantee as its origin, so that's also fine.

For trn and ref we need to return a locally immutable reference capability that doesn't violate any guarantees the field makes. In both cases, we can return box.

Reading from a tag variable

This one is easy: tag variables are opaque! They can't be read from.

results matching ""

    No results matching ""