Expressions are the core computational units of Scaly. Every expression evaluates to a value. Unlike many languages, Scaly uses postfix operators and does not define operator precedence — evaluation order is always explicit.
Expressions are the core computational units of Scaly. Every expression evaluates to a value.
Integer literals are sequences of decimal digits, optionally preceded by a minus sign for negative numbers.
Hexadecimal literals start with 0x or 0X followed by hexadecimal digits (0-9, a-f, A-F).
Floating-point literals contain a decimal point separating the integer and fractional parts.
String literals are enclosed in double quotes. They may span multiple lines, with line breaks preserved in the resulting string.
Character literals represent a single character, enclosed in backticks.
Operations allow combining expressions.
An operation is a sequence of operands that evaluates to a single value. Each operand is an expression optionally followed by member access. An operation ends with a colon, a line break, or anything which is not an expression. Evaluation uses a context which is empty at the start of an operation. When the context is empty, operator-shaped identifiers act as prefix functions, taking the next operand as their argument.
When the context holds a value, operators chain left-to-right. Each operator takes the current value and the next operand, producing a new value. There is no operator precedence built into the language itself. Operator precedence is built into the implementation of the individual operators. The common arithmetic operators are built into the standard library.
Parentheses create a empty context. This allows prefix forms inside an otherwise operator chain, and explicit grouping when needed.
Identifiers can have name shape (alphanumeric) or operator shape (symbols). The shape is purely lexical and does not determine behavior. Whether an identifier acts as a prefix function or chain operator depends on its declaration and the register state.
Let bindings introduce local variables. The syntax is let followed by a name and a value expression (no equals sign). Multiple statements are separated by colons or newlines.
If expressions evaluate one of two branches based on a boolean condition. The syntax is if followed by the condition, a colon, the consequent, and optionally else with an alternative.
if true: 1 else 0 ; evaluates to 1 if false: 1 else 0 ; evaluates to 0 if 5 > 3: 10 else 20 ; evaluates to 10
If expressions can be nested:
if false: 1 else if true: 2 else 3 ; evaluates to 2
Match expressions compare a value against multiple cases. The syntax is match followed by the scrutinee, a colon, one or more case branches, and optionally else.
match 2: case 1: 10 case 2: 20 else 0 ; evaluates to 20 match 5: case 1: 10 else 0 ; evaluates to 0
Multiple cases can share the same branch:
match 2: case 1 case 2: "one or two" else "other"
Choose expressions pattern match on union types, binding the inner value to a variable.
Choose expressions match on the variant of a union value and bind the inner value.
Choose works with any union type, including Result.
The else branch is evaluated when no when clause matches.