OPTION
An OPTION is one named variant of a union
TYPE, together with the payload it carries.
Format
The grammar of a single OPTION line:
OPTION ::= "OPTION" type identifier
type ::= name [ "(" type { " " type } ")" ]
name ::= identifier { "." identifier }
identifier ::= letter { letter | digit }
OPTION keyword is followed by the payload type and then the variant's name.Usage
An OPTION keyword can only live inside a
TYPE keyword.
Inside a TYPE
Names one variant of the union, together with the payload type that variant carries.
TYPE Shape
OPTION Circle circle
OPTION Rect rect
Each option is one indented line under a type header, naming a variant of that union and the payload type it carries. A type built from options is a union; a type holds fields or options, never both.
Can Contain
Nothing. An OPTION is a leaf: a payload type and a name. It has no body and opens no
indented lines — it only names one variant of the union it sits in.
Targets
The same example, rendered to each target. A union becomes that target's idiomatic sum type, and
each OPTION becomes one variant carrying its payload type.
JavaScript
// a tagged value: { tag: "circle" | "rect", value }
class Shape {
constructor(tag, value) { this.tag = tag; this.value = value; }
static circle(value) { return new Shape("circle", value); }
static rect(value) { return new Shape("rect", value); }
}
// value.circle projects reactively: (s.tag === "circle" ? s.value : null)
TypeScript
type Shape =
| { tag: "circle"; value: Circle }
| { tag: "rect"; value: Rect };
const Shape = {
circle: (value: Circle): Shape => ({ tag: "circle", value }),
rect: (value: Rect): Shape => ({ tag: "rect", value }),
};
Dart
sealed class Shape {}
final class ShapeCircle extends Shape { final Circle value; ShapeCircle(this.value); }
final class ShapeRect extends Shape { final Rect value; ShapeRect(this.value); }
Swift
public enum Shape {
case circle(Circle)
case rect(Rect)
}
Go
type Shape struct {
tag string
value any
}
func Shape_circle(v Circle) Shape { return Shape{"circle", v} }
func Shape_rect(v Rect) Shape { return Shape{"rect", v} }
Rust
enum Shape {
Circle(Circle),
Rect(Rect),
}
Zig
const Shape = union(enum) {
circle: Circle,
rect: Rect,
};
JSON
["U", "Shape", [], [
["P", "circle", "Circle"],
["P", "rect", "Rect"]
]]
Related
A type built from options is a union; the record counterpart of an option is a
FIELD — where a union is exactly one of
its options, a record is every field at once, and both are declared with
TYPE. Projecting an option yields an
Optional, itself just the built-in union with some and none
options, which is why reading a variant returns one. Back to
the language.