AS4 Feature proposal: improved varargs support
Posted in: AS4,ActionScript
ActionScript 3 (AS3) currently provides incomplete support for varardic functions. This is a proposal for improving that support in AS4.
AS3 provides support for “varargs” via the use of an ellipsis before the last parameter in either a constructor or method declaration. To put that into simpler terms, consider the following code:
function f(...args):void { for each (var o:Object in args) { doSomething(o); } }
The code declares a variadic function (in this case a method) f(), which can take zero or more parameters. The method can then access those parameters via an array that – in this case – is called “args”. So f(1, 2,3) would result in doSomething(1), doSomething(2) and doSomething(3) being called sequentially.
AS3 also provides support for calling a method with an array of parameters, rather than by explicitly specifying them as a parameter list. That can be demonstrated with the following modification to our code example:
function f(...args):void { doSomething.apply(this, args); } function doSomething(...args) { for each (var o:Object in args) { ... } }
This takes advantage of the fact that functions are first-class Objects in AS3 and thus can have methods of their own. In this case the method apply() takes an array as its second parameter and calls its instance function with the array expanded to a set of parameters.
Whilst these features are handy, the syntax of apply is clunky and rather toy-like and reveals the JavaScript origins of AS3. Further, the use of …args (the “(rest) parameter” as Adobe call it), falls down when used with constructors as it doesn’t work with inheritance. Consider the following class:
class Parent { public function Parent(...args) { ... } }
If we create a child class, we lose the ability to use Parent’s constructor’s varargs. If we did the following:
class Child extends Parent { public function Child(...childArgs) { super(childArgs); } }
all that happens is that the constructor for Parent gets passed a single parameter, which is of type Array and contains the set of parameters in childArgs.
So I am proposing a simple change to ActionScript language for AS4: the (rest) parameter notation can be used both for defining variadic functions and for passing array-based parameter sets to methods and constructors. This would allow the following code to be written:
public class Parent { public function Base(...varargs) { for (var n:int = 0; n < varargs.length; n++) { trace("Parent " + n + "=" + varargs[n]); } } } public class Child extends Parent { public function Child(...varargs) { super(...varargs); processVarArgs(...varargs); } private function processVarArgs(...varargs) { for (var n:int = 0; n < varargs.length; n++) { trace("Child" + n + "=" + varargs[n]); } } }
Calling new Child(“a”, “b”, “c”, “d”) would then give the following result:
Parent 0=a
Parent 1=b
Parent 2=c
Parent 3=d
Child 0=a
Child 1=b
Child 2=c
Child 3=d
The compiler already understands this notation, as one gets a “1199: RestExpressionNode not yet implemented” error, rather than a syntax error, when using it. My guess therefore is that the Flash Player needs to be tweaked so support this in order to add it to AS4.
Social Web