Assignments
Value assignments to variables use the =
symbol.
let foo = 42;
bar = 123 * 456 - 789;
x[1][2].prop = do_calculation();
Valid Assignment Targets
The left-hand-side (LHS) of an assignment statement must be a valid l-value, which must be rooted in a variable, potentially extended via indexing or properties.
Expressions that are not valid l-values cannot be assigned to.
x = 42; // variable is an l-value
x[1][2][3] = 42 // variable indexing is an l-value
x.prop1.prop2 = 42; // variable property is an l-value
foo(x) = 42; // syntax error: function call is not an l-value
x.foo() = 42; // syntax error: method call is not an l-value
(x + y) = 42; // syntax error: binary op is not an l-value
Values are Cloned
Values assigned are always cloned. So care must be taken when assigning large data types (such as arrays).
x = y; // value of 'y' is cloned
x == y; // both 'x' and 'y' hold different copies
// of the same value
Moving Data
When assigning large data types, sometimes it is desirable to move the data instead of cloning it.
Use the take
function (defined in the LangCorePackage
but excluded
when using a raw Engine
) to move data.
The original variable is left with ()
x = take(y); // value of 'y' is moved to 'x'
y == (); // 'y' now holds '()'
x != y; // 'x' holds the original value of 'y'
Return large data types from functions
take
is convenient when returning large data types from a function.
fn get_large_value_naive() {
let large_result = do_complex_calculation();
large_result.done = true;
// Return a cloned copy of the result, then the
// local variable 'large_result' is thrown away!
large_result
}
fn get_large_value_smart() {
let large_result = do_complex_calculation();
large_result.done = true;
// Return the result without cloning!
// Method style call is also OK.
large_result.take()
}
Assigning large data types to object map properties
take
is useful when assigning large data types to object map properties.
let x = [];
// Build a large array
for n in 0..1000000 { x += n; }
// The following clones the large array from 'x'.
// Both 'my_object.my_property' and 'x' now hold exact copies
// of the same large array!
my_object.my_property = x;
// Move it to object map property via 'take' without cloning.
// 'x' now holds '()'.
my_object.my_property = x.take();
// Without 'take', the following must be done to avoid cloning:
my_object.my_property = [];
for n in 0..1000000 { my_object.my_property += n; }