Blocks and Scopes
Blocks
In Figures, a "block" is a sequence of calculations surrounded by curly braces { ... }
. Functions, if statements, while loops, and others use blocks to define their calculations.
This example has two blocks, one for the if
statement and one for the else
clause:
dinner = random(15..30 dollars)
if dinner > $25 {
dinner += 15% tip
}
else {
dinner += 20% tip
}
$23
$27.60
NOTE
By convention, the calculations inside a block are indented to visually separate themBlocks can be nested inside each other. For example, here's a while
loop block with an if
statement block contained within it:
value = 10
double evens = 0
while value > 0 {
if is even(value) {
double evens += value × 2
}
value -= 1
}
10
0
60
0
Scopes
A scope is an area where values are defined. When you create a new variable or function, it belongs to a scope, and you can use that name anywhere in the scope. For example, the top level of your sheet is called the "global scope". Here, run
and bicycle
are variables in the global scope and can be used anywhere in the sheet.
run = 5 miles
bicycle = 25 miles
run × 2 + bicycle × 3
5 mi
25 mi
85 mi
Blocks define a new scope inside the global scope. Variables like run
can be used inside the block scope. However, a variable defined inside a block can't be used outside that block scope.
run = 5 miles × 4 days
bicycle = 25 miles × 2 days
if run > 10 miles {
all runs = run
}
all runs + bicycle
20 mi
50 mi
20 mi
●
In the above example, all runs
was defined inside the if statement block so it can't be added to bicycle
in the global scope. To make this work, you would define all runs
in the global scope first.
run = 5 miles × 4 days
bicycle = 25 miles × 2 days
all runs = 0
if run > 10 miles {
all runs = run
}
all runs + bicycle
20 mi
50 mi
0
20 mi
70 mi
Child Scopes
Just like the global scope can contain block scopes, a block scope can contain other block scopes. You can use any names defined in the same scope or a containing scope.
runs = [5 mi, 3 mi, 5 mi]
long runs = 0
for run in runs {
if run > 3 miles {
long runs += run
}
}
long runs
[5 mi, 3 mi, 5 mi]
0
10 mi
10 mi
In the example above, runs
and long runs
are in the global scope, so they're available anywhere in the sheet. Then run
is defined in the for-loop scope so its also available in its child scope, the if statement block.
Conflicting Names
Normally you can't create two variables with the same name. There would be no way to tell which variable you mean.
let value = 10
let value = 20
10
●
But you can do this if they're defined in different scopes.
let value = 10
do {
let value = value + 1
value × 2
}
value × 2
10
11
22
20
There's a value
defined in the global scope and a different value
in the do-statement scope. Notice that you can even declare one value
using the other. Figures knows to look at the current scope for a variable first, then keep looking at each containing scope until the variable name is found.
External Scopes
In addition to the hierarchy of scopes defined in your sheet, there are scopes that contain the global scope. First, there's the built-in scope: a sheet defined by the system called Figures
. All the built-in names are available anywhere in your sheet because it's a containing scope. Also, just as you can create new values with the same name inside an inner scope, you can use reuse built-in names for your values.
maximum(5, 10, 15)
maximum = 42
Figures.maximum(maximum, 15)
15
42
42
As you can see in the example above, maximum
is re-defined to be a variable instead of a function. However, the original function is still available using the member operator.
Importing sheets works just like the Figures
sheet. When you import another sheet, it's global scope is available as a containing scope to your sheet. This means you can use any values defined at the global level in the imported sheet.