AS3 User-defined generics: why they are not possible (yet)

! Warning: this post hasn't been updated in over three years and so may contain out of date information.

With Flash Player 10, Adobe introduced a special data type to ActionScript 3 (AS3): the Vector class. The Vector class is a type-safe array class. In other words, the elements of an instance are guaranteed to all be the same type. It achieves this by being a parameterized type, or as such types are commonly known, it is a generic type.

The Vector class is partially type-safe at compile-time and full type-safe at runtime. In the above example code, it will not compile as we are trying to assign “4” to an integer vector on line 3. If we fix this, the code compiles as it cannot detect the invalid assignment on line 5. This will cause a runtime exception though.

Generics have a number of uses. They help to detect errors earlier for example. With an array, an invalid value can be added, but this won’t cause an error until the value is read later. With generics, the error occurs at write-time and so is quicker and easier to find and fix. You also have a clearer idea of what data you are dealing with. A method that returns Vector.<int> is preferable to one that returns an Array, as it’s immediately obvious what the collection will contain.

Given that generics have advantages over untyped collections, it’s no surprise that from the moment they were revealed, folk have been wondering if and how they can create their own generic classes. It was quickly revealed that Adobe hadn’t officially supplied such an ability, and as time has passed and more versions of the SDK and its compiler have come along, its clear it is seen – at best – as a low priority feature. This of course leaves it up to the community to find a way of adding them. In order to achieve such support, two things need to occur: a method is needed to create generic classes and the mxmlc/ compc compilers need to support such classes when referenced by other code.

The Compilers
I’ll start with the second item on the list as I think this is the biggest hurdle to custom generic AS3 classes. If you add the following line into some AS3 code:

var x:Array.<int>;

and compile it, you’ll get the following error:

1199: type parameters with a non-parameterized type

As the Flex SDK compilers are open source, you can download that source and search for the error in the Java code. It’s in ReferenceValue.java:

So here we get a clue as to how we might do custom generics: identify what bit is about the Vector class that results in is_parameterized being set true and replicate that in our new generic classes. Sadly there’s a problem. A search for where is_parameterized is set, reveals it is set in only one place in one file – Context.java:

So the compiler hard-codes support specifically for the Vector class. With the current compiler, there is no way to use custom generic classes, even if we somehow created them via another means. Of course, because the compiler is open source, there is a way around this: modify the compiler’s source to create a custom version. Ideas for how to do this range from hacking a quick check of the package name and setting the flag if it’s for example, __generics__.xxx, through implementing a special IGenericNParam interface or using metadata through to unofficially extending the AS3 language specification in order to provide proper syntax support.

The problem with the last option is likely the reason the above bodge method exists in the first place: it doesn’t appear that there is currently any way of identifying the fact that a class is generic within either the bytecode of a SWF or within the catalogue.xml (or new xml file) within a SWC. Defining new content of a SWF is I feel a recipe for disaster for random bugs and failures with past and future Flash Players, so the modified SWC option would be the only practical one. I’m guessing though that the compiler creates temporary .abc files as it compiles a new SWF or SWC and the modified SWC solution wouldn’t help when a generic class is used within the same library or SWF.

Creating generic classes
Assuming the problems discussed above could be overcome and a generics-friendly version of compiler created, there would be little point in doing so without having a means of creating those generic classes in the first place. So you have created a class within package __generics__.test and compiled it, referenced it within another class and built a test SWF with the modified compiler. You then run the SWF … what happens to your class? How is it told what type it is handling in this instance? Does the bytecode need modifying in some way to handle this? Or does the VM handle all the type checking for the class? Richard Szalay has documented how generic classes get created within the AVM, but this doesn’t really clarify whether custom generic classes need to do anything special.

I feel this is a bit of a chicken and egg situation. Until the compiler is modified and an instance of a custom generic class is created, it seems difficult to know whether that custom generic class needs creating in a special way in order to allow an instance of a custom generic class is created… Luckily there might be a solution: the Adobe product managers for Flash technologies tend to be a friendly and approachable lot. So it’s time for me to email some questions to them.

Conclusion
The best solution to all this is for lots of people to vote for the issue “Enhance Vector type to allow runtime determination of the generic type”
and for Adobe to implement it. Failing that, hopefully the above information will encourage someone to try a proof-of-principle modification to the compiler, which in turn might lead to a community solution. I might even find the time to try it myself one day!

2 thoughts on “AS3 User-defined generics: why they are not possible (yet)

Comments are closed.