Keywords · TYPE · OPTION

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 }
An 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
A union that is either a circle or a rectangle.

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.