Basics, 7 of 8
Functions
Parameters and results, defaults and named arguments, several results at once, ByRef, and overloads.
What you’ll build
The pieces of a till that prints receipts: a function that formats money, one that adds up any number of prices, one that finds the cheapest and dearest items at once, and one that applies a discount to a running total. Together they show how FutureBlitz functions take and give values.
Parameters and a result
A Function lists its parameters, each with its type, and its result’s type after a colon. A
function with a result must Return one on every path; fb checks this when it compiles. A
function whose body is one expression can write it after =>.
Import std.core
Function Money(cents: Int): String
Local sign = cents < 0 ? "-" : ""
Local whole = cents < 0 ? -cents : cents
Return "{sign}${whole / 100}.{whole % 100:02}"
End Function
Function Line(item: String, cents: Int): String => "{item:<12}{Money(cents):>9}"
Print(Line("coffee", 350))
Print(Line("refund", -120))coffee $3.50 refund -$1.20
Functions are declared at a file’s top level, and can be called from anywhere in the file, above their declaration too. Every call has parentheses, even one with no arguments.
Defaults and named arguments
A parameter can have a default, used when the call leaves it out. A call can name an argument,
like symbol: "€", to skip the parameters before it or to make the call clearer.
Import std.core
Import std.text
Function Money(cents: Int, symbol: String = "$"): String
Return "{symbol}{cents / 100}.{cents % 100:02}"
End Function
Function Line(item: String, cents: Int, width: Int = 12, symbol: String = "$"): String
Return item.PadRight(width) + Money(cents, symbol).PadLeft(9)
End Function
Print(Line("tea", 280))
Print(Line("tea", 280, symbol: "€"))
Print(Line("tea", 280, 6))tea $2.80 tea €2.80 tea $2.80
A parameter can’t be assigned inside its function, unless it’s a ByRef parameter, which this
page comes to below. To change a value that came in, copy it into a Local first.
Any number of arguments
A last parameter written prices: Int... takes the rest of a call’s arguments, however many,
as an array. A call can also pass an array there as it is.
Import std.core
Function Total(prices: Int...): Int
Local sum = 0
For price In prices
sum += price
End For
Return sum
End Function
Print(Total())
Print(Total(350, 280, 425))
Local basket = [120, 120, 999]
Print(Total(basket))
Print(basket)0 1055 1239 [120, 120, 999]
Print takes any number of values this way, of any types a string can show, which is why
Print(a, b) prints both, with a space between. An array passed to Print is one value, shown
as [120, 120, 999].
Several results at once
A function gives several values at once by returning a tuple, written in parentheses. Local
can take a tuple apart into one variable for each element, and _ skips an element that isn’t
needed.
Import std.core
Function LowHigh(prices: Int[]): (Int, Int)
Local low = prices[0]
Local high = prices[0]
For price In prices
If price < low Then low = price
If price > high Then high = price
End For
Return (low, high)
End Function
Local cheapest, dearest = LowHigh([350, 120, 999, 425])
Print("from {cheapest} to {dearest} cents")
Local _, top = LowHigh([5, 50, 500])
Print(top)
Local both = LowHigh([7, 3])
Print(both, both.0, both.1)from 120 to 999 cents 500 (3, 7) 3 7
ByRef
A ByRef parameter is the caller’s own variable, so assigning it changes the caller’s value. The
call says ByRef too, so a reader can see which variables a call may change.
Import std.core
Function Discount(ByRef total: Int, percent: Int)
total -= total * percent / 100
End Function
Local total = 2000
Discount(ByRef total, 10)
Print(total)
Discount(ByRef total, 50)
Print(total)1800 900
Only a Local, a Global, a ByRef parameter, or a field of one can be passed ByRef: not a
constant, a literal, a loop variable, another parameter, an array’s element, or a computed value.
Overloads
Several functions can share a name when their parameter types differ. A call runs the one whose parameters fit its arguments.
Import std.core
Function Describe(cents: Int): String => "{cents} cents"
Function Describe(item: String): String => "an item named {item}"
Function Describe(item: String, cents: Int): String => "{item} at {cents} cents"
Print(Describe(350))
Print(Describe("tea"))
Print(Describe("tea", 280))350 cents an item named tea tea at 280 cents
What you learned
- A function declares each parameter’s type and its result’s type, and returns on every path.
- Parameters can have defaults, and a call can name its arguments.
values: T...takes any number of arguments as an array.- A tuple returns several values, and
Local a, b = ...takes it apart. - A
ByRefparameter changes the caller’s variable, and the call saysByReftoo. - Functions with the same name and different parameter types are overloads.
The rules are in the language reference.
Report an issue with this page or with FutureBlitz on GitHub.