# Local variables and assignment

While document variables are persisted, variables can be defined locally within code blocks (like constructors to be used to compute things. These variables are only used to compute.

``````private int score;

@construct {
int temp = 123;
temp = 42;
}
``````

### Define by type

Native types can be defined within code without a value as many of them have defaults:

``````#transition {
int local;
local = 42;
string str = "hello";
}
``````

The default values follow the principle of least surprise.

typedefault value
boolfalse
int0
long0L
double0.0
string""
list<T>empty list
table<T>empty table
maybe<T>unset maybe
T[]empty array

A local variable can be annotated as readonly, meaning it can not be assigned.

``````#transition {
readonly int local = 42;
}
``````

This is fairly verbose, so we introduce the let keyword.

### Define via the "let" keyword and type inference

Instead of leading with the readonly and the type, you can simply say "let" and allow the translator to precisely infer the type and mark the variable as readonly.

``````#transition {
let local = 42;
}
``````

This simplifies the code and the aesthetics.

### Math-based assignment, increment, decrement

Numerical types provide the ability to add, subtract, and multiply the value by a right-hand side. Please note: division and modulus are not available as there is the potential for division by zero, and division by zero is bad.

``````#transition {
int x = 3; // 3
x *= 4; // 12
x--; // 11
x += 10; // 21
x *= 2; // 42, the cosmos are revealed
x++;
}
``````

### List-based bulk assignment

Lists derived from tables within the document provide a bulk assignment via '=' and the various math based assignments (+=, -=, *=, ++, --).

``````record R {
int x;
}
table<R> _records;

procedure reset() {
(iterate _records).x = 0;
}

procedure bump() {
(iterate _records).x++;
}
``````