Expressions and Operators
Klyn expressions are compact but strongly typed. This page covers arithmetic, comparisons, boolean logic, identity checks, membership, indexing, interpolation, and operator overloads.
total = 10 + 5
delta = total - 3
scaled = delta * 2
ratio = scaled / 4 # Double: integer / integer is true division
quotient = scaled // 4 # Int: integer division
rest = 17 % 5
power = 2 ** 10
total += 1
total -= 1
total *= 2
total //= 2
total++
total--
The / operator performs true division. Dividing integer primitives therefore
produces a Double, while // performs integer division and keeps the
integer family of the operands. Floating-point division stays in the floating-point family and
supports /=.
assert 9 / 2 == 4.5
assert 9 // 2 == 4
value = 9.0
value /= 2.0
assert value == 4.5
value = 5
assert value == 5
assert value != 6
assert value < 10
assert value <= 5
assert value >= 1
assert 1 < value < 10
Chained comparisons are a built-in language feature and are ideal for range-style conditions.
Numeric comparisons preserve integer precision across signed, unsigned, and floating-point
operands. NaN is the exception: it is unordered, so every ordered comparison involving
nan or nanf returns false. See
NaN and Infinity.
ready = true
connected = true
failed = false
text = "hello"
assert ready and connected
assert not failed
assert text is String
assert text is not null
assert 10 in [10, 20, 30]
assert "green" not in {"red", "blue"}
Klyn uses and, or, and not. C-style
&& and || are rejected.
name = "Ada"
score = 7
ratio = 3.14159
print(f"Player: {name}")
print(f"Score: {score:03d}")
print(f"Ratio: {ratio:.4f}")
Interpolated strings are often the clearest way to build small textual messages without manual concatenation.
user.name
lines[0]
data[-1]
config["theme"]
result = compute(10)
The following table is ordered from the strongest binding level to the weakest. Operators on the same row have the same precedence; associativity decides how an unparenthesized sequence at that level is grouped. Parentheses always override these defaults and are recommended whenever they make an expression's intent easier to read.
| Operators | Associativity | Purpose |
|---|---|---|
Highest priority., ::, [] |
Left to Right | Member access, binding references, indexing, and slicing. |
++, -- | Right to Left (prefix); Left to Right (postfix) | Prefix or postfix update. |
+value, -value, ~value | Right to Left | Unary numeric and bitwise operators. |
** | Right to Left | Exponentiation. |
*, /, //, %, @ | Left to Right | Multiplication, division, remainder, and matrix multiplication. |
+, - | Left to Right | Addition and subtraction. |
<<, >> | Left to Right | Bit shifts. |
<, <=, >, >=, is, is not, in, not in | Left to Right; ordering may chain | Ordering, type or identity checks, and membership. |
==, !=, =~ | Left to Right | Equality and regular-expression matching. |
& | Left to Right | Bitwise AND. |
^ | Left to Right | Bitwise XOR. |
| | Left to Right | Bitwise OR. |
not | Right to Left | Boolean negation. |
and | Left to Right | Short-circuit Boolean AND. |
or | Left to Right | Short-circuit Boolean OR. |
thenValue if condition else elseValue | Right to Left | Conditional expression. |
Lowest priority+=, -=, *=, /=, //=, %=, **=, @=, <<=, >>=, &=, ^=, |= |
Right to Left | Compound mutation. |
assert 2 + 3 * 4 == 14
assert 2 ** 3 ** 2 == 512 # 2 ** (3 ** 2)
assert -2 ** 2 == 4 # (-2) ** 2: unary minus binds first
assert 1 << 2 + 1 == 8 # 1 << (2 + 1)
assert true or false and false # true or (false and false)
assert not 3 < 2 # not (3 < 2)
Calls are parsed with their primary expression and therefore bind before the operators above.
An as cast applies to the completed call/member chain before surrounding arithmetic.
The = token used in a named call argument, together with : and
, delimiters, is parser syntax rather than a general value operator.
An expression such as minimum < probe.value() < maximum is not rewritten as two
independent calls. Klyn evaluates probe.value() once and reuses that result for both
comparisons. Exponentiation and conditional expressions associate to the right; ordinary
arithmetic, equality, bitwise, and Boolean binary operators associate to the left.
Strings, fixed arrays, and dynamic array lists support Python-style
[start:stop:step] slices. Bounds may be omitted and negative indexes are resolved
from the end. The stop index is exclusive.
text = "Hello World"
assert text[0:5] == "Hello"
assert text[::-1] == "dlroW olleH"
values = [10, 20, 30, 40, 50]
assert values[1:4] == [20, 30, 40]
assert values[::2] == [10, 30, 50]
values[1:4] = [200, 300, 400]
assert values == [10, 200, 300, 400, 50]
message = "small" if value < 10 else "large"
public operator==(other as Point) as Boolean:
return this.x == other.x and this.y == other.y
c = a @ b
Operators use ordinary syntax at the call site. A type may define only the operators that make sense for its domain.