Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Algebraic enumerations

Algebraic enumerations, as opposed to simple enumerations, contain type X() definitions instead of just const X definitions; they desugar to an one-level hierarchy of classes, with the enum being an abstract class, and with each variant being a class with a meta::invoke method (so you can specify either the defined signature, or an object literal).

Example

enum Exp {
    /**
     * @param left Left-hand side.
     * @param right Right-hand side.
     */
    type Plus(left : Exp, right : Exp)
    type Number(value : decimal)
    type Empty()
}

var exp : Exp

exp = Empty()
exp = Plus({ left: x, right: y })
exp = Plus(x, y)

switch type (exp) {
    case (Number(value)) {
    }
    case (Plus(x, y)) {
    }
    case (Empty()) {
    }
}

Type inference

var e:E = A()
var e:E = Subcategory.A()

v is A
v as Subcategory.A

Namespaces

The variants of an algebraic enum may be under namespaces for extra conciseness, by using dots in their name:

enum I {
    type Loc.Get(index : uint)
}

With type inference, one would basically have:

var i : I = Loc.Get(idx)

Shared properties

When an algebraic enum defines an instance variable, the constructors of each variant expect that variable inside a plain object if the variable isn’t optional.

enum Fragment {
    public const location:Location;

    type Simple();
    type Combined(left:Fragment, right:Fragment);
}

Fragment.Simple({ location: loc })

Sub-blocks

Each variant may have its own class block.

enum E {
    type A() {
        override public function get x() : double (10)
    }
    type B() {
        override public function get x() : double (24)
    }

    public abstract function get x() : double
}

Variant parameter list

Variant parameter lists may have follow entirely method signatures, having required parameters, default parameters and a rest parameter.

type A(...rest : [decimal])