Operators and Expressions
Precedence, arithmetic semantics, optional operators, casts, assignment, and expression values.
Expression model
Most constructs that compute a value can appear wherever a value is expected.
La3 uses expressions to keep examples direct. A block can return its final expression, if can choose a value, match can compute a result, and loop can finish with break value. The reader sees data flow instead of a trail of mutable temporaries.
- Statements are still available where a value is not needed.
- An early
returnis allowed and should be used for guard clauses. - Branches that produce values must agree on type.
- The type checker treats expression value and control-flow reachability as one semantic unit.
Arithmetic semantics
Numeric operators have explicit, documented behaviour so examples do not depend on host-language guesses.
- Integer
/truncates toward zero. %keeps the sign of the left operand.//is floor division.**always producesf64because exponentiation naturally escapes integer-only results.- Mixed numeric arithmetic requires an explicit
ascast.
let a = 7 / 2 // 3
let b = -7 / 2 // -3
let c = -7 // 2 // -4
let d = 2 ** 10 // f64Logical operators
&&, ||, and ! are boolean operators, not value-selection operators.
La3 deliberately avoids the Lua convention where logical operators return one of their operands. That idiom is compact, but in a language that otherwise resembles Rust, C, and TypeScript it would make familiar syntax mean something surprising.
&&evaluates the right side only when the left side is true.||evaluates the right side only when the left side is false.- Both operators always produce
bool. - Use
??for value defaults and?.for optional access.
Optional operators
?? and ?. are the lightweight control-flow operators for T | nil.
left ?? rightevaluatesrightonly whenleftisnil.receiver?.fieldreturnsnilwhenreceiveris absent.- Chained optional access short-circuits at the first absent link.
Option<T>has its own method vocabulary, includingmap,unwrap_or, and?.
let port = opts.port ?? 443
let city = user?.address?.city ?? "unknown"Casts
as marks every conversion that can change representation or lose information.
The checker accepts numeric-to-numeric casts and integer-to-char or char-to-integer casts. It rejects conversions that would pretend unrelated runtime representations are the same thing, such as a string cast directly to an integer.
- Float-to-integer casts truncate.
- Integer narrowing keeps the low bits of the value.
- There is no implicit widening just because the destination type is larger.
- The docs should show casts at protocol boundaries, binary formats, and size conversions.