Skip to content

Enums

An enum is a closed set of named choices. Use one where a value is one of a fixed list, such as a blend mode or a playing style, instead of a String the code must spell correctly.

/// How a part is played.
enum Style {
/// Short and detached.
staccato,
/// Connected.
legato,
accent, // a trailing comma is allowed
}
print(Style.legato); // Style.legato
  • An enum is written at the top level of a file, like a class.
  • Its name starts with an upper-case letter, as a type name does.
  • A variant is lower snake_case: ease_in, not EaseIn. The error names the snake_case spelling.
  • An enum has at least one variant, and names each variant once.
  • /// documents the enum and each variant. The editor shows the docs on hover and in completion, and show(Style) prints them with the variants.

An enum name is claimed like every other definition: see One definition per name.

Enum.variant reads a variant. A variant prints as it is written, and type() returns its enum’s name. The enum itself prints as <enum Style>, and type() returns enum Style.

enum Style { staccato, legato }
let s = Style.staccato;
assert type(s) == "Style";
assert type(Style) == "enum Style";
print(s); // Style.staccato
print(Style); // <enum Style>

A variant the enum does not declare is an error. It lists the variants and suggests the closest:

let s = Style.legatto;
// enum Style has no variant 'legatto'. Did you mean 'legato'? Variants: staccato, legato

The editor reports the misspelt variant before the code runs.

== and != compare two variants of one enum by name. A variant compared with a variant of another enum, or with a String or Number, is a type error. A variant compared with NUL is not equal to it.

enum Style { staccato, legato }
assert Style.legato == Style.legato;
assert Style.legato != Style.staccato;
assert Style.legato != NUL;
print(Style.legato == Style.staccato); // false
enum Mode { legato }
Style.legato == Mode.legato; // error: expected matching types
Style.legato == "legato"; // error: expected matching types

Variants have no order: <, >, <= and >= are type errors.

A dotted name in a match arm compares the subject with the variant. It never binds a name. See match.

enum Style { staccato, legato, accent }
fn velocity(style) {
match style {
Style.staccato => 70,
Style.accent => 120,
_ => 90,
}
}
assert velocity(Style.accent) == 120;
print(velocity(Style.legato)); // 90

There is no exhaustiveness check: add _ for the variants no arm names.

An enum name is a type in an annotation. Only a variant of that enum fits it: the editor flags a String or a variant of another enum, and running refuses one. A String that spells a variant gets the variant to write in the error, (write Style.legato).

enum Style { staccato, legato }
fn play_as(style: Style) -> Number {
return match style { Style.staccato => 0.25, _ => 1.0 };
}
print(play_as(Style.staccato)); // 0.25

Running an enum declaration again declares the same enum again. Variants read before the run stay equal to the variants read after it, even when the new declaration changes the variant order. An enum is told apart by its name and by where it is declared: the session, or a module file.

Run this first:

enum Style { staccato, legato }
let before = Style.legato;
print(before);

Then run this, with the variants in a new order:

enum Style { legato, staccato }
assert before == Style.legato; // still equal

A module exports an enum like a class. Read its variants through the module, or import the enum by name. private enum keeps it inside the module. See Modules.

lib/styles.non
enum Style { staccato, legato }
private enum Internal { a, b }
use "styles";
use "styles" { Style };
let a = styles.Style.legato;
assert a == Style.legato;

An enum declared in the session and an enum of the same name declared in a module are two enums: their variants do not compare.

  • Values on a variant — a variant is a name only. It carries no number and no data.
  • Methods — an enum has only its variants.
  • Calling an enum — Style() is a type error.
  • Iterating an enum — for s in Style is a type error.
  • A variant as a Dict key — Dict keys are Strings and Numbers.