There is a feature request to support functions which can take a variable number of arguments in Dart (the same request was mentioned earlier in a comment to another feature request). But we can implement such functions without modifying the language or the compiler!
typedef dynamic ApplyType(List positionalArguments);
class Variadic implements Function {
final ApplyType _apply;
Variadic(this._apply) {}
@override
dynamic noSuchMethod(Invocation invocation) {
if (invocation.memberName == #call) {
if (invocation.isMethod)
return _apply(invocation.positionalArguments);
if (invocation.isGetter)
return this;
}
return super.noSuchMethod(invocation);
}
}
num sumList(List<num> xs) =>
xs.fold(0, (num acc, num x) => acc + x);
final Function sumVariadic = new Variadic(sumList);
void main() {
print(sumList([100, 200, 300]));
print(sumVariadic(100, 200, 300));
}
Notes:
The trick is that according to the language specification,
sumVariadic(…)
is a shorthand forsumVariadic.call(…)
(Section 12.15.4, “Function Expression Invocation”). Although we cannot definecall
as a method ofsumVariadic
(because thencall
itself must be a variadic function!), we can define thenoSuchMethod
method to specify what this method invocation should actually do.The declaration of
Variadic
produces a static warning “Concrete classes that implementFunction
must implement the methodcall()
”. This is as described in the language specification (Section 15.5, “Function Types”), but I am not sure if this warning is desirable.With this approach, the static type of
sumVariadic(100, 200, 300)
isdynamic
, notnum
.Needless to say, if you want to use variable-length argument lists seriously, you probably want the proper support of the language instead of this hack. But it is fun to try.
The code above supports only positional arguments. Support for named arguments is left as an exercise.