Language Foundations

Operators & Expressions

Choose arithmetic, comparison, and conditional operators, and distinguish their results from assignment.

Choose operators for calculations, comparisons, and conditional work. Use the grouping rules to read an expression's result and distinguish it from an assignment that changes a value.

Follow a calculation to its result

Install Topaz through First Program, then save this as operators-expressions.tpz.

TOPAZ
function score(base: int, bonus: int) -> int {
    let doubled = base * 2
    if bonus > 0 { doubled + bonus } else { doubled }
}

let result = score(20, 2)
let exact = result == 42
let changed = result != 41

print("{result} {exact} {changed}")

Check and run it from the folder containing the file.

BASH
topaz check operators-expressions.tpz
topaz run operators-expressions.tpz

The check succeeds, and the program prints the following text.

Output
42 true true

score(20, 2) first stores 40 in doubled. Since bonus is positive, the if branch adds 2 and returns 42. Both comparisons are true. == and != compare values without changing the binding.

Choose an operator by its job

TaskFormBehavior
Calculate+, -, *, /, %, **Both operands must be int or both float. % takes integers
Join stringsleft + rightBoth operands must be strings
Compare<, <=, >, >=, ==, !=The operand types must support the chosen comparison
Test membershipvalue in collectionFor map keys, write key in map.keys
Combine conditionsleft && right, left || rightSkip the right side when the left side decides the result
Supply a missing valuevalue ?? fallbackUse the fallback for null or None
Propagate a Result errorvalue?Unwrap Ok or return Err from the enclosing function or closure
Pass a value to a callvalue |> nextApply the pipeline rules
Change a valuetarget = value, +=, ??=Perform an assignment statement

&& evaluates the right side when the left side is true. || evaluates it when the left side is false. Skipping unneeded work is called short-circuit evaluation. ?? skips the fallback when a value is present.

Postfix ? requires a compatible Result return type. See Null, Option, Result & Faults for error propagation and missing values.

Group calculations and compare values

Use parentheses to make grouping clear. Multiplication binds more tightly than addition, so 2 + 3 * 4 gives 14. (2 + 3) * 4 gives 20.

Precedence decreases in this order.

  1. Calls, indexing, member access, optional access, and postfix ?
  2. Exponentiation **
  3. Unary +, -, !
  4. Multiplication, division, and remainder
  5. Addition and subtraction
  6. Ranges
  7. Comparison and membership
  8. &&, then ||, then ??
  9. Function composition >>, then pipeline |>

Function composition appears in the specification. For the documented execution path, connect named functions with calls or |>.

int is a signed 64-bit integer. Division truncates toward zero, and a nonzero remainder has the dividend's sign. Runtime integer overflow, division or remainder by zero, and a negative integer exponent cause a runtime fault. In a constant expression, these operations cause a check error. float follows IEEE-754 binary64, including infinity and NaN. Convert explicitly between int and float.

Primitive values, compatible records, Arrays, Options, Results, and nominal values support equality when their contents do. Arrays compare length and element order. Nominal values must come from the same enum, record, or newtype declaration. Map and Set values, functions, resources, and templates cannot be compared for equality.

Correct an assignment or operator

Assignment changes a mutable target and produces no value. Use == to test equality. To increase a mutable count, write count = count + 1. count++, count--, and count **= 2 are unsupported.

Bitwise operators, implicit numeric conversion, a floating-point remainder operator, operator overloading, and user-defined operators are unsupported.

Continue with Types for operand types, Patterns & Control Flow for branch results, or Pipelines & Placeholders to connect calls.