Silex v0.47.1 / Docs Canonical source ↗

Calculate, compare, and chain operations

Silex operators cover numeric calculations and can receive explicit semantics for package types. Impossible operations remain compile-time errors.

Calculate with numbers

func main() {
    let left = 10
    let right = 3

    print(left + right)
    print(left - right)
    print(left * right)
    print(left / right)
    print(left % right)
}

This program prints 13, 7, 30, 3, and 1, each on its own line. The +, -, *, and / operators accept numbers; % accepts integers only. Silex checks overflow, division by zero, and unrepresentable negation.

Compatible integers widen within their signed or unsigned family. The presence of a floating-point number selects the common float32 or float64 type.

Define an operator for a type

An operator function is declared at module level. Its parameters make both operands explicit, and its body remains an ordinary Silex function:

struct Vec2 {
    var x:float
    var y:float
}

func operator +(left:Vec2, right:Vec2) Vec2 {
    return Vec2(left.x + right.x, left.y + right.y)
}

func operator *(left:Vec2, right:float) Vec2 {
    return Vec2(left.x * right, left.y * right)
}

func operator -(value:Vec2) Vec2 {
    return Vec2(-value.x, -value.y)
}

+, *, and / require two parameters. - accepts either two parameters for subtraction or one for negation. Each orientation is explicit: accepting Vec2 * float does not automatically declare float * Vec2.

Parameters are owned values without defaults, and the return type is a non-void owned value. At least one operand must be a nominal type declared by the function's package, so a package cannot redefine calculations between two foreign types. Generic operator functions are not accepted yet.

Visibility follows ordinary function rules. An overload intended for package users must be public and becomes available through the import that exposes its module. Resolution compares operand types and their implicit conversions; the return type never selects an overload.

Compare values

Numbers recognize ==, !=, <, <=, >, and >=. Strings compare their exact UTF-8 bytes. Two structures are comparable when all their fields are; their comparison is recursive. Enums compare their active variant and then their associated values. Classes compare shared identity, not field contents.

Comparing T? with a T value promotes the latter to an optional. Thus, maybe_name == "Silex" checks both the string's presence and its contents; an absent value produces false.

Combine conditions

if ready && count > 0 {
    work()
}

if missing || expired {
    refresh()
}

&& and || short-circuit evaluation: their right operand is evaluated only when the result is not already known. ! negates a boolean.

Manipulate unsigned bits

&, ^, <<, and >> accept unsigned integers. A shift count must fit the width of the left operand.

let masked = flags & mask
let toggled = flags ^ mask
let shifted = value << 2
let reduced = value >> 1

Change a value

A mutable variable, field, or indexed element accepts +=, -=, *=, /=, %=, as well as ++ and --. Each compound assignment performs the same checked operation as its operator, then stores the result back in the original place. When a binary operator is overloaded, +=, -=, *=, or /= reuses that overload automatically; its result must be assignable to the target type. %= remains integer-only, while ++ and -- remain numeric-only.

Apply several operations to the same object

The .. cascade operator evaluates its receiver once, applies each segment, and produces that same receiver after its changes:

var values:int[] = []
    ..append(10)
    ..append(20)
    ..reverse()

A segment is a method call or direct field assignment. Ordinary mutability, visibility, ownership, and borrowing rules still apply. An existing value must therefore be mutable when a segment writes to it; a new owned temporary can be configured directly.

A single dot after a call ends the cascade and resumes ordinary access on that call's result: values..append(30).count(). .. is one token and remains distinct from ..., which forms an integer range.

Exact operator precedence is available in the syntax reference.

Back to values · Choose a branch or loop