Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Expressions: Values and Control Flow

Rex is expression-oriented: everything produces a value.

This page introduces the “everyday” expression forms you’ll use constantly.

Literals

( true
, false
, 123
, 3.14
, "hello"
)

Common primitive types are bool, i32, f32, string (plus uuid, datetime if enabled by the host).

Integers vs floats

123 is an integer literal. It can specialize to any Integral type from context, and defaults to i32 when ambiguous. 3.14 is a float literal and defaults to f32.

If you need to force a different numeric type, you can use an annotation (covered later).

( (4 is u8)
, (4 is i64)
, (-3 is i32)
)

Negative numbers

Rex supports negative integer literals:

-420

Negative literals require a signed numeric type. For example, (-3 is u8) is a type error, while (-3 is i16) is valid.

When you’re unsure about parsing, you can always write subtraction explicitly:

0 - 1

If / then / else

if is an expression and must have an else:

let x = 10 in
  if x < 0 then "neg" else "non-neg"

A common mistake

if requires both branches and they must have the same type:

-- Not OK: the branches disagree ("string" vs "i32")
if true then "yes" else 0

Equality and comparisons

Comparisons are ordinary functions (usually from the prelude type classes):

( 1 == 2
, 1 != 2
, 1 < 2
, 2 >= 2
)

If you try to compare a type without an Eq / Ord instance, typechecking will fail.

Working with strings

String concatenation uses + (via AdditiveMonoid string):

"Rex " + "rocks"

Because + is type-class-based, the same syntax also works for numeric addition.

Grouping: parentheses are your friend

When in doubt, add parentheses—especially when mixing application and infix operators:

let f = \x -> x + 1 in
  f (1 + 2)