Statements

Statements are terminated by semicolons ; and they are mandatory, except for the last statement in a block (enclosed by {} pairs) where it can be omitted.

Semicolons can also be omitted for statement types that always end in a block – for example the if, while, for, loop and switch statements.

let a = 42; // normal assignment statement let a = foo(42); // normal function call statement foo < 42; // normal expression as statement let a = { 40 + 2 }; // 'a' is set to the value of the statements block, which is the value of the last statement // ^ the last statement does not require a terminating semicolon (but also works with it) // ^ semicolon required here to terminate the 'let' statement // it is a syntax error without it, even though it ends with '}' // that is because the 'let' statement doesn't end in a block if foo { a = 42 } // ^ no need to terminate an if-statement with a semicolon // that is because the 'if' statement ends in a block 4 * 10 + 2 // a statement which is just one expression - no ending semicolon is OK // because it is the last statement of the whole block

Statements Block

Syntax

Statements blocks in Rhai are formed by enclosing zero or more statements within braces {}.

{ statement; statement;statement }

{ statement; statement;statement; } // trailing semi-colon is optional

Closed scope

A statements block forms a closed scope.

Any variable and/or constant defined within the block are removed outside the block, so are modules imported within the block.

let x = 42; let y = 18; { import "hello" as h; const HELLO = 99; let y = 0; h::greet(); // ok print(y + HELLO); // prints 99 (y is zero) : : } // <- 'HELLO' and 'y' go away here... print(x + y); // prints 60 (y is still 18) print(HELLO); // <- error: 'HELLO' not found h::greet(); // <- error: module 'h' not found

Statement Expression

A statement can be used anywhere where an expression is expected.

These are called, for lack of a more creative name, “statement expressions.”

The last statement of a statements block is always the block’s return value when used as a statement, regardless of whether it is terminated by a semicolon or not.

If the last statement has no return value (e.g. variable definitions, assignments) then it is assumed to be ().

let x = { let foo = calc_something(); let bar = foo + baz; bar.further_processing(); // <- this is the return value }; // <- semicolon is needed here... // The above is equivalent to: let result; { let foo = calc_something(); let bar = foo + baz; result = bar.further_processing(); } let x = result; // Statement expressions can be inserted inside normal expressions // to avoid duplicated calculations let x = foo(bar) + { let v = calc(); process(v, v.len, v.abs) } + baz; // The above is equivalent to: let foo_result = foo(bar); let calc_result; { let v = calc(); result = process(v, v.len, v.abs); // <- avoid calculating 'v' } let x = foo_result + calc_result + baz; // Statement expressions are also useful as function call arguments // when side effects are desired do_work(x, y, { let z = foo(x, y); print(z); z }); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // statement expression