implicit
Argument Passing
Making use of lexical scope can help reduce argument passing noise between a family of related functions, but doing so is not always possible - you might need to split your code among multiple code units.
Implicit argument passing delivers similar levels of terseness:
struct Module { filename: string }
struct LineCol { line: int; col: int }
struct Diagnostic { filename: string; lc: LineCol; error: string }
fn emit_diagnostic(error: string,
implicit module: Module,
implicit lc: LineCol,
implicit ref diagnostics: Diagnostic[])
{
diagnostics ~= Diagnostic(:module.filename, :lc, :error)
}
fn parse_bool(span: byte[]) {
if (span == "true")
return true
if (span != "false")
emit_diagnostic("Invalid bool literal: " ~ span)
return false
}
Note how we can call
only only specify the emit_diagnosticerror:
argument, the rest will be resolved automatically.
string
Implicit Argument Resolution
Here is how
arguments work:
implicit
-
Any function may have any number of
arguments;implicit -
When invoking a function, the caller may omit any or all of the
arguments of the callee;implicit -
When omitted,
arguments are automatically resolved as follows:implicit-
First, if an
local with matching name and type exists within the lexical scope of the callsite, it is matched and passed to the callee.implicit -
Otherwise, the caller itself receives a matching
argument, and it is now the responsibility of their callers to provide it.implicit
-
This continues, cross module, until either a matching
is found, or a function whose signature cannot be extended is reached, at which point the compiler will error out with the reverse call stack of the mismatched implicit
.
implicit