asymptote: Rest arguments
6.11.3 Rest arguments
---------------------
Rest arguments allow one to write functions that take a variable number
of arguments:
// This function sums its arguments.
int sum(... int[] nums) {
int total=0;
for(int i=0; i < nums.length; ++i)
total += nums[i];
return total;
}
sum(1,2,3,4); // returns 10
sum(); // returns 0
// This function subtracts subsequent arguments from the first.
int subtract(int start ... int[] subs) {
for(int i=0; i < subs.length; ++i)
start -= subs[i];
return start;
}
subtract(10,1,2); // returns 7
subtract(10); // returns 10
subtract(); // illegal
Putting an argument into a rest array is called _packing_. One can
give an explicit list of arguments for the rest argument, so 'subtract'
could alternatively be implemented as
int subtract(int start ... int[] subs) {
return start - sum(... subs);
}
One can even combine normal arguments with rest arguments:
sum(1,2,3 ... new int[] {4,5,6}); // returns 21
This builds a new six-element array that is passed to 'sum' as 'nums'.
The opposite operation, _unpacking_, is not allowed:
subtract(... new int[] {10, 1, 2});
is illegal, as the start formal is not matched.
If no arguments are packed, then a zero-length array (as opposed to
'null') is bound to the rest parameter. Note that default arguments are
ignored for rest formals and the rest argument is not bound to a
keyword.
In some cases, keyword-only parameters are helpful to avoid arguments
intended for the rest parameter to be assigned to other parameters. For
example, here the use of 'keyword' is to avoid 'pnorm(1.0,2.0,0.3)'
matching '1.0' to 'p'.
real pnorm(real keyword p=2.0 ... real[] v)
{
return sum(v^p)^(1/p);
}
The overloading resolution in 'Asymptote' is similar to the function
matching rules used in C++. Every argument match is given a score.
Exact matches score better than matches with casting, and matches with
formals (regardless of casting) score better than packing an argument
into the rest array. A candidate is maximal if all of the arguments
score as well in it as with any other candidate. If there is one unique
maximal candidate, it is chosen; otherwise, there is an ambiguity error.
int f(path g);
int f(guide g);
f((0,0)--(100,100)); // matches the second; the argument is a guide
int g(int x, real y);
int g(real x, int x);
g(3,4); // ambiguous; the first candidate is better for the first argument,
// but the second candidate is better for the second argument
int h(... int[] rest);
int h(real x ... int[] rest);
h(1,2); // the second definition matches, even though there is a cast,
// because casting is preferred over packing
int i(int x ... int[] rest);
int i(real x, real y ... int[] rest);
i(3,4); // ambiguous; the first candidate is better for the first argument,
// but the second candidate is better for the second one