Syntax

The other pages in these docs walk through the language a topic at a time, in prose. This page is the opposite: an explicit, exhaustive catalog of the concrete syntax itself - every expression, statement, definition, and declaration the language has, each as its own entry with a railroad diagram, a plain-language description, and a runnable example. It's meant for looking something up, not reading start to finish - use the search box in the top bar to jump straight to a construct by name, or follow the links inside a description to a related one.

Argument Destructuring

#argument-destructuring
patterndeclaration

How a single function parameter (or a Let or Const target) can bind to a value: as a plain name, or by pulling pieces out directly. {x, y} pulls named fields off a struct, (a, b) pulls elements off a tuple by position, and [a, b] pulls elements off a list - so instead of binding the whole value and writing point.x yourself, the pieces you need arrive as their own local names. All three forms take the same elements: x, or x as y - which renames a struct field, or binds a tuple/list element under both names - and at most one ...rest anywhere among them, collecting whatever the other elements don't cover (the remaining fields of a struct, or the elements in between for a tuple or list). A bare ... skips them without binding.

Syntax treeAst.Pattern, Ast.NamePattern, Ast.PatternElement, Ast.StructPattern, Ast.TuplePattern, Ast.ListPattern

WORD { WORD WORD as WORD , WORD WORD as WORD , , ... WORD , WORD WORD as WORD , } ( WORD WORD as WORD , WORD WORD as WORD , , ... WORD , WORD WORD as WORD , ) [ WORD WORD as WORD , WORD WORD as WORD , , ... WORD , WORD WORD as WORD , ]

Arguments Declaration

#arguments-declaration
declaration

The full parameter list a function, method, or lambda declares - one or more comma-separated parameters, each an Argument Destructuring target with an optional : Type and an optional := default value, e.g. (x: Integer, y: Integer := 0).

Syntax treeAst.Parameter

Atom

#atom
expressionatom

The smallest, indivisible pieces an expression can be built from - a name, a number, a string, true/false, and a handful of other one-token forms below. Every larger expression (a call, a binary operation, a list, ...) is ultimately built by combining these.

Attributes

#attributes
filedefinition

Metadata tags written directly above a definition or statement, e.g. @test marks a function as a test to run, and @require(&env: String := "production") supplies a fallback for a Context Reference. Some take arguments in parentheses, most don't.

Syntax treeAst.Attribute

TokensAttribute

Binary Operation

#binary-operation
expressionoperator

Two values joined by an operator in the middle, like ordinary arithmetic - a + b. Also covers the compact a² form for squaring/powers, which is just shorthand for a ^ 2 written with a superscript instead of spelling out the operator.

Syntax treeAst.Binary

TokensSuperscript

Binding Statement

#binding-statement
statement

The two statements that give a name a value: Let introduces a brand new local variable, and Set changes the value an existing one already holds.

Block

#block
block

A sequence of statements wrapped in { }, run one after another - the body of a function, an If branch, a For loop, and so on. An empty block is just {}.

Written where a value is wanted - let area := { ... }, an argument, a branch of an if or match used as a value - a block is a value: its statements run in a scope of their own, so what they bind ends with the block, and its value is its last statement's when that's an expression - undefined otherwise. A return, !! or break in it leaves the way it would from any block of the function. A lambda's own { } body is a function's body, giving what its returns give; written in parentheses, λ(x) ({ ... }), it's a block used as a value.

Syntax treeAst.Block

TokensBracket, EmptyBrackets

Boolean Literal

#boolean-literal
expressionatomliteral

The two boolean values a program can write directly: true and false. Neither has its own lexer rule - both lex as an ordinary Word Reference, and the parser is what recognizes this exact spelling as the literal, tried before it would try to resolve either as a variable.

Syntax treeAst.Boolean

TokensWord

true false

Brace Call

#brace-call
expressioncall

Calling something with curly braces instead of parentheses, e.g. Point{1, 2} - used for constructing a struct instance by passing its field values in order, or by name. A bare name spelled exactly like one of the fields is shorthand for passing it by name: Point{x, y} means Point{x := x, y := y}, whatever order it's written in.

Syntax treeAst.BraceCall

Break

#break
statementcontrol-flow

Exits a For loop early. Since loops don't have separate labels, you name which loop to break out of by the variable it binds, e.g. break x stops the loop that introduced x - useful once loops are nested.

Syntax treeAst.Break

break WORD

Call

#call
expressioncall

Calling a function (or anything else callable) with a parenthesized, comma-separated list of arguments, e.g. area(5). An optional <TypeArgs> right before the parentheses supplies generic type arguments explicitly, e.g. make<Circle>(5). A ?, ! or !? right before the parentheses guards the callee the same way it guards member access: f?(x) skips the call when f is undefined, f!(x) asserts f isn't an error, and f!?(x) skips the call when f is either (see Operators).

Syntax treeAst.Call, Ast.Guard

TokensBracket

Call Arguments

#call-arguments
call

The values passed at a call site, comma-separated - each one is either just a value (matched by position) or name := value (matched by parameter name, so order doesn't matter for that one).

Syntax treeAst.Argument

TokensPunctuation

Comment

#comment
file

Text the compiler skips, allowed anywhere whitespace is. /// runs to the end of the line, and /* ... */ runs up to the first */, across lines if needed, without nesting. A line comment takes three slashes because // is already the floor-division operator. Both are matched by the lexer's space rule, \/\/\/[^\n]* and \/\*(?:[^*]|\*(?!\/))*\*\/, and join the whitespace token around them.

TokensSpace

/// CHAR /* CHAR */

Condition Expression

#condition-expression
expressioncontrol-flow

An expression used somewhere the result has to be a yes/no answer - If's own condition, one of For's while/until/if/skipping modifiers, or a Match Case's guard. It's written with the exact same grammar as any other Value Expression - there's no special "boolean expression" syntax, just a position that's expected to come out true or false.

Syntax treeAst.Expression

Const Definition

#const-definition
definition

Gives a name to a fixed value, e.g. const maxRetries := 3. Optionally name its type explicitly instead of letting it be inferred: const pi: Float := 3.14159. The name can be a pattern, the same as a Let's - const (low, high) := bounds() makes a constant of each name it binds, the value worked out once and destructured the way a Let would. Like any definition's, the name can be backtick-quoted - const `tax rate` := 23.

Syntax treeAst.Const

Context Definition

#context-definition
definitioninjection

Declares the type of a context value, e.g. context database: Database: every Context Reference &database is a Database, and every Inject of database has to give one. Its reach is a Define's: with local in front, the reads and injections in its own file; with nothing, those in its folder; with global, those anywhere in the project. A value after := is its default - what &database reads where nothing up the call stack injected one, made the first time it's needed. Only at the top of a file, and a name has one declaration where it's read; the builtin context values are declared by the language. A context value is one name at run time, however far each declaration reaches, so every declaration of a name in the project - in any folder, local, global or an @inject definition - has to give it the same type. The name can be backtick-quoted - context `request id`: String - but never holds a /: a context value isn't reached through a folder. A const or function written @inject, @injectLocally or @injectGlobally declares its name too, with its own type, over the same reach.

Syntax treeAst.ContextDeclaration

Context Reference

#context-reference
expressionatominjection

Reads a value that was injected somewhere up the call stack, by name - e.g. &env reads whatever the nearest Inject env (anywhere in the current call chain, not just lexically nearby) most recently set. It's how a value can reach deeply-nested code without being threaded through every function call in between as an explicit parameter. Its type is the builtin's, or what a Context Definition (or the function's own @require) declares - reading a name nothing declares is an error. Lexed as a single merged token: a bare & immediately followed by a name, with no space allowed in between. The name can be backtick-quoted - &`request id` - which is how a value an @inject definition with a quoted name provides is read back: @inject function `format price`(...) is &`format price`. It's never a path - a context name holds no /.

Syntax treeAst.Context

TokensContext

Continue

#continue
statementcontrol-flow

Skips the rest of the current iteration of a For loop and moves on to the next one. Like Break, it names which loop by the variable that loop binds.

Syntax treeAst.Continue

continue WORD

Control Flow Statement

#control-flow-statement
statementcontrol-flow

The statements that decide what runs next or how many times: If for a yes/no branch, For for looping over something, Match for picking between several shapes/patterns, and Break/Continue for controlling a loop from inside its own body.

Defer

#defer
statement

Schedules an expression to run once the current block finishes, no matter how it finishes - whether it runs off the end normally or exits early via Return, Break, or similar. Handy for cleanup code (like closing a file) that has to happen regardless of which way execution actually leaves.

Syntax treeAst.Defer

Define

#define
filedefinition

A top-level definition in a file - a function, struct, enum, union, interface, const, and so on - optionally prefixed with local (visible only in its own file) or global (also reachable from other folders by its path - see Path Reference). With neither, it's visible by its bare name in its own folder only. Any definition's name can be backtick-quoted to hold spaces - struct `Order line`, const `tax rate` := 23 - but never a /: a path is only how a definition is looked up (see Path Reference), never what it's called. A Context Definition is never named by a path: a global one types its context value's reads everywhere.

Syntax treeAst.Definition, Ast.Visibility

Enum Definition

#enum-definition
definition

Defines a type that's one of several named alternatives ("cases"), each optionally carrying its own data - a case can be empty, hold a fixed set of values like a tuple, or hold named fields like a small struct. Enums can also be built by combining others together with || instead of writing every case out by hand - naming a struct there adds one case carrying its fields. An interface or method every part has, the combined enum has too, each call going to the part its case came from. (A single | makes an untagged union instead.)

enum(U8), enum(String), ... is a keyed enum: each case has a key of that type, written after its name and values with := - or, left out, one more than the case before's for an integer type (0 for the first) and the case's name for String. It gets value.key(), Type.fromKey(key) (the case carrying nothing with that key, or undefined) and Type.from(struct) (the case whose fields are a struct's, by name and type).

Syntax treeAst.Enum, Ast.EnumCase

Error

#error
statement

Exits the current function the same way Return does, but marks the result as an error value instead of an ordinary one - the thing error-handling code specifically checks for. An optional with clause attaches a second value alongside the error itself, e.g. extra context about what went wrong.

Syntax treeAst.Error

Exit Statement

#exit-statement
statement

Every statement about how a function or block actually finishes: Return hands back a value, Yield hands a generator's next value to whoever is iterating it, Error hands back a failure, and Defer schedules cleanup for whenever that happens.

Field Definition

#field-definition
definition

A single member inside a Struct's body (or a struct-shaped Enum case): either a field, a per-instance slot that can have a default value - worked out again each time a value is built, so a Map.of() default gives each instance its own map, and a λ taking nothing as the default of a field that isn't a function is called each time - or a const, a single value shared by the type itself rather than by each instance.

Syntax treeAst.Field

File

#file
file

The complete contents a single source file can have, top to bottom: any number of implement blocks and definitions (bare, or prefixed with local/global), each optionally preceded by attributes.

Syntax treeAst.File

Operator Chain

#operator-chain
expressionoperator

A run of the same comparison-style operator chained together, read the way you'd naturally read it on paper - a < b < c checks both comparisons at once, rather than computing a < b as a boolean and then comparing that boolean to c the way many languages would.

Syntax treeAst.Chain

For

#for
statementcontrol-flow

Loops over an iterable value, binding each item (and optionally its index too) to a name for the loop's body. The item can be destructured with a pattern, as a Let would - for (key, value) in pairs - or kept under a name as well with as: for pair as (key, value) in pairs. The pattern's names are bound in the body and in the modifiers. Four optional modifiers - while, until, if, skipping - can filter which iterations actually run, or stop the loop early, without needing an if/break inside the body.

Syntax treeAst.For, Ast.LoopModifier

Function Declaration

#function-declaration
declaration

A function's signature on its own, with no body - its name, parameter list, and optional return type. Used both for a full Function Definition and, without a body, for a signature listed inside an Interface. The name is either a plain word or a backtick-quoted one, which can hold spaces and special characters - handy for a test's name, e.g. function `adds two numbers`(), called back as `adds two numbers`() (see Path Reference).

Syntax treeAst.Function, Ast.Declaration

Function Definition

#function-definition
definition

A complete, runnable function: its signature (see Function Declaration) followed immediately by the Block of statements that make up its body. A @js declaration - a JavaScript function Refingere calls, implemented by a JavaScript or TypeScript module - has none. See JavaScript and TypeScript.

Syntax treeAst.Function

Generic Instantiation

#generic-instantiation
expressioncall

Supplying type arguments to a generic name without immediately calling it, e.g. plain Array<Integer> used as a type rather than as part of a call - as opposed to Call's own optional type arguments, which are always followed by parentheses.

Syntax treeAst.GenericInstantiation

TokensBracket

If

#if
statementcontrol-flow

Runs one of two branches depending on whether a condition is true - each branch can be a single expression on the same line, or a full { } block for anything more involved. The else branch is optional; without one, a false condition just means nothing runs and execution continues normally. else if chains another If onto the else branch, on the same line - each with its own condition, the first true one running. Written where a value is wanted - set x := if c then 1 else -1 - an If is that value: an Inline If, each branch then one expression. A Match can be a value too.

Syntax treeAst.If

Implement a Macro

#implement-a-macro
definitionmacro

Defines a macro of your own - code the compiler runs while compiling, taking source in and giving source (or a value) back. Exactly one kind attribute says how it's used: @bodyMacro for #name {{{ ... }}}, @stringMacro for #name"...", @deriveMacro for @derive(Name), @attributeMacro for @name(...), and @programMacro for one that's never used by name - it runs over the whole program and adds code for what it selects. @phase picks when it runs. The first parameter is its input, and its type picks the form: a String, an Array<Token>, or a syntax tree. The result is read back in its place - source text, tokens, a tree, or any other value as a constant - and an error is a compile error where the macro was used. Top level only, and visible to the whole project. See Writing macros.

Syntax treeAst.Macro

Implement an Interface

#implement-an-interface
definition

Attaches a full set of an interface's functions to a concrete type in one place, e.g. giving Circle everything Shape requires. This is how a type actually satisfies an interface - the interface itself only declares signatures, never bodies.

Syntax treeAst.Implement

Implement Statement

#implement-statement
statementdefinition

An implement block used directly as a statement inside a block rather than at the top level of a file.

Syntax treeAst.Implement

Index Access

#index-access
expressioncall

Reading an element out of something by position or key, e.g. xs[0]. Also covers the compact subscript shorthand - xs₀ means exactly the same thing as xs[0], just written with a small digit instead of brackets. A ?, ! or !? right before the brackets guards the indexed value: xs?[0] skips the lookup when xs is undefined, xs![0] asserts xs isn't an error, and xs!?[0] skips it when xs is either (see Operators).

Syntax treeAst.Index, Ast.Guard

TokensBracket, Subscript

Inject

#inject
statementinjection

Sets a value under a name, visible to the rest of the current block and to anything it calls (however deeply), until the block ends. The value has to be of the name's declared type - see Context Definition. Read it back elsewhere with a Context Reference, e.g. &env. The name alone - inject retries - injects the value of that name in scope, the same as inject retries := retries; nothing else can follow it on the line. The name can be backtick-quoted, the same as in a Context Reference: inject `request id` := id.

Syntax treeAst.Inject

Injection Statement

#injection-statement
statementinjection

The two statements around dynamically-scoped values: Inject sets one for the rest of its block, and Reject removes this block's own copy of one.

Inline Definition

#inline-definition
statementdefinition

Any of the eight definition kinds (struct, function, interface, ...), written directly inside a block - unlike at the top level of a file, local/global can't be put in front.

Syntax treeAst.Definition

Inline If

#inline-if
expressioncontrol-flow

An If written where a value is wanted: if condition then a else b picks between two values rather than running one of two branches of code, so it can be used anywhere a value is expected - the right side of a Let, a function argument, and so on. Each branch is a value - one expression, or a block giving its last one's (see Block); else if chains another, and without an else the value is undefined when the condition doesn't hold. then and else can each start a line of their own, indented to continue the statement.

There's no condition ? a : b - a ? after a value is an error saying to write the if.

Syntax treeAst.InlineIf

Interface Definition

#interface-definition
definition

Declares a set of function signatures a type can promise to implement - no bodies here, those come later via a separate Implement block for each concrete type.

Syntax treeAst.Interface

Lambda

#lambda
expression

A small, unnamed function written inline, e.g. λ(x: Integer) x + 1 (or the equivalent lambda(x: Integer) x + 1). The parameter list is optional - a lambda with none at all just takes no arguments.

Syntax treeAst.Lambda

Let

#let
statement

Declares a brand-new local variable, e.g. let total := 0. The left-hand side can also destructure a struct or tuple directly (see Argument Destructuring) instead of binding one plain name.

Syntax treeAst.Let

List Literal

#list-literal
expressionliteral

A comma-separated sequence of values in brackets, e.g. [1, 2, 3], for a growable, ordered collection - as opposed to a Tuple Literal, which is a fixed-size grouping instead. A bare ... in place of an element is an elision - it stands for the elements left out between its neighbours, e.g. ["1", "2", ..., "15"]. It isn't ..rest, which spreads an iterable's own elements in place.

Syntax treeAst.List, Ast.Elision

TokensEmptyBrackets

[ Value Expression ... , , ]

Macro Invocation

#macro-invocation
expressionatom

Invokes a macro by name with no extra body attached, e.g. #line. Lexed as a single merged token: a bare # immediately followed by a Word Reference.

Syntax treeAst.MacroInvocation

TokensMacro

Macro With Body

#macro-with-body
expressionatom

Invokes a macro and hands it a raw block of text to work with, e.g. #SQL {{{ SELECT * FROM users }}} - everything between the triple braces is passed through untouched rather than being parsed as ordinary code. Also a single merged token: a Macro Invocation, exactly one space, then the body itself, matched by {{{(?:\[sS]|[^\])*}}}.

Syntax treeAst.MacroWithBody

TokensMacroBody, Placeholder

# Word Reference {{{ ESCAPE CHAR }}}

Match

#match
statementexpressioncontrol-flow

Tries a value against a list of cases in order and runs the body of the first one that matches - the general-purpose way to branch on more than the two options an If gives you, especially by an enum case or a value's own shape.

Where a value is wanted - after :=, as an argument, after return - a match is that value: the value of the first matching case, whose branch is then a value - an expression, or a block giving its last one's (see Block). When no case matches it's undefined, so its type is its cases' types joined, with Undefined added unless a case _ (or a name), or a case for each of an enum's cases, takes every value.

Syntax treeAst.Match

Match Case

#match-case
control-flowpattern

One branch inside a Match: a pattern to test the subject against, an optional if guard checked only once the pattern has already matched, and then the branch to run.

Syntax treeAst.MatchPattern, Ast.NamePattern, Ast.WildcardPattern, Ast.LiteralPattern, Ast.TypePattern, Ast.CasePattern, Ast.ErrorPattern, Ast.MatchCase

Method Declaration

#method-declaration
declaration

A method's signature, attached to the type it belongs to with for <Target>. Its first parameter, self, is the value it's called on - circle.diameter(). A function name for Target is the other kind: it has no self and is called on the type, Circle.unit().

Syntax treeAst.Method, Ast.Declaration

Method Definition

#method-definition
definition

The counterpart to Function Definition for methods - a Method Declaration followed by its body. There's no implicit receiver - the body reads fields through self.

Syntax treeAst.Method

Number Literal

#number-literal
expressionatomliteral

A numeric value written directly in code, e.g. 42 or 3.14159. Can also be written in hexadecimal, explicit decimal, octal, or binary using a 0x/0d/0o/0b prefix. Each base's digits (and an optional fractional part after .) can have underscores mixed in as separators. A plain decimal can end in an exponent - e or E, an optional sign, and digits - which makes it a float whether or not it has a fraction: 1e3 is 1000.0, 2.5e-4 is 0.00025. The full lexer rule is (0x[0-9a-fA-F_]+(.[0-9a-fA-F_]+)?)|(0d[0-9_]+(.[0-9_]+)?)|(0o[0-7_]+(.[0-7_]+)?)|(0b[0-1_]+(.[0-1_]+)?)|([0-9][0-9_]*(.[0-9_]+)?([eE][+-]?[0-9][0-9_]*)?).

Syntax treeAst.Number

TokensNumber

0x HEX_DIGITS . HEX_DIGITS 0d DIGITS . DIGITS 0o OCTAL_DIGITS . OCTAL_DIGITS 0b BINARY_DIGITS . BINARY_DIGITS DIGIT DIGITS . DIGITS e | E + - DIGITS

Operator Expression

#operator-expression
expressionoperator

Any expression built by applying an operator - an ordinary Binary or Prefix/Postfix Operation, or several operators chained together as an Operator Chain.

TokensSymbol

Path Reference

#path-reference
expressionatom

A name written between backticks. Starting with / it's a path from the project root (`/folder/name`); starting with ./ or ../, a path from the current file's folder (`../folder/name`). A path reaches only a global definition, and is how another folder's definitions are used. Anything else is a quoted name, looked up like a bare word - handy for names with spaces, like a test's (`adds two numbers`); a / anywhere else in it is an error. Only a reference is ever a path: the same backticks naming a definition - function `adds two numbers`(), struct `Order line` - or a context value (&`request id`) hold a plain name, with no / in it at all. Matched by `(?:\[sS]|[^`\])*` - like a string literal, but backtick-delimited, with the same backslash-escapes-the-next-character rule.

Syntax treeAst.Path

TokensPath

` ESCAPE CHAR `

Postfix Call

#postfix-call
expressioncall

Any of the four tight-binding forms that can follow directly after a value with no space in between: calling it (Call), indexing it (Index Access), constructing it (Brace Call), or giving it explicit type arguments (Generic Instantiation).

Postfix Operation

#postfix-operation
expressionoperator

An operator written after its one operand, e.g. x!!.

Syntax treeAst.Postfix

Prefix Operation

#prefix-operation
expressionoperator

An operator written before its one operand, e.g. -x.

Syntax treeAst.Prefix

Reject

#reject
statementinjection

Removes this block's own injected value for a name, if it set one. Rejecting a name that was never injected in this exact block is simply a no-op, not an error. The name can be backtick-quoted: reject `request id`.

Syntax treeAst.Reject

reject WORD Path Reference

Return

#return
statement

Exits the current function immediately, handing back the given value as the function's result.

Syntax treeAst.Return

Root

#root
expression

A square root (or, with a small subscript number right after it, a root of any other degree - e.g. a cube root), applied to whatever expression follows.

Syntax treeAst.Root

TokensSubscript

√ SUBSCRIPT Value Expression

Set

#set
statement

Reassigns something that already exists, e.g. set total := total + x. Unlike Let, the target can be a full expression like an index or field access, not just a plain name. Every infix or chaining operator also has a compound form: set total += x is set total := total + x, set ok and= x is set ok := ok and x, and set ok <= x is set ok := ok < x. The target stops before any binary operator, so that last one isn't a comparison. == and != stay the equalities - their compounds are === and !==.

Syntax treeAst.Set

set Set Expression := INFIX = CHAINING = Value Expression

Statement

#statement
statement

Everything that's legal on its own line inside a Block: declaring or reassigning a local, working with injected values, branching or looping, exiting a function, defining something inline, or just a bare expression run for its side effect.

Syntax treeAst.Statement

String Literal

#string-literal
expressionatomliteral

Text written directly in code, in single, double, or triple-quoted form - the triple-quoted forms can span multiple lines. Each quote style is its own lexer rule, e.g. the plain single-quoted form is '(?:\[sS]|[^'\])*' - a backslash escapes whatever character comes right after it (so an escaped quote can't end the string early), and anything else just has to not be the closing quote or a bare backslash.

Syntax treeAst.String

TokensString

''' ESCAPE CHAR ''' """ ESCAPE CHAR """ ' ESCAPE CHAR ' " ESCAPE CHAR "

String Macro

#string-macro
expressionatommacro

A macro applied to a string: its name written directly against a String Literal, with no space - #format"Hello, #{ name }!". Like a Macro With Body, it's one merged token, and the string is the macro's input rather than a plain value. Any quote style works, including the triple-quoted, multi-line ones. Inside the string, #{ expression } is a placeholder for a Refingere value, and \#{ writes a literal #{; every other escape works as in any string. The string still ends at its first unescaped closing quote, so a placeholder that needs quotes of its own goes in a string of the other style. Every string macro is listed on Macros.

Syntax treeAst.Piece, Ast.StringMacro

TokensStringMacro, Placeholder

Struct Definition

#struct-definition
definition

Defines a type made of named fields and constants, e.g. a Circle with a radius field. Instead of writing every field by hand, a struct can also be defined as the combination of other structs' fields using &&, or built purely from them with :=. A combined struct also gets the implement blocks and methods of the structs it's combined from, with self and Self standing for itself, unless it has its own. Combined with Error - struct Problem { field start: U64 } && Error - it's an error type of its own, with Error's fields and methods. (A single & makes a tuple of the types instead - see Type Expression.)

Syntax treeAst.Struct

Symbol Literal

#symbol-literal
expressionatom

An operator referenced as a plain value rather than being applied to anything, e.g. (+) - useful for passing an operator around like any other function. Written with its own parentheses, unlike Context or Macro, which merge their prefix character directly onto the name. The parentheses are ordinary tokens; what's inside them is one Symbol token, e.g. (<=) - or a lone < or >, which lex as brackets. A word operator works the same way, e.g. (and), (not) or (shl), the same operator as its symbol spelling where it has one - (and) is (∧). Every one but await, which pauses the function it's written in rather than being applied to anything.

Syntax treeAst.Symbol

TokensSymbol

( SYMBOL WORD )

Tuple Literal

#tuple-literal
expressionliteral

A fixed-size, ordered grouping of values, e.g. (1, 2) - as opposed to a List Literal, which can grow or shrink. () is the empty tuple, and a single-element tuple needs a trailing comma ((x,)) to tell it apart from an ordinary parenthesized expression.

Syntax treeAst.Tuple

TokensEmptyBrackets

Type Definition

#type-definition
definition

Gives an existing type (or combination of types) a new name, e.g. type Meters := Float - the type equivalent of Const Definition.

Syntax treeAst.TypeAlias

Type Expression

#type-expression
expression

An expression written where a type is expected instead of a value - e.g. after the : in a parameter or field. It's parsed with the exact same grammar as an ordinary Value Expression, just with a couple of ambiguous cases (like <) resolved in favor of "this is a type" instead of "this is a comparison". Two operators build new types out of existing ones: A | B is an untagged union (a value of either A or B - see Union Definition for giving one a name), and A & B is a tuple of both, with tuples on either side flattened in, so (Integer, U8) & String is (Integer, U8, String).

Syntax treeAst.Expression

Union Definition

#union-definition
definition

Defines an untagged union: a value of any one of its member types, with nothing recorded about which one it is - unlike an Enum Definition's cases, members have no names of their own, and a value carries no tag saying which member it is - so a union can't be told apart by match cases, and using it correctly is up to the code that holds it. When the member matters, use an enum. Members can be listed as cases, or written with | the same way the A | B type expression builds an anonymous union; other unions after a closing | have their members merged in.

Syntax treeAst.Union

Value Expression

#value-expression
expression

Anything that evaluates to a value - the umbrella every operator, literal, call, and reference on this page falls under. Whenever another entry's grammar needs "some expression" without caring which kind, this is what it means.

Syntax treeAst.Expression

Word Reference

#word-reference
expressionatom

A bare name, referring to whatever local variable, function, or other definition that name was already bound to. Matched by the lexer's own word rule: a leading underscore or Unicode "identifier start" character, followed by zero or more Unicode "identifier continue" characters - [_p{ID_Start}][p{ID_Continue}]*, minus a handful of superscript/subscript letters reserved for compact indexing and powers.

Syntax treeAst.Word

TokensWord

_ ID_START ID_CONTINUE

Yield

#yield
statement

Makes the function a generator: calling it returns an Iterator without running the body, and each value asked of that iterator runs the body up to its next yield, hands the value over, and pauses there. The sequence ends when the body does - at its end, or at a Return. Defers marked @onYield run at every pause.

Syntax treeAst.Yield