asymptote: Named arguments
6.11.2 Named arguments
----------------------
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.