Expressions and Operators
Arithmetic
Section titled “Arithmetic”Operators +, -, *, /, % work on int and float. Integer division truncates. Mixed int/float operations promote to float.
10 + 3 # 1310 / 3 # 3 (int division truncates)10.0 / 3 # 3.333... (mixed promotes to float)10 % 3 # 1 (modulo)String Concatenation
Section titled “String Concatenation”The ~ operator (D-style) concatenates strings:
let full = "hello" ~ " " ~ "world"let path = HOME ~ "/docs"String Interpolation
Section titled “String Interpolation”Double-quoted strings support interpolation. In expression context (assignments, conditions, lambdas), variables are accessed by bare name without $. The $ prefix is required only inside double-quoted strings.
| Syntax | Meaning |
|---|---|
$name | Variable interpolation |
$name[expr] | Subscript access (list or object) |
${expr} | Expression evaluation |
let name = "world"echo "hello $name" # hello worldecho "count: ${1 + 2}" # count: 3echo "${name}_suffix" # world_suffix
let parts = "a.b.c".split(".")echo "$parts[0]" # aecho "$parts[0].$parts[2]" # a.cSingle-quoted strings are literal — no interpolation occurs.
Comparison
Section titled “Comparison”== and != work on all types. <, >, <=, >= work only on numbers (int, float) and semver values. Using ordering operators on other types produces a type error.
Logical Operators
Section titled “Logical Operators”&&, ||, ! — standard boolean operators with short-circuit evaluation.
Match Expressions
Section titled “Match Expressions”match is an expression that produces a value. It can be assigned to variables or used in return statements:
let category = match ext { "jpg" | "png" | "gif" => "images" "mp4" | "mkv" => "videos" _ => "other"}Each arm is pattern => expression. The | operator combines multiple patterns. The wildcard _ matches anything. Every arm must produce a value.
Use return match in functions:
fn classify(ext) { return match ext { "jpg" | "png" => "image" _ => "unknown" }}Lambdas
Section titled “Lambdas”Arrow syntax for anonymous functions:
- Explicit single-param:
x => x + 1 - Multi-param:
(acc, x) => acc + x - Implicit lambda: When a method like
maporfilterreceives a non-lambda expression, it is wrapped asa => <expr>. The implicit parameter is alwaysa:
[1, 2, 3].map(a + 10) # [11, 12, 13][1, 2, 3, 4].filter(a > 2) # [3, 4]`ls`.map("-> ${a}") # implicit lambda with string interpolationThe implicit a always shadows any outer variable named a within the lambda body.
Element-wise String Methods on Lists
Section titled “Element-wise String Methods on Lists”String methods can be called directly on lists. The method is applied to each element and returns a list of results:
let lines = [" hello ", " world "]lines.trim() # ["hello", "world"]lines.trim().toUpper() # ["HELLO", "WORLD"]["a-b", "c-d"].replace("-", "_") # ["a_b", "c_d"]Supported: trim, toUpper, toLower, toNumber, replace, split, startsWith, endsWith.
Expression Statements
Section titled “Expression Statements”A parenthesized expression used as a statement evaluates the expression and outputs its value to stdout:
let x = 42(x) # outputs: 42(x * 2) # outputs: 84([1, 2, 3]) # outputs: [1, 2, 3]This is a shorthand for .writeln(stdout). The parentheses are required to distinguish an expression statement from a command invocation. Without them, a bare name in statement position resolves in the command namespace.