Values & Types
Resonon is dynamically typed: a value has a type, a variable does not. Operators on values are in Operators; collections are in Collections & Iterators. Why containers share and primitives copy is in Values & Sharing.
Comments
Section titled “Comments”| Syntax | Kind |
|---|---|
// … | Line comment |
/* … */ | Block comment |
/// … | Doc comment for the definition below it |
//! … | Doc comment for the file; only at the top of the file |
//// … | Line comment (four or more slashes) |
//! File documentation — what this file is.
// Line comment/* Block comment */
/// Doubles a number.fn double(x) { return x * 2;}print(double(4));Doc comments are shown by show(), editor hover, and resonon pkg inspect.
///documents the nextfn,let,class, class method ordspdefinition. Blank lines and ordinary comments in between change nothing; consecutive///blocks join into one.- A
///with nothing below it to document — above ause, an expression, a class field, inside a block, or at the end of the file — is an error. - A
//!anywhere but the top of the file is an error. - A doc comment with an
Experimental:line marks what it documents as experimental, with the text after it saying what may change:show(), editor hover and completion say so. In a file’s//!, it marks everything the file defines.
Literals
Section titled “Literals”| Type | Literals |
|---|---|
| Number | 42, 3.14, .5, 5., 1e-3, 2.5e2, 0xFF, 0b1010, 0xFF_FF, 0b1010_0011 |
| String | "text", f"text {expr}" |
| Boolean | true, false |
| NUL | NUL |
| Note | C4, F#3, Bb2, C-1 … G9 |
| Rest | _ |
| Pattern | [C4 E4 G4], <C4 E4>, {C4 D4 E4} — see Mini-Notation Grammar |
| Array | #[1, 2, 3] |
| Dict | #{"key": 1, 36: "kick"} |
| Tuple | (1, "a") |
| Function | fn(x) { return x * 2; } |
Numbers
Section titled “Numbers”There is one Number type: 5 and 5.0 are the same value. Hex and binary literals accept _
separators.
Strings
Section titled “Strings”Strings are double-quoted and immutable; every string method returns a new string. The methods are
in the String reference.
| Escape | Character |
|---|---|
\" | Double quote |
\\ | Backslash |
\n | Newline |
\r | Carriage return |
\t | Tab |
An f prefix makes a format string: any expression inside {…} is evaluated and formatted as
print() would show it. {{ and }} are literal braces. String literals may appear inside the
braces.
let vel = 100;let notes = #["C4", "E4", "G4"];print(f"Dynamics: {if vel > 80 { "loud" } else { "soft" }}");print(f"Root: {notes[0]}, count: {notes.length()}");print(f"Literal braces: {{like this}}");assert "Tempo: " + 120 == "Tempo: 120"; // + also concatenatesA string is not directly iterable: for ch in "abc" is an error; iterate "abc".iter(), which
yields one-character strings.
Booleans and truthiness
Section titled “Booleans and truthiness”if conditions, match guards, assert, &&, || and ! require an actual
Boolean; any other value is a type error. Where a callback’s result is tested — .filter(),
.find(), .any(), .all() — only false and NUL are falsy, and everything else, including
0, "" and #[], is truthy.
print(#[0, "", false, NUL, #[]].filter(fn(x) { return x; })); // [0, "", []]NUL is the absence of a value.
NUL == NUListrue;NULequals nothing else (not0, notfalse).NULcannot be ordered (NUL < 1) or used in arithmetic, except that"text" + NULgives"textNUL".- A function without a
returnreturnsNUL. Iterators returnNULonce exhausted, anddict.get(key)returnsNULfor a missing key. - Reading a variable that was never defined is an error, not
NUL. NULcan be stored in arrays, dicts and tuples.
A note literal is a letter, an optional accidental (# or b), and an octave from -1 to 9.
Notes map to MIDI 0–127 (C-1 to G9, C4 = 60); a note outside that range is a parse error.
Notes compare with Numbers by MIDI value. A name like Cs2 is not a note; it parses as an
identifier.
assert C4 == 60;assert A4 >= 69;assert Bb3 == A#3;print(C-1); // the lowest MIDI noteprint(G9); // the highestType annotations
Section titled “Type annotations”Annotations are advisory: the language server uses them for signatures, hover and completion, and
they are never checked at run time. A parameter annotated Number accepts any value.
| Where | Syntax |
|---|---|
| Parameter | fn f(x: Number) |
| Return | fn f() -> Number |
| Union | Number | String |
| Function type | (Number) -> Number |
| Class field | let speed: Number; |
| Tuple destructuring | let (f, l): (Number, String) = (440, "A4"); |
| Variable | let x: Number = 1; — legal, but by convention left out |
fn apply(f: (Number) -> Number, x: Number | String) -> Number { return f(x);}print(apply(fn(n) { return n * 2; }, 5)); // 10type()
Section titled “type()”type(value) returns the type’s name as a String; for a class instance, the class name.
assert type(42) == "Number";assert type("hi") == "String";assert type(true) == "Boolean";assert type([C4 D4]) == "Pattern";assert type((1, 2)) == "Tuple";print(type(#[1]));