1. Basic Syntax
1.1 Comments
-- Single line comment
/* Block comment
spans multiple lines
/* and can be nested */ */
1.2 Literals
-- Integer literals
42
0
123_456_789
-- Hexadecimal integer literals
0xFF
0x100
0xDeadBeef
-- Float literals (require a digit on both sides of the decimal point)
3.14
0.5
2.0
-- Fraction literals (integer/integer with no spaces around /)
1/2
3/4
-7/8
-- Fractions are automatically reduced
6/4 -- 3/2
-- A fraction literal cannot be immediately followed by /
-- to prevent ambiguity. Use spaces for division:
-- 1/2/3 -- ERROR: ambiguous
-- 1/2 / 3 -- OK: fraction 1/2 divided by 3
-- Imaginary literals
4i
1.5i
-- String literals
"hello world"
-- Symbol literals (interned strings, compared by pointer)
'ok
'error
-- Boolean literals
true
false
1.3 Multi-line and Raw Strings
An ordinary "..." string is single-line and processes backslash escapes (\n, \t, \", \\, \uhhhh, \Uhhhhhhhh). A literal newline inside it is an error.
For text that spans several lines — or that is easier to write without escaping — there are two raw string forms. Both span multiple lines and perform no escape processing: every character between the delimiters, including newlines and backslashes, is taken verbatim.
-- Triple-quoted raw string: delimited by """ ... """
let haiku = """
an old silent pond
a frog jumps into the pond—
splash! silence again
""";
-- Guillemet raw string: delimited by « ... »
let note = «She said "hello" and left.»; -- quotes need no escaping
-- No escapes are interpreted: this string contains a literal
-- backslash-n, not a newline.
let raw = """C:\new\table""";
The content is captured exactly as written: there is no automatic stripping of the leading newline or of indentation. In the haiku above the string therefore begins with a newline (right after the opening """) and the lines are flush-left because they are written flush-left in the source.
Because the forms are raw, a triple-quoted string cannot contain the sequence """, and a guillemet string cannot contain » (nor do guillemets nest). Pick whichever delimiter does not occur in your text: use « » when the text contains double quotes or """, and use """ when it contains guillemets.
Raw strings are handy for embedding other source verbatim — for example a program to load into a silo, a synthdef body, or a block of JSON or template text — without escaping its quotes:
let silo0 = """
import audio_engine.*;
async fn voice(self Actor<Msg>, init Msg) Void {
-- ...
}
voice spawn(Msg.int(0)) register('voice);
""";
attachVM(0);
await siloLoad(0, silo0);
1.4 Semicolons
-- Semicolons are required statement terminators
let x = 42;
let y = 10;
-- Exception: the last expression in a block is the implicit
-- return value and does NOT have a semicolon
fn square(x Int) Int {
x * x -- no semicolon: this is the return value
}
1.5 Printing Output
-- println prints its arguments separated by spaces, followed by a newline
println(42); -- 42
println("hello", "world"); -- hello world
println(1, 2.5, true); -- 1 2.5 true
println(); -- (empty line)
-- print is the same but without a trailing newline
print("x=");
println(42); -- x=42
-- Pipeline syntax works too
42 println; -- 42
"hello" println; -- hello
-- Auto-map with @ to print each element on its own line
[1, 2, 3] @ println;
-- 1
-- 2
-- 3
For large nested values there is also a width-aware pretty printer, prettyPrint / prettyString — see §26.