v0.4.0

Statements

A function body is a block: a sequence of statements between { and }, run in order. Every statement is one of these:

StatementFormPage
Bindinglet x = …; var x = …;Bindings
Constantconst X = …;Constants
Expressionexpression;below
ifif c { … } else { … }if
whenwhen c { … }Conditional compilation
matchmatch v { … }match
while, do while, loop, forwhile c { … } …Loops
break, continuebreak; continue label;break and continue
returnreturn value;return
throwthrow error;Errors
try blocktry { … } catch { … }Handling errors
unsafe blockunsafe { … }Pointers
deferdefer statementdefer

Expression statements

An expression followed by ; is a statement, run for its effect: a call, an assignment, an increment.

PrintLine("hello");
total += price;
count++;

The ; is required. When something else follows a complete expression, the compiler names it: error: expected ';' after expression, but found ':'.

A call that can throw is marked with try wherever it is written, a statement included, so its error can never be lost: try Save(config); passes the error on, try? Save(config); drops it, and try Save(config) catch { e => Report(e) }; handles it. Unmarked, it is error: call to 'Save' can throw 'IoError' but is not marked with 'try'.

An if, match or unsafe block at the start of a statement is the statement, ended by its }, and its value is not used: a branch or arm that ends with a value other than () is an error, this branch yields a value of type 'int' that is not used, whose help reads add ';' or use the value. To use such a value there, bind it or wrap the expression in parentheses.

Blocks are bodies

Braces appear only as the body of something — a function, an if branch, a loop, a match or catch arm, a try or unsafe block. A block on its own is not a statement:

let x = 1;
{
    let y = 2;
}
error: expected an expression before '{'

A body is always a block, even when it holds one statement: if ready return 1; is error: expected '{' to start the 'if' body before 'return'. A value that needs a few statements to compute can be the block of an if value or a match arm, which yields the expression it ends with when that expression has no ;.

Conditions

if, while and do while test a condition, as does an if used as a value, and every condition follows the same rules.

It is a bool. A number, a pointer or an optional is never true or false by itself:

let count: int32 = 3;
if count {
}
error: condition for 'if' must have type 'bool', but found 'int32'

Write the test: if count != 0. An optional is tested with a binding is, which also names its payload: if found is .Some(value) { … } — see Type tests.

It needs no parentheses. if count > 0 { … } is the usual form. Parentheses are allowed, as around any expression, but add nothing: if (count > 0) { … } means the same.

A structure literal inside it is parenthesised. After if, while, for … in, match and when, the first { that could start the body does start the body. So Point { x: 1, y: 2 } cannot appear bare in a condition — its brace would be taken as the body:

if p == (Point { x: 1, y: 2 }) {
    PrintLine("at the start");
}

Without the parentheses the compiler reports error: expected ';' after expression, but found ':' at the first field. A structure literal inside a call's argument list needs no extra parentheses, since the call's own parentheses already enclose it.

See also