Definitions declare new types that can be used throughout a program. Types can have properties, methods, and nested definitions.
A routine is introduced by one of three keywords, and that keyword — not the spelling of the name — decides how the routine behaves:
function declares a pure function: its inputs are borrowed and immutable, and it returns a result without side effects. A function is applied prefix, by writing its name before a parenthesized argument list.
procedure declares a routine that may mutate its inputs and have side effects (builders, I/O).
operator declares an operator: a pure routine applied infix between its two operands (or prefix, for a unary operator).
The three identifier forms from the lexical chapter — alphanumeric, operator-character, and single-quoted string identifiers — are interchangeable as names here. A function may be named with operator characters, and an operator may be named with letters or a quoted string; what makes one a function and the other an operator is the declaration keyword, never the first character of the name.
function 'add seven'(n: int) returns int ; string-named function
n + 7
function ++(n: int) returns int ; operator-char-named function
n + 1
let a 'add seven'(35) ; applied prefix -> 42
let b ++(41) ; applied prefix -> 42
Operators may be declared at the top level, not only as members of a type. Like functions, they accept any of the three name forms:
operator <+>(left: int, right: int) returns int ; operator-char name
left + right
operator 'divided by'(left: int, right: int) returns int ; quoted name
left / right
let c 40 <+> 2 ; infix -> 42
let d 84 'divided by' 2 ; infix -> 42
Built-in arithmetic, comparison, and logical operators carry their usual precedences. A custom operator with a text or single-quoted name binds most weakly of all — at the same level as || — so the built-in arithmetic in an expression combines before it. For example, given the 'minus' operator above, 20 'minus' 3 + 5 parses as 20 'minus' (3 + 5) and yields 12.
Definitions declare new types that can be used throughout a program.
The define keyword creates a new structure type with named properties.
| Input | Result |
|---|---|
define Point(x: int, y: int) Point(3, 4) | {"_type":"Point","x":3,"y":4} |
define Point(x: int, y: int) Point(3, 4).x | 3 |
define Point(x: int, y: int) let p Point(3, 4) p.x + p.y | 7 |
define Point(x: int, y: int) define Rectangle(origin: Point, width: int, height: int) Rectangle(Point(0, 0), 10, 5).width | 10 |
Unions define types with multiple variants. Each variant can optionally carry a value.
| Input | Result |
|---|---|
define Option union(Some: int, None) Some(5) | {"_type":"Option","_variant":"Some","value":5} |
define Option union(Some: int, None) None | {"_type":"Option","_variant":"None"} |
define Result union(Ok: int, Err: String) Ok(42) | {"_type":"Result","_variant":"Ok","value":42} |
define Result union(Ok: int, Err: String)
Err("error") | {"_type":"Result","_variant":"Err","value":"error"} |
define Option union(Some: int, None) Option.Some(5).value | 5 |
A routine's role is set by its declaration keyword, not by how its name is spelled. A function may be named with ordinary letters, with a single-quoted string identifier (which may contain spaces), or with operator characters; in every case it is an ordinary function, applied by writing its name before a parenthesized argument.
The operator keyword declares an operator, applied infix between its two operands. Like functions, operators may be named with operator characters or with a text or single-quoted name. Operators may be declared at the top level, not only inside a type. A text-named operator binds more weakly than the built-in arithmetic operators, so the arithmetic combines first.
| Input | Result |
|---|---|
operator <+>(left: int, right: int) returns int
left + right
40 <+> 2 | 42 |
operator 'plus'(left: int, right: int) returns int
left + right
40 'plus' 2 | 42 |
operator 'divided by'(left: int, right: int) returns int
left / right
84 'divided by' 2 | 42 |
operator 'minus'(left: int, right: int) returns int
left - right
20 'minus' 3 + 5 | 12 |