Language Reference: Variables
Defining, accessing, and updating variables
Defining Variables
We can use variables to store values. Variables in Pointless are
defined using the assignment = operator. Variable names
must be valid identifiers, and must not
be keywords.
-- Store the string "Lilah" in the variable `name`
name = "Lilah"
name ="Lilah"
Accessing Variables
After a variable is defined, it can be used by other pieces of code.
points = 90
total = 100
points / total
0.9
Reassigning Variables
Variables can updated after being initially defined. The syntax for reassigning an existing variable is the same as for defining a new variable.
score = 0
score = 1
score =1
Compound Assignment
Sometimes we want to update an existing variable based on its current
value, for example incrementing a score variable.
score = 0
score = score + 1
score =1
We can simplify these sorts of updates using the
compound assignment syntax, which combines a binary opeartor
like + with the assignment operator =.
score = 0
score += 1 -- Equivalent to score = score + 1
score =1
Compound assignment also works with pipeline operators.
cmpPct = 27 / 43
cmpPct |= Math.roundTo(3) -- Equivalent to cmpPct = Math.roundTo(cmpPct, 3)
cmpPct =0.628
The available compound assignment operators are +=,
-=, *=, /=, **=,
%=, |=, $=, and
?=.
Variable Scope
Pointless is function-scoped, meaning that functions determine the scope of variables.
Variables defined outside of functions are globals, and can be accessed both by code within functions and code outside of functions.
pi = 3.14 -- Close enough
fn area(radius)
pi * radius ** 2 -- We can use the global `pi` within the function
end
area(5)
78.5
Variables defined inside a function, including function parameters, are locals, and are only accessible withing that function.
fn distance(x1, y1, x2, y2)
-- `dx` and `dy` are only defined within the function
dx = x1 - x2
dy = y1 - y2
Math.sqrt(dx ** 2 + dy ** 2)
end
distance(0, 0, 3, 4)
-- Incorrect, we can't access `dx` outside of `distance`
dx
5
Error: variable is not defined
Function-scoping means that control structures like conditionals and loops don't create new scopes. Variables defined within these control structures (including loop variables) will be accessible outside of the structures.
numbers = [1, 2, 3, 4, 5]
total = 0
for n in numbers do
total += n
end
total
n
15
5
Shadowing
Local variables with the same names as globals will shadow those globals. Defining a local variable inside a function will not change the value of a global variable with the same name.
greeting = "Hello"
fn sayHi()
-- Changes the value of `greeting` within the function, making a new local
-- definition and leaving the global definition for `greeting` unchanged
greeting = "hi"
"$greeting world!"
end
sayHi()
greeting -- Value of the global variable hasn't changed
"hi world!"
"Hello"
When a function defines a local variable that shadows a global, code in the function won't have access the global definition, even if the variable access precedes the local definition.
greeting = "Hello"
fn sayHi()
-- Invalid, local variable `greeting` is not yet defined and
-- global `greeting` is shadowed and therefore inaccessible
print(greeting)
greeting = "hi"
end
sayHi()
Error: variable has not been defined yet
Structural Updates
In Pointless, we can use assignment syntax to update variables containing lists, objects, and tables.
hero = { name: "Lilah", score: 0, items: [none] }
hero.score += 1 -- Increment the `score` value in `hero`
hero.items[0] = "food" -- Replace the first value in the `items` list in `hero`
hero ={ name: "Lilah", score: 1, items: ["food"] }
Note that structural updates like these are still just variable reassignments; they do not mutate the underlying data structures like they would in other languages. See the chapter on immutability for more details.