Expressions

Every field value, function argument, and let right-hand side is an expression — something that produces a value. WCL's expression grammar is small: literals, identifiers, member access, calls, operators, and a handful of constructor forms.

Covered elsewhere

Literal forms live with their types (Numbers, Strings, Booleans, Symbols, Optionals, Lists, Tensors). Function literals are in Functions. if / match / let / block expressions are in Control Flow. This chapter focuses on the connective tissue.

Operators

GroupOperators
Arithmetic+ - * / %
Comparison== != < <= > >=
Logical&& || !
Unary-expr (negate), !expr (not)

Precedence follows the usual conventions: unary tightest, then * / %, then + -, then comparison, then &&, then ||. Use parentheses to group when in doubt.

Numeric promotion

Arithmetic and comparison widen mixed numeric operands to a common type, so cross-width and integer/float mixing work without explicit casts.

a = 1 + 2.0        // i64 widened to f64 → 3.0
b = 1u32 == 1i64   // true
c = 3.0 * 2u8      // 6.0

Member access

A dotted path reads a field. Access chains through records, variant payloads, and any composite that exposes named members.

region = service.metadata.region
deep   = config.services.web.metadata.region

Function calls

Parentheses call a function or constructor. Arguments are expressions, evaluated lazily; the call evaluates the body in a fresh context.

n      = len(items)
total  = sum(map(items, fn(x: i64) -> i64 x * 2))
shape  = Point { x: 1.0, y: 2.0 }

Variant construction

Build a union variant with Union::Variant. Record bodies go in braces, typeref payloads in parentheses, unit constructors stand bare.

a = Shape::Circle { radius: 5.0, stroke: 0.5 }
b = Shape::Polygon(7)
c = Shape::Empty

See Unions for declaring the surrounding variant set.

List literals

Square brackets and commas build a list<T>. See Lists for nested lists and the collection builtins.

xs    = [1, 2, 3]
names = ["alice", "bob"]
empty = []