Basics, 2 of 8
Variables and constants
Local, Const, and Global, what each can see, and why a variable has a value before it's read.
What you’ll build
A program that takes orders at a café: it counts them, keeps a running total, and prints a
summary. It uses each of the three ways to declare a name, Local, Const, and Global, and
shows the rules that catch mistakes with them before the program runs.
Locals
Local declares a variable. With a value, its type is the value’s; without one, the type is
written after a colon. A variable keeps its type: it can be given a new value of that type, but
not a value of another.
Import std.core
Local orders = 0
Local total: Int = 0
Local last: String
orders += 1
total += 350
last = "espresso"
orders += 1
total += 425
last = "cappuccino"
Print("{orders} orders, {total} cents, the last a {last}")2 orders, 775 cents, the last a cappuccino
Assigning "three" to orders would be an error, since orders is an Int. A name must be declared before it’s used, so a misspelled name is an error too, not
a new variable.
A value on every path
A variable declared without a value must be assigned before it’s read, on every path the program
can take to the read. Here size is assigned in both branches of the If, so the read after it
is fine.
Import std.core
Local cents = 425
Local size: String
If cents > 400
size = "large"
Else
size = "small"
End If
Print("a {size} order")a large order
Without the Else, size has no value when cents is 400 or less, and the program doesn’t
build. The check happens when the program is compiled, so a variable can never be read before it
holds a value:
Import std.core
Local cents = 425
Local size: String
If cents > 400
size = "large"
End If
Print("a {size} order") Compiling cafe.fb
cafe.fb:8:11: error: 'size' is read before it's assigned
|
8 | Print("a {size} order")
| ^^^^
error: couldn't build cafe.fb because of 1 errorConstants
Const declares a value that never changes. Whenever its value can be worked out when the program
is compiled, as these can, it is, and then it costs nothing when the program runs; one that needs
the running program, like a call to a function that reads a file, is worked out once as the program
starts, with the Globals. One known when the program is compiled can be used anywhere in its file,
even above its declaration. These are written in UPPER_CASE, a common way to mark constants.
Import std.core
Const ESPRESSO = 350
Const TAX_PERCENT = 8
Const WITH_TAX = ESPRESSO + ESPRESSO * TAX_PERCENT / 100
Print("an espresso is {ESPRESSO} cents, {WITH_TAX} with tax")an espresso is 350 cents, 378 with tax
Assigning to a Const, as in ESPRESSO = 400, is an error.
Globals
A Local in a file’s top-level code belongs to that code alone, and functions can’t see it. A
Global is a variable for the whole file, which every function in it can read and change. A
Global without a value starts at its type’s zero: 0, 0.0, False, or "".
Import std.core
Const TAX_PERCENT = 8
Global orders: Int
Global total: Int
Function Order(item: String, cents: Int)
orders += 1
total += cents
Print("{item}: {cents} cents")
End Function
Order("espresso", 350)
Order("cappuccino", 425)
Order("croissant", 300)
Print("{orders} orders, {total + total * TAX_PERCENT / 100} cents with tax")espresso: 350 cents cappuccino: 425 cents croissant: 300 cents 3 orders, 1161 cents with tax
Had orders been a Local, Order wouldn’t compile, since it couldn’t see orders. Keep
Globals few: a function that takes what it needs as parameters is easier to follow.
Blocks and names
A Local declared inside a block, like an If or a loop, exists only in that block. A name can’t
be declared again in a block nested in the one that declared it, in a function or in top-level
code, and a function’s Local can’t reuse one of its parameters’ names, so one name always means
one variable there.
Import std.core
Local prices = [350, 425, 300]
Local expensive = 0
For price In prices
Local over = price - 400
If over > 0 Then expensive += 1
End For
Print("{expensive} item over 400 cents")1 item over 400 cents
over is a new variable on each pass of the loop, and can’t be used after End For. Declaring
another Local over in a block inside the loop would be an error.
What you learned
Localdeclares a variable; its type is its value’s, or written after a colon.- A variable keeps its type, and must be assigned on every path before it’s read.
Constis a value that never changes, worked out when the program is compiled whenever it can be.Globalis shared by a file’s functions, and starts at its type’s zero.- A
Locallives in its block, and the blocks nested in that one can’t reuse its name.
The rules are in the language reference.
Report an issue with this page or with FutureBlitz on GitHub.