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 when b mod a is zero; the left operand is the divisor. Its ASCII-safe alias is the divides keyword, with the Unicode form canonical. a ∤ b ("a does not divide b") returns the Number b mod a rather than a strict Boolean — non-zero, and therefore truthy, exactly when a does not divide b. 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.
  • default is 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 whole opts default fallback expression.
  • 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" );