Default argument
Some arguments are nearly always the same. Squaring is the usual power; 0 to 100 is the usual range. A default value lets the common call leave that argument out, while the unusual call can still say exactly what it wants. You write it after the parameter's type: name: type = value.
One optional parameter
exponent has a default, so a call may stop after base:
func Power(base: int, exponent: int = 2) -> int {
var result = 1;
for i in 0..exponent {
result *= base;
}
return result;
}
Power(5) means exactly Power(5, 2) — the compiler fills in the missing argument at the call. Power(2, 10) passes its own exponent, and the default is not used.
Arguments fill from the left
Several parameters may have defaults:
func Clamp(value: int, low: int = 0, high: int = 100) -> int {
Arguments still fill the parameters strictly from the left. A call can stop early, but it cannot skip a parameter in the middle:
| Call | value | low | high | Result |
|---|---|---|---|---|
Clamp(150) | 150 | 0 | 100 | 100 |
Clamp(-5) | −5 | 0 | 100 | 0 |
Clamp(42, 50) | 42 | 50 | 100 | 50 |
Clamp(150, 0, 255) | 150 | 0 | 255 | 150 |
The last row is the price of that rule: to change high, the call must also give low, even when it wants the default there. There is no way to name an argument and skip the ones before it.
Every parameter optional
A default may be any value of the parameter's type — a character as easily as a number. When every parameter has one, a call may pass nothing at all:
func Rule(width: int = 12, mark: char = '-') {
for i in 0..width {
Print(mark);
}
PrintLine();
}
Rule() prints twelve dashes, Rule(5) five, and Rule(5, '=') five equals signs.
Defaults come last
A parameter without a default may not follow one with a default. In Mix(first: int = 1, second: int) there would be no way to supply second while leaving first out — the first argument always lands in first — so the declaration itself is refused. Put the parameters callers usually change first, and the ones they rarely touch at the end.
The program
The whole lesson is one package in the Examples repository. Its comments explain every step.
// A parameter can carry a default value, written `name: type = value`. A call
// may then leave that argument out, and the default is used in its place.
//
// Defaults suit the argument that is nearly always the same: squaring is the
// usual power, 0 to 100 the usual range. The common call stays short, and the
// unusual one can still say exactly what it wants.
import Io::{ Print, PrintLine };
// `exponent` is optional. `Power(5)` means `Power(5, 2)`.
func Power(base: int, exponent: int = 2) -> int {
var result = 1;
for i in 0..exponent {
result *= base;
}
return result;
}
// Several parameters may have defaults. Arguments still fill the parameters
// from the left, so a call can stop early but cannot skip one in the middle.
func Clamp(value: int, low: int = 0, high: int = 100) -> int {
if value < low {
return low;
}
if value > high {
return high;
}
return value;
}
// A default may be any value of the parameter's type, a character as easily as
// a number. Every parameter here has one, so a call may pass nothing at all.
func Rule(width: int = 12, mark: char = '-') {
for i in 0..width {
Print(mark);
}
PrintLine();
}
func Main() -> int {
PrintLine("Power(5) {}", Power(5));
PrintLine("Power(2, 10) {}", Power(2, 10));
PrintLine("Clamp(150) {}", Clamp(150));
PrintLine("Clamp(-5) {}", Clamp(-5));
PrintLine("Clamp(42, 50) {}", Clamp(42, 50));
// To change `high` the call must also give `low`, even when it wants the
// default there. There is no way to name an argument and skip the rest.
PrintLine("Clamp(150, 0, 255) {}", Clamp(150, 0, 255));
Rule();
Rule(5);
Rule(5, '=');
// A parameter without a default may not come after one with a default,
// because there would be no way to reach it while leaving the earlier one
// out:
//
// func Mix(first: int = 1, second: int) -> int { ... }
// error: parameter 'second' without a default value cannot follow
// a parameter with a default value
return 0;
}
Run it
cd Examples/Functions/DefaultArgument
rux run
Power(5) 25
Power(2, 10) 1024
Clamp(150) 100
Clamp(-5) 0
Clamp(42, 50) 50
Clamp(150, 0, 255) 150
------------
-----
=====
Common mistakes
func Mix(first: int = 1, second: int) fails with error: parameter 'second' without a default value cannot follow a parameter with a default value. Move the parameters with defaults to the end.Rux has no named arguments, so
Clamp(150, high: 255) is a syntax error: expected ',' between arguments before ':'. Pass every argument up to the one you want to change.exponent: int = 2.5 fails with error: default value type 'float64' does not match parameter type 'int'. The default is checked against the parameter's type like any other value.Try it yourself
- Write
Greet(name: char8[..] = "world")that printsHello, …!, and call it with and without a name. - Predict what
Clamp(150, 255)returns, then run it. Which parameter did255land in? - Swap the parameters of
Ruleso thatmarkcomes first and onlywidthhas a default. Which calls inMainstill compile? - Write the
Mixfunction from this lesson and read the error.
Learn more
- Default arguments in the Rux Reference
- Overload — the other way to let one name take different numbers of arguments
- Variadic — a function that takes any number of arguments