Promise

From Erights

Jump to: navigation, search

A promise, in E, is a kind of unresolved eventual ref. It is a ref which will resolve to some other ref later; therefore all sends it receives are stored, then forwarded at the time of the resolution. Every promise has a corresponding resolver (though it might be implicit), which constitutes the permission to cause it to resolve to a given other reference (which may itself be a promise).

A local promise is a promise whose resolver is in this vat; local promises are reliably implemented by the local ELib. A remote promise is a promise whose resolver is in a different vat; remote promises are implemented by proxies.

Local promises

The general-purpose operation to create a local promise is Ref#promise/0.

? def [promise, resolver] := Ref.promise()
# value: [<Promise>, <Resolver>]

? Ref.state(promise)
# value: "EVENTUAL"

? Ref.isResolved(promise)
# value: false

Once a promise (local or remote) is resolved, it is indistinguishable from the reference which it is resolved to, whether that reference is Selfless,

? resolver.resolve(99)

? promise
# value: 99

? promise + 1
# value: 100

? promise == 99
# value: true

or Selfish.

? def [promise, resolver] := Ref.promise()
> resolver.resolve(def x {})
> promise == x
# value: true

XXX write tests and doc from the LocalResolver's perspective (isDone, resolveRace/smash, behavior after it is resolved) -- EoCL has some in ref.updoc

Calls and sends

? def [promise, resolver] := Ref.promise(); null

As with any unresolved ref, a promise cannot be called.

? promise(1)
# problem: not synchronously callable: <Promise>.run(1)

However, any sends to the promise are accepted and buffered in the resolver, in time order.

? promise <- (2)
# value: <Promise>

? E.sendOnly(promise, "run", [3])

If the resolver becomes garbage, then so does the buffer; future messages to the promise are silently discarded and do not accumulate. Note that this implies that the promise does not strongly refer to the resolver. (XXX write tests for this using finalizers.)

At the instant a local promise is resolved to another ref (which is known as its resolution), the buffered messages are sent, in the order they arrived, to the resolution.

? var items := []
> def resolution(x) { items with= x }
> resolution <- (4)             # demonstrating exact ordering
> def resolveReturn := resolver.resolve(resolution)
> resolution <- (5)
> resolveReturn

? items
# value: [4, 2, 3, 5]
Personal tools
more tools