Operators
Operators
Arithmetic
+ # addition / string concat / array append or concat / object merge
- # subtraction
* # multiplication
/ # division (error on division by zero)
% # modulo (integer types only; error on modulo by zero)
Integer division by INT_MIN / -1 and LLONG_MIN / -1 saturates to the
type’s maximum instead of trapping. The same guard applies to % (it would
otherwise return 0 rather than trap).
A name immediately after a number is an error — write the operator
explicitly:
var y = 5
var z = 99 * y # correct
# var z = 99y # error: unexpected 'y' after number '99'
Arrays with +
[1, 2] + [3, 4] -> [1, 2, 3, 4] # concatenate
[1, 2] + 3 -> [1, 2, 3] # append
3 + [1, 2] -> [3, 1, 2] # prepend
arr += value # append in place (same-type)
Objects with +
{a: 1} + {b: 2} -> {a: 1, b: 2} # merge; right side wins on conflicts
obj += {key: val} # merge in place
Unary and compound
- # numeric negation
! # logical NOT
= += -= *= /= %= # compound assignment (add_assign avoids O(n²));
# `arr += x` stays type `array` — "same-type" constrains the result, not the element
x++ # postfix increment
x-- # postfix decrement
Comparison
== != > < >= <=
- Integer-to-integer comparisons (
int/long/charin any mix) are
exact — they compare as 64-bit integers, never throughdouble, so no
precision is lost above2^53. Only comparisons involvingfloat/double
promote todouble, with the usual floating-point precision limits. - String comparisons are lexicographic.
charparticipates as a number ('a' + 1is double98.0).- Comparing incompatible types (e.g.
intvsstring) is an error. nil == nilistrue.- Functions never compare equal — even
f == fisfalse.
Logical
&& and || short-circuit:
if (a && b) { ... }
if (a || b) { ... }
Ternary
The condition must be parenthesized:
var label = (score >= 60) ? "pass" : "fail"
Precedence
Highest to lowest:
| Precedence | Operators |
|---|---|
| 1 (highest) | Unary ! - |
| 2 | Multiplicative * / % |
| 3 | Additive + - |
| 4 | Relational < > <= >= |
| 5 | Equality == != |
| 6 | Logical AND && |
| 7 | Logical OR ` |
| 8 | Ternary ? : |
| 9 (lowest) | Assignment = += -= *= /= %= ++ -- |
Numeric promotion
| Left | Op | Right | Result | Notes |
|---|---|---|---|---|
int |
op | int |
int |
saturates on overflow |
int |
op | float |
float |
|
float |
op | float |
float |
|
long |
op | long |
long |
saturates on overflow |
int |
op | long |
long |
|
long |
op | float |
double |
no precision loss through float |
char |
op | number | double |
|
| anything | op | double |
double |
For + - * / on integral long ∘ float, the long is promoted through
double (previously through float, which lost everything past 24 bits:
16777217L + 1.0f collapsed to 16777216).
String concatenation: when either operand of + is a string, both are
converted to strings and concatenated (nil + " " is "nil ").