Variables & Scope
Variable names can contain letters or numbers, but must start with a letter. By convention multi-word names are written in camelCase
.
foo
bar3
myLongVariableName
i18n
New variables don't have to be declared specially. Assigning to an unused variable name will create that variable.
foo = 5
foo = foo + 1
It's possible to assign to any variable at essentially any point, but the exact behaviour depends on the surrounding context – assignment to foo
might update foo
, or create a new variable with the name foo
.
Function scopes
Functions cannot alter a variable outside of the function body. For example
x = 1
fn foo() {
x = 2
}
foo()
println(x) # => 1
foo
is free to create and use a variable called x
, but it is a new variable unrelated to the x
in global scope. The same applies to closures.
Control flow scopes
Variables assigned inside a while
, for
or if
/else
will update an outside variable if it exists.
fn foo() {
x = 1
if true {
x = 2
}
return x
}
println(foo()) # => 2
However, if there is no outer variable with the same name, the variable only exists inside the if
body.
fn foo() {
if true {
x = 2
}
return x
}
println(foo()) # => error: No variable named `x`
If this code were to work, it would nevertheless break if the if
condition were false
. Preventing variables from "leaking" in this case simplifies things: a variable is either defined or it isn't, regardless of any runtime values.
If you need to initialise a variable inside a loop or conditional, just set it to nil
first.
fn foo() {
x = nil
if true {
x = 2
}
return x
}
println(foo()) # => 2
Let scope
let
allows you to create a new variable regardless of whether one already exists.
fn foo() {
x = 1
let x = 2 {
# ...
}
return x
}
println(foo()) # => 1
Inside the let
body, assignments work the same as in loops and conditionals.