6.12.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