Core syntax Operators

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.

Arithmetic and Updates
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
Comparisons
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.

Boolean Logic, Identity, Membership
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"}
Use language keywords

Klyn uses and, or, and not. C-style && and || are rejected.

Strings and Interpolation
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.

Calls, Members, and Indexing
user.name
lines[0]
data[-1]
config["theme"]
result = compute(10)
Operator Precedence

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.

Evaluation order Operator binding order
Read from top to bottom
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, ~valueRight to LeftUnary numeric and bitwise operators.
**Right to LeftExponentiation.
*, /, //, %, @Left to RightMultiplication, division, remainder, and matrix multiplication.
+, -Left to RightAddition and subtraction.
<<, >>Left to RightBit shifts.
<, <=, >, >=, is, is not, in, not inLeft to Right; ordering may chainOrdering, type or identity checks, and membership.
==, !=, =~Left to RightEquality and regular-expression matching.
&Left to RightBitwise AND.
^Left to RightBitwise XOR.
|Left to RightBitwise OR.
notRight to LeftBoolean negation.
andLeft to RightShort-circuit Boolean AND.
orLeft to RightShort-circuit Boolean OR.
thenValue if condition else elseValueRight to LeftConditional 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.

Chained comparisons evaluate intermediate operands once

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.

Slices

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]
Conditional Expressions
message = "small" if value < 10 else "large"
Operator Overloading
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.