7.8 Boxes
A box is an object with a single value field, which can be accessed from a box bx as bx.value or set to the value of expr using bx.value := expr or other assignment operators like :=. The function Box.value can also be directly used.
A box is normally mutable, but immutable boxes can originate from Racket or Box.snapshot. Assignment is statically allowed but fails dynamically for an immutable box. The Box annotation is satisfied by both mutable and immutable boxes, while MutableBox and ImmutableBox require one or the other.
annotation | |
| |
annotation | |
| |
annotation | |
| |
annotation | |
| |
annotation | |
The Box.now_of form constructs a predicate annotation that matches a box whose values satisfies annotation, but it does not ensure in any way that future values installed into the box will satisfy annot. The given annot must not be a converting annotation. Static information from annot is not propagated to accesses of the box’s values, since there’s no guarantee that the value will still satisfy the annotation.
The Box.later_of form constructs a converter annotation that immediately matches a box without checking that its value currently satisfies annot. The conversion result of the annotation is a view on the original box, but one where annot is checked against a value when it is accessed from the box or for a value to be installed into the box. (A different view of the box might changes its value to one that does not satisfy annot.) Static information from annot is propagated to accesses of the box’s value. Note that a converter annot is applied for each access or update.
MutableBox matches only mutable boxes, and ImmutableBox matches only immutable boxes (that may originate from Racket).
> Box(1) :: Box.now_of(Number)
Box(1)
> Box("a") :: Box.now_of(Number)
::: value does not satisfy annotation
value: Box("a")
annotation: Box.now_of(Number)
Box: current value does not satisfy annotation
current value: "b"
annotation: Number
Box: new value does not satisfy annotation
new value: "c"
annotation: Number
> b
Box(1)
1
> b
Box(2)
> x
1
def: value does not satisfy annotation
value: Box(1)
annotation: matching(Box((_ :: String)))
> Box.value(b)
1
> Box.value(b, 2)
> Box.value(b)
2