Appendix B: Operators
This document lists ZuzuScript expression operators, ordered from highest precedence to lowest precedence.
Precedence summary table (highest to lowest)
Notes
- Higher rows bind tighter than lower rows.
- Most binary operators are left-associative.
**is right-associative.▷is left-associative;◁is right-associative. Their ASCII-safe aliases are|>and<|. The Unicode forms are canonical.«(left shift) and»(right shift) have the ASCII-safe aliases<<and>>. The Unicode forms are canonical. Inside a set literal, a bare>>or»always closes the literal rather than acting as a shift; parenthesize shift expressions used as set elements.a ∣ b("a divides b") is true whenb mod ais zero; the left operand is the divisor. Its ASCII-safe alias is thedivideskeyword, with the Unicode form canonical.a ∤ b("a does not divide b") returns the Numberb mod arather than a strict Boolean — non-zero, and therefore truthy, exactly whenadoes not divideb. It has no ASCII alias.⊤and⊥are boolean literals, not operators, so they do not appear in the precedence table.?:,? :, chain operators, and assignment operators are parsed after the main Pratt precedence table. Chain operators bind looser than ternary expressions and tighter than assignment.defaultis a left-associative binary operator at the type-aware equality tier.- Postfix forms (call/member/index/dict access/postfix
++/--) are parsed immediately after primaries and therefore bind tighter than all infix operators. - Argument spread is call syntax, not an infix operator. In
fn(...opts default fallback), the spread operand is the wholeopts default fallbackexpression. - At expression start,
->and→begin a leading-arrow lambda. In infix position,->remains the existing comparison-level operator.
| Level | Associativity | Operators |
|---|---|---|
| Postfix | left-to-right chaining | (...) (call), .name, .(expr)(...), [index], [start:length], {key}, postfix ++, postfix -- |
| Prefix | right-to-left nesting | unary +, unary -, !, ¬, unary ~, unary √, ⌊...⌋, ⌈...⌉, unary # (cardinality), unary \\ (reference), not, abs, sqrt, floor, ceil, round, int, uc, lc, length, typeof, prefix ++, prefix -- |
| 15 | right-to-left | ** |
| 14 | left-to-right | *, /, ×, ÷, mod |
| 13 | left-to-right | +, - |
| 12 | left-to-right | _ |
| 11 | left-to-right | union, ⋃, intersection, ⋂, \\, ∖ |
| 10 | left-to-right | «, » |
| 9 | left-to-right | & |
| 8 | left-to-right | ^ |
| 7 | left-to-right | | |
| 6 | left-to-right | =, ≠, <, >, <=, ≤, >=, ≥, <=>, ≶, ≷, ∣, divides, ∤, eq, ne, gt, ge, lt, le, cmp, eqi, nei, gti, gei, lti, lei, cmpi, in, ∈, ∉, subsetof, ⊂, supersetof, ⊃, equivalentof, ⊂⊃, instanceof, does, can, binary ~, @, @?, @@ |
| 5 | left-to-right | ==, ≡, !=, ≢, default |
| 4 | left-to-right | and, ⋀, and?, ⋀?, nand, ⊼, nand?, ⊼?, butnot, ⊭, butnot?, ⊭? |
| 3 | left-to-right | xor, ⊻, xor?, ⊻?, nor, ⊽, nor?, ⊽?, xnor, ↔, xnor?, ↔? |
| 2 | right-to-left | onlyif, ⊨, onlyif?, ⊨? |
| 1 | left-to-right | or, ⋁, or?, ⋁? |
| Ternary | right-to-left grouping in practice | ? :, ?: |
| Chain | by direction | ▷, ◁, |>, <| |
| Assignment | right-to-left grouping in practice | :=, ~=, +=, -=, *=, ×=, /=, ÷=, **=, _=, ?:= |
Detailed table
| Operator | Aliases | Kind | Precedence | Definition |
|---|---|---|---|---|
| Mathematical operators and numeric comparisons | ||||
+ |
Unary prefix | Numeric identity. | ||
- |
Unary prefix | Negative number. | ||
√ |
sqrt |
Unary prefix | Square root. | |
abs |
Unary prefix | Absolute value. | ||
floor |
⌊...⌋ |
Unary prefix | Round down to the nearest integer. | |
ceil |
⌈...⌉ |
Unary prefix | Round up to the nearest integer. | |
round |
Unary prefix | Round to the nearest integer. | ||
int |
Unary prefix | Convert to an integer value. | ||
** |
Binary infix | 15 | Exponentiation. | |
× |
* |
Binary infix | 14 | Multiplication. |
÷ |
/ |
Binary infix | 14 | Division. |
mod |
Binary infix | 14 | Remainder after division. | |
∣ |
divides |
Binary infix | 6 | Divides: true if the right operand is an exact multiple of the left. |
∤ |
Binary infix | 6 | Does not divide: the remainder of the right operand divided by the left, truthy when non-zero. | |
+ |
Binary infix | 13 | Addition. | |
- |
Binary infix | 13 | Subtraction. | |
= |
Binary infix | 6 | Numeric equality. | |
≠ |
Binary infix | 6 | Numeric inequality. | |
< |
Binary infix | 6 | Less than. | |
> |
Binary infix | 6 | Greater than. | |
≤ |
<= |
Binary infix | 6 | Less than or equal to. |
≥ |
>= |
Binary infix | 6 | Greater than or equal to. |
≶ |
<=>, ≷ |
Binary infix | 6 | Numeric three-way comparison. |
| String operators and string comparisons | ||||
uc |
Unary prefix | Uppercase string conversion. | ||
lc |
Unary prefix | Lowercase string conversion. | ||
length |
Unary prefix | String length. | ||
# |
Unary prefix | Cardinality. Calls a concrete count() method when available, otherwise falls back to length. |
||
_ |
Binary infix | 12 | String concatenation. | |
eq |
Binary infix | 6 | Case-sensitive string equality. | |
ne |
Binary infix | 6 | Case-sensitive string inequality. | |
gt |
Binary infix | 6 | Case-sensitive string greater-than comparison. | |
ge |
Binary infix | 6 | Case-sensitive string greater-than-or-equal comparison. | |
lt |
Binary infix | 6 | Case-sensitive string less-than comparison. | |
le |
Binary infix | 6 | Case-sensitive string less-than-or-equal comparison. | |
cmp |
Binary infix | 6 | Case-sensitive string three-way comparison. | |
eqi |
Binary infix | 6 | Case-insensitive string equality. | |
nei |
Binary infix | 6 | Case-insensitive string inequality. | |
gti |
Binary infix | 6 | Case-insensitive string greater-than comparison. | |
gei |
Binary infix | 6 | Case-insensitive string greater-than-or-equal comparison. | |
lti |
Binary infix | 6 | Case-insensitive string less-than comparison. | |
lei |
Binary infix | 6 | Case-insensitive string less-than-or-equal comparison. | |
cmpi |
Binary infix | 6 | Case-insensitive string three-way comparison. | |
~ |
Binary infix | 6 | Regexp match. | |
| Bitwise operators | ||||
~ |
Unary prefix | Bitwise NOT. | ||
« |
<< |
Binary infix | 10 | Bitwise left shift. |
» |
>> |
Binary infix | 10 | Bitwise right shift. |
& |
Binary infix | 9 | Bitwise AND. | |
^ |
Binary infix | 8 | Bitwise XOR. | |
| |
Binary infix | 7 | Bitwise OR. | |
| Logical operators | ||||
! |
Unary prefix | Logical negation. | ||
¬ |
not |
Unary prefix | Logical negation. | |
⋀ |
and |
Binary infix | 4 | Logical AND. |
⊼ |
nand |
Binary infix | 4 | Logical NAND. |
⊭ |
butnot |
Binary infix | 4 | Logical AND NOT. |
⊻ |
xor |
Binary infix | 3 | Logical XOR. |
⊽ |
nor |
Binary infix | 3 | Logical NOR. |
↔ |
xnor |
Binary infix | 3 | Logical XNOR. |
⊨ |
onlyif |
Binary infix | 2 | Logical implication. |
⋁ |
or |
Binary infix | 1 | Logical OR. |
| Value-preserving logical operators | ||||
⋀? |
and? |
Binary infix | 4 | Return the right operand if the left is truthy; otherwise return the left operand. |
⊼? |
nand? |
Binary infix | 4 | Return ⊥ when both operands are truthy, the right operand when only it is truthy, and ⊤ otherwise. |
⊭? |
butnot? |
Binary infix | 4 | Return the left operand when it is falsey or the right is falsey; otherwise return ⊥. |
⊻? |
xor? |
Binary infix | 3 | Return the truthy operand when exactly one operand is truthy; otherwise return ⊥. |
⊽? |
nor? |
Binary infix | 3 | Return ⊥ when both operands are truthy, the falsey operand when exactly one operand is truthy, and ⊤ otherwise. |
↔? |
xnor? |
Binary infix | 3 | Return the right operand when the left is truthy, the left operand when only the right is truthy, and ⊤ otherwise. |
⊨? |
onlyif? |
Binary infix | 2 | Return the right operand if the left is truthy; otherwise return ⊤. |
⋁? |
or? |
Binary infix | 1 | Return the left operand if it is truthy; otherwise return the right operand. |
| Set operators and set comparisons | ||||
⋃ |
union |
Binary infix | 11 | Set union. |
⋂ |
intersection |
Binary infix | 11 | Set intersection. |
∖ |
\ |
Binary infix | 11 | Set difference. |
∈ |
in |
Binary infix | 6 | Membership test using type-aware equality. |
∉ |
Binary infix | 6 | Negative membership test. | |
⊂ |
subsetof |
Binary infix | 6 | Subset test. |
⊃ |
supersetof |
Binary infix | 6 | Superset test. |
⊂⊃ |
equivalentof |
Binary infix | 6 | Set equivalence test. |
| Path operators | ||||
@ |
Binary infix | 6 | Evaluate a path and return the first match. | |
@@ |
Binary infix | 6 | Evaluate a path and return all matches. | |
@? |
Binary infix | 6 | Check whether a path has at least one match. | |
| OO / type related operators | ||||
typeof |
Unary prefix | Return the runtime type name. | ||
instanceof |
Binary infix | 6 | Inheritance-aware type or class check. | |
does |
Binary infix | 6 | Trait implementation check. | |
can |
Binary infix | 6 | Method availability check. | |
≡ |
== |
Binary infix | 5 | Type-aware equality. |
≢ |
!= |
Binary infix | 5 | Type-aware inequality. |
| Chain operators | ||||
▷ |
|> |
Chain infix | Bind the left value to ^^ while evaluating the right expression. |
|
◁ |
<| |
Chain infix | Bind the right value to ^^ while evaluating the left expression. |
|
| Assignment operators | ||||
:= |
Assignment infix | Assign a new value. | ||
~= |
Assignment infix | Regexp-replace assignment. | ||
+= |
Assignment infix | Add and assign. | ||
-= |
Assignment infix | Subtract and assign. | ||
×= |
*= |
Assignment infix | Multiply and assign. | |
÷= |
/= |
Assignment infix | Divide and assign. | |
**= |
Assignment infix | Exponentiate and assign. | ||
_= |
Assignment infix | Concatenate and assign. | ||
?:= |
Assignment infix | Assign only when the current value is undefined or null-like. | ||
| Other operators | ||||
++ |
Postfix | Increment and return the previous value. | ||
-- |
Postfix | Decrement and return the previous value. | ||
++ |
Unary prefix | Increment and return the new value. | ||
-- |
Unary prefix | Decrement and return the new value. | ||
\ |
Unary prefix | Create an lvalue reference. | ||
? : |
Ternary | Conditional expression with true and false branches. | ||
?: |
Ternary | Elvis-style short ternary with a fallback value. | ||
default |
Binary infix | 5 | Copy a Dict or PairList and fill missing keys from another Dict or PairList. | |
Ambiguous tokens by role
Some tokens are valid in more than one role:
~is both unary bitwise-not (prefix) and binary regexp-match.\\is both unary reference (prefix) and binary set difference.+and-can be unary (prefix) or binary arithmetic.#is a prefix operator for cardinality;#followed by!at the start of a file is still a shebang line.++and--can be prefix or postfix....is a range operator inside collection literals, a variadic marker in parameter lists, and argument spread inside call argument lists.
When mixing forms, parentheses are recommended for readability.
This matters especially for path lvalues. When applying prefix/postfix ++ or --, or unary reference \\, to data @ path, data @@ path, or data @? path, parenthesize the path expression:
( data @ "/meta/count" )++; ++ ( data @@ "/users/*/age" ); \( data @? "/meta/title" );