Operators
Arithmetic
Section titled “Arithmetic”| Operator | Meaning | Example | Result |
|---|---|---|---|
+ | Add | 3 + 4 | 7 |
- | Subtract, or negate | 10 - 3 | 7 |
* | Multiply | 3 * 4 | 12 |
/ | Divide (always a float) | 10 / 4 | 2.5 |
// | Floor divide (always an integer) | 7 // 2 | 3 |
% | Remainder | 10 % 3 | 1 |
** | Power | 2 ** 8 | 256 |
/ always returns a float, even for two integers. // floors both operands and rounds the result toward negative infinity:
println 10 / 4 # 2.5println 10 // 4 # 2println -7 // 2 # -4println 7.9 // 2 # 3+ and * also work on strings and lists, and + on bytes. + concatenates and * repeats. If either side of + is a string, the other side is converted to a string.
println "hello" + " world" # hello worldprintln [1, 2] + [3, 4] # [1, 2, 3, 4]println "ha" * 3 # hahahaprintln [0] * 4 # [0, 0, 0, 0]println "count: " + 5 # count: 5Repeating zero times, or a negative number of times, gives an empty string or list: [0] * 0 is [].
Comparison
Section titled “Comparison”| Operator | Meaning |
|---|---|
==, != | Equal, not equal |
<, <=, >, >= | Ordering |
in | Membership |
Integers and floats compare numerically. Strings compare lexicographically. == compares lists and hashmaps by value. See Equality.
println 3 < 3.14 # trueprintln 1 == 1.0 # trueprintln "apple" < "banana" # trueprintln [1, 2] == [1, 2] # truein tests whether a list contains a value, a hashmap contains a key, or a string contains a substring:
println 2 in [1, 2, 3] # trueprintln "name" in {name: 1} # trueprintln "ell" in "hello" # trueprintln !(4 in [1, 2, 3]) # trueLogical
Section titled “Logical”Each logical operator has a symbol and a keyword form. They behave identically.
| Symbol | Keyword | Meaning |
|---|---|---|
&& | and | True when both sides are truthy |
|| | or | True when either side is truthy |
! | not | Negation |
&& and || short-circuit: the right side is only evaluated when it is needed.
println true && false # falseprintln true and false # falseprintln false || true # trueprintln not true # falseNull coalescing
Section titled “Null coalescing”a ?? b is a unless a is null, in which case it is b. Only null triggers the fallback; false, 0 and "" don’t.
name = nullprintln name ?? "anonymous" # anonymousprintln false ?? "fallback" # falseprintln null ?? null ?? "found" # foundTernary
Section titled “Ternary”condition ? a : b picks one of two values:
age = 20println age >= 18 ? "adult" : "minor" # adultBitwise
Section titled “Bitwise”| Operator | Meaning | Example | Result |
|---|---|---|---|
& | AND | 5 & 9 | 1 |
| | OR | 5 | 9 | 13 |
^ | XOR | 5 ^ 9 | 12 |
~ | NOT | ~5 | -6 |
<< | Shift left | 5 << 1 | 10 |
>> | Arithmetic shift right | -16 >> 2 | -4 |
>>> | Logical shift right | -16 >>> 28 | 15 |
flags = 0b1010println flags & 0b0010 # 2println flags | 0b0001 # 11println flags ^ 0b1111 # 5println -16 >> 2 # -4Assignment
Section titled “Assignment”| Operator | Equivalent to |
|---|---|
a = b | Assign |
a += b | a = a + b |
a -= b | a = a - b |
a *= b | a = a * b |
a /= b | a = a / b |
a //= b | a = a // b |
a %= b | a = a % b |
a **= b | a = a ** b |
a &= b, a |= b, a ^= b | Bitwise AND, OR, XOR |
a <<= b, a >>= b, a >>>= b | Shifts |
a &&= b | Assign b only if a is truthy |
a ||= b | Assign b only if a is falsy |
a ~= b | a = ~b (bitwise NOT of b) |
n = 20n += 5 # 25n -= 10 # 15n *= 4 # 60n //= 7 # 8n **= 2 # 64println n # 64
port = 0port ||= 8080println port # 8080Compound assignment works on list elements, hashmap keys and instance variables too:
scores = [10, 20, 30]scores[1] += 5println scores # [10, 25, 30]
totals = {apples: 3}totals["apples"] *= 2println totals # {"apples": 6}Assigning to several names at once is covered in Variables.
Precedence
Section titled “Precedence”From highest to lowest. Operators on the same row are evaluated left to right.
| Level | Operators |
|---|---|
| 1 | Unary -, !, not, ~ |
| 2 | *, /, //, %, ** |
| 3 | +, - |
| 4 | <<, >>, >>> |
| 5 | <, <=, >, >=, in |
| 6 | ==, != |
| 7 | & |
| 8 | ^ |
| 9 | | |
| 10 | &&, and |
| 11 | ||, or, ?? |
| 12 | ? : |
| 13 | Assignment |
Two consequences are worth knowing:
**has the same precedence as*and groups left to right, so2 ** 3 ** 2is(2 ** 3) ** 2, which is64. Unary minus binds tighter, so-2 ** 2is4.- Comparisons bind tighter than the bitwise operators, so
x & 1 == 0meansx & (1 == 0). Parenthesize bit tests:(x & 1) == 0.
println 2 + 3 * 4 # 14println (2 + 3) * 4 # 20println 2 ** 3 ** 2 # 64println (6 & 1) == 0 # trueLine breaks in expressions
Section titled “Line breaks in expressions”A binary operator must be on the same line as its left operand. To split a long expression, end the line with the operator:
a, b, c = 1, 2, 3
ok = a > 0 && b > 0 && c > 0
println ok # trueOperator overloading
Section titled “Operator overloading”Structs can define their own behavior for binary operators. See Operator Overloading.