LEVIATHAN v962456e · 962456eee1

Types

Type expressions

How a type is written: names, qualified names, generic instantiations, unions, optionals and function types.

since 0.1.0-alpha.1linuxwindowswasm

Description

A type expression appears wherever a type is expected: a variable declaration, a field, a parameter, a return type, a type argument. These forms exist:

form example meaning
name int, string, MyClass a built-in or declared type
qualified name Shapes::Box a type declared in a namespace
generic instantiation Array<int>, Array<Array<int>> a generic type with its type arguments
union int | string a value that is one of the listed types
optional int? shorthand for int | None
function type (int, int) => int a function taking two ints and returning int

var and let stand where a type would. They are not types: they ask the compiler to use the type of the initializer. var is a freely reassignable variable. let is a single-assignment binding, so assigning to it again is a compile error.

Type expressions in declarations

namespace Shapes {
    class Box {
        int side = 2;
    }
}

class Couple<A, B> {
    A first;
    B second;
}

int apply((int, int) => int op, int a, int b) => op(a, b);

Shapes::Box b = Shapes::Box();
Array<Array<int>> grid = [[1], [2, 3]];
Couple<string, int> p = Couple("k", 7);
console.writeln(b.side);
console.writeln(grid.length());
console.writeln(p.second);
console.writeln(apply((x, y) => x * y, 6, 7));
2
2
7
42

Rules

  • A type name is an identifier, optionally qualified with ::. A generic type adds its arguments in angle brackets: Name<T1, T2>. Instantiations nest: Array<Pair<K, V>>.
  • A union T1 | T2 is a closed set of alternatives. T? is T | None. See lang.unions-and-optionals.
  • A function type is written (T1, T2) => R, with the parameter types in parentheses and the result type after =>.
  • var and let are inference markers, never part of a type. The variable's type is the initializer's type. They are written at a declaration only, and only inside a function or block.
  • let x = e; is a single-assignment binding: assigning to it later is the compile error "cannot assign to const".

Examples

Unions, optionals and inference markers inside a function:

Unions, optionals, var and let

void demo() {
    int | string either = 5;
    int? maybe = None;
    var v = 10;
    let w = 20;
    v = v + 1;
    console.writeln(either is int);
    console.writeln(maybe == None);
    console.writeln(v + w);
}
demo();
true
true
31

A function-typed variable:

A function type

void demo() {
    (int) => int inc = (x) => x + 1;
    console.writeln(inc(4));
}
demo();
5

Notes

A var or let declaration, and a variable whose type is a function type written with a leading parenthesis, cannot start a top-level statement. Write them inside a function or a block statement such as the body of an if.

See also

  • Array — An ordered sequence of values of one type, Array<T>, with value semantics.