It is sometimes difficult to remember the order in which arguments
appear in a function declaration. Named (keyword) arguments make calling
functions with multiple arguments easier. Unlike in the C and C++
languages, an assignment in a function argument is interpreted as an
assignment to a parameter of the same name in the function signature,
not within the local scope. The command-line option -d
may be used to check Asymptote
code for cases where a
named argument may be mistaken for a local assignment.
When matching arguments to signatures, first all of the keywords are matched, then the arguments without names are matched against the unmatched formals as usual. For example,
int f(int x, int y) { return 10x+y; } write(f(4,x=3));
outputs 34, as x
is already matched when we try to match the
unnamed argument 4
, so it gets matched to the next item, y
.
For the rare occasions where it is desirable to assign a value to
local variable within a function argument (generally not a good
programming practice), simply enclose the assignment in
parentheses. For example, given the definition of f
in the
previous example,
int x; write(f(4,(x=3)));
is equivalent to the statements
int x; x=3; write(f(4,3));
and outputs 43.
Parameters can be specified as “keyword-only” by putting keyword
immediately before the parameter name, as in int f(int keyword x)
or
int f(int keyword x=77)
. This forces the caller of the function to use
a named argument to give a value for this parameter. That is, f(x=42)
is legal, but f(25)
is not. Keyword-only parameters must be listed
after normal parameters in a function definition.
As a technical detail, we point out that, since variables of the same name but different signatures are allowed in the same scope, the code
int f(int x, int x()) { return x+x(); } int seven() {return 7;}
is legal in Asymptote
, with f(2,seven)
returning 9.
A named argument matches the first unmatched formal of the same name, so
f(x=2,x=seven)
is an equivalent call, but f(x=seven,2)
is not, as the first argument is matched to the first formal, and
int ()
cannot be implicitly cast to int
. Default
arguments do not affect which formal a named argument is matched to,
so if f
were defined as
int f(int x=3, int x()) { return x+x(); }
then f(x=seven)
would be illegal, even though f(seven)
obviously would be allowed.