Skip to content

Type grammar

Types may be named directly or qualified through a namespace:

String
Geometry.Point

Generic arguments use angle brackets in type syntax:

Array<String>
Table<String, Int>

Generic call arguments use doubled angle brackets so they remain distinct from comparison operators:

Array.create<<Int>>(4, 0)
identity<<String>>("Pop")

Functions, records, and tagged unions may declare type parameters. In rc.3, calls must supply every type argument explicitly; record literals obtain their concrete generic type from an annotation or other expected context.

Append ? when a value may also be nil:

String?

The general union spelling joins alternatives with |:

String | Int | nil

This type union is distinct from a declared tagged union: a tagged union gives alternatives named cases and optional payloads.

Array types have equivalent short and named forms:

{String}
Array<String>

Typed tables likewise have two forms:

{[String]: Int}
Table<String, Int>

A tuple lists positional element types:

(String, Int, Boolean)

A function type lists named parameters and an optional result:

function(value: Int): String
function(message: String)

A parenthesized function result declares an exact fixed result pack:

function(value: Int): (Int, String)

A namespace alias gives an existing type another source name:

public type Scores = {[String]: Int}

The initial alias form is non-generic. It erases to its target before HIR and adds no new runtime identity.

Parentheses group compound types when necessary. Type spelling does not cause implicit conversions: aliases aside, values must satisfy the exact expected type or an explicitly permitted union/interface relationship.