Skip to content

Enums, Unions & Patterns

Jiang separates finite tag sets from payload-bearing sum types:

  • enum defines named members.
  • union defines a safe tagged union where variants may carry payloads.
enum Mode {
read,
write,
}
Mode mode = Mode.read;
Mode other = .write;

Members may specify values:

enum Priority {
low = 1,
medium,
high,
}

Enums can define static and instance methods:

enum Mode {
read,
write,
static Int answer() {
return 42;
}
Int value() {
return self.value;
}
}
Int a = Mode.answer();
Int b = Mode.read.value();
union Result<T, E> {
T ok;
E err;
}
Result<Int, ParseErr> a = Result.ok(42);
Result<Int, ParseErr> b = .err(ParseErr.bad);

Same-type variants can be grouped:

union Value {
Int int_value, code;
Double float_value;
UInt8[] text;
}

Unions can bind an explicit tag enum:

enum Kind {
int_value,
text,
}
union(Kind) TaggedValue {
Int int_value;
UInt8[] text;
}
if value is .int_value(_ n) {
print(n);
} else {
print(0);
}

Use _! for a mutable inferred binding:

if value is .int_value(_! n) {
n = n + 1;
}

Optional values use some:

if maybe is some payload {
print(payload);
} else {
print(0);
}
Int code = switch mode {
.read => 1,
.write => 2,
}

Union payloads:

Int result = switch value {
.int_value(_ n) => n,
.code(_ code) => code,
.float_value(_) => 0,
.text(_ bytes) => bytes.length,
}

Optional values:

Int value = switch maybe {
some payload => payload,
null => 0,
}

is and switch branch roots accept:

  • optional patterns: some payload
  • variant patterns: .name(...) or Type.name(...)
  • literal patterns such as null, numbers, chars, and booleans

Bindings and wildcards are sub-patterns of optional or variant payloads. Tuple patterns are not switch roots; use destructuring statements for tuples.