You declare local variables using the syntax:
let(local-declarations) [ let-body ]
let allows 1..N local variable
declarations (where N ==
Each declaration follows the form:
local-id = lambda-expression
You can set
let(_a = 123, _b = 456) [ _a + _b ]
The type of the local variable assumes the type of the lambda- expression. Type deduction is reference preserving. For example:
let(_a = arg1, _b = 456)
_a assumes the type of
arg1: a reference to an
int i = 1; let(_a = arg1) [ cout << --_a << ' ' ] (i); cout << i << endl;
the output of above is : 0 0
While with this:
int i = 1; let(_a = val(arg1)) [ cout << --_a << ' ' ] (i); cout << i << endl;
the output is : 0 1
Reference preservation is necessary because we need to have L-value access
to outer lambda-scopes (especially the arguments).
refs are L-values.
vals are R-values.
The scope and lifetimes of the local variables is limited within the let-body.
let blocks can be nested.
A local variable may hide an outer local variable. For example:
let(_x = 1, _y = ", World") [ // _x here is an int: 1 let(_x = "Hello") // hides the outer _x [ cout << _x << _y // prints "Hello, World" ] ]
The RHS (right hand side lambda-expression) of each local-declaration cannot refer to any LHS local-id. At this point, the local-ids are not in scope yet; they will only be in scope in the let-body. The code below is in error:
let( _a = 1 , _b = _a // Error: _a is not in scope yet ) [ // _a and _b's scope starts here /*. body .*/ ]
However, if an outer let scope is available, this will be searched. Since the scope of the RHS of a local-declaration is the outer scope enclosing the let, the RHS of a local-declaration can refer to a local variable of an outer scope:
let(_a = 1) [ let( _a = 1 , _b = _a // Ok. _a refers to the outer _a ) [ /*. body .*/ ] ]