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

Language constructs

Identifiers

Variables and type variables

In regular expression:[a-z_]([-]*[a-zA-Z0-9_]+)*['?]*

  • seq, x', some?, foo-bar
  • fooBar, a0, take_while

Constructor, type constructor, and trait names

In regular expression:[A-Z][a-zA-Z0-9_]*

  • List, Nil, Eq, Iter

Module names

In regular expression:[a-z_]([-]*[a-zA-Z0-9_]+)*

  • core, cmp, iter

Module path (qualified module names)

A sequence of module names separated by ::

  • ::core::cmp, ::core::list Absolute path
  • cmp, list, foo::bar Relative path

Qualified names

A module path followed by a variable, constructor, type constructor, or trait name

  • ::core::iter::seq, ::core::iter::Seq, ::core::iter::Iter
  • iter::seq, iter::Seq, iter::Iter

Literals

  • () Unit value literal
  • true, false Boolean value literals
  • 0,100, -1 Integer value literals
  • 0u8, 100u8, 0xFFu8 8-bit unsigned integer literals
  • 0u16, 100u16, 0xFFFFu16 16-bit unsigned integer literals
  • 0u32, 100u32, 0xFFFFFFFFu32 32-bit unsigned integer literals
  • 0u64, 100u64, 0xFFFFFFFFFFFFFFFFu64 64-bit unsigned integer literals
  • 'A', '\n', '🎉' Unicode Scalar Value literals
  • "abc", "🎉🤣👍🍺" Unicode UTF-8 string literals

Primitive types

  • () Unit type
  • Bool Boolean type
  • Int Integer type
  • u8 8-bit unsigned integer type
  • u16 16-bit unsigned integer type
  • u32 32-bit unsigned integer type
  • u64 32-bit unsigned integer type
  • ScalarValue Unicode Scalar Value type
  • ScalarString Unicode UTF-8 string type (synonym of Str ScalarValue)
  • @[t] or @[] t Array type
  • (t,), (t1, t2) Tuple type
  • @{x:t1, y:t2} Record type
  • t1 -> t2 Function type
  • T t, t1 t2 Type-level function application

Operators

Infix (binary) operators

  • ==, != Equality / Non-equality operators
  • <=, <, >, >= Comparison operators
  • &&, || Logical operators
  • +, -, *, /, % Arithmetic operators
  • |>, <| Pipeline operators
  • >>, << Function composition operators

Prefix operators

  • nagete, - Arithmetic negation
  • not, ! Boolean not

User defined infix operators

In regular expression:[*+\-/!$%&=^?<>]+

  • ?>, ===, <+>

Operators as functions

  • (==) 1 1
  • (+) 1 2

Functions and constructors as operators

  • 1 `Cons` Nil
  • x `@{Eq Int}.(==)` y

Declarations

At the top level of a module:

  • mod Define sub-module
  • use Import identifiers
  • type Define Algebraic Data Type (ADT)
  • trait Define Multi-Parameter Type Class (MPTC)
  • impl Define MPTC instance implementation
  • *let Define generic/overloaded function template
  • let Define a variable or function
  • let rec Define a recursive function

Statements

Within a local scope:

  • let Variable / function binding
  • let rec Recursive function binding

Note

In the case of let rec p = e;,

  • p must be a variable pattern.

In the case of let p = e;,

  • At the top level of a module, p must be a variable pattern.
  • Within a local scope, any pattern can be used for p.

Expressions

Value expressions

(evaluate to themselves; safe to generalize)

  • (), true, 0 Literals
  • λp.e/\p.e Lambda abstraction (function)
  • @[], @[e1], @[e1, e2] Array value
  • (e1,), (e1, e2) Tuple value
  • @{x = e1, y = e2} Record value
  • @{T t1 t2} Trait record value
  • |(e op)/|(e op _) Infix-operator partial application (bind the 1st argument)
  • |(op e)/|(_ op e) Infix-operator partial application (bind the 2nd argument)

Infix-operator partial applications (a.k.a. section syntax) are desugared into lambda abstraction.

Note

Old section syntax #(e op)/#(e op _) and #(op e)/#(_ op e) are deprecated.
Use new syntax |(e op)/|(e op _) and |(op e)/|(_ op e) instead.

Important

Old record value syntax @{x: e1, y: e2} are deprecated and no longer supported.
Use new syntax @{x = e1, y = e2} instead.

Non-value expressions

(require evaluation; not eligible for generalization)

  • x Evaluate variable
  • e1 e2 Function application
  • e1[e2] Array index access
  • e.0 Tuple index access
  • e.x Record field access
  • { stmt1; stmt2; expr } Block expression (evaluates to the last expression; introduces a new scope)
  • if (e1) e2 else e3 If then else
  • match (e) { p1 => e1, .. } Pattern matching

Minumul Type Annotaions

  • e: t Optional type annotations for expressions
    This adds a type equality constraint between the inferred type of e and the annotated type t.
    This helps type inference and the constraint solver resolve the last mile of ambiguity.

  • Type annotations as signatures are required only in trait declarations.
    Other bindings (such as let and lambda parameters) do not accept type signatures.

Note

The expr: t syntax is only permitted for atomic expressions.
If you need to type-annotate a complex expression,
enclose the expression in parentheses and follow it with the type annotation.

Examples:

let add = \a.\b. (a + b): Int;

add 2 + 3
// => 5: Int
(cast 10): u8
// => 10: u8
(cast 10): (Result e u8)
// => Ok 10: Result RuntimeError u8

Patterns

  • _ Wildcard pattern
  • (), true, 0 Literal pattern
  • 'A', '🎉' Unicode Scalar Value literal pattern
  • x, foo Variable pattern
  • Nil, Cons p ps Constructor pattern
  • @[], @[p1, p2], @[p, ps..], @[p, ..], @[ps..], @[..] Array pattern
  • (p1,), (p1, p2) Tuple pattern
  • @{x = p1, y = p2}, @{x, y} Record pattern

Important

Old record pattern syntax @{x: p1, y: p2} are deprecated and no longer supported.
Use new syntax @{x = p1, y = p2} instead.