An AS3 language extension proposal: Java-style enums

Enumerations, or “enums”, are a handy language feature present in many programming languages. It’s what is often referred to as a syntactic sugar feature. What this means is that the behaviour of enums can be achieved using other language features, enums just simplify the process. To use another buzz-word, enums avoid developers having to write a lot of “boiler plate” code, ie code that is long-winded and repetitive and that is better suited to the compiler inferring or generating it for you. Not only does boiler-plate code waste a developer’s time, it encourages that developer taboo: copying and pasting. Copying and pasting of code is one of the greatest sources of bugs, and so anything that discourages it is a good thing. Unfortunately ActionScript 3 (AS3) lacks enums, so I’m proposing here a way of adding them to the language.

As enums are syntactic sugar, they can simulated by the developer, but this invariably introduces boiler-plate code. My proposal therefore is for a simple preprocessor that takes a enum description and generates the AS3 code from it. I wish to take the idea a little further though. Most languages have enums that take the form of:

The language might provide an ordinal and name functions for the enum and might support iterating over the values. That is about it though. One language stands out from the crowd here and that is Java. Many enums are more than just a list of values: each value has metadata associated with it. Java 5 introduced a neat way of encapsulating that metadata within the enum. Consider the following code, which is a classic example of Java enums in action taken from The Java Tutorials:

So the enum is the set of planets and each planet has a mass and radius associated with it. The Planets enum also defines extra methods for manipulating those mass and radius data.

Whilst powerful, Java enums still contain a lot of boiler-plate code, as the developer has to define the constructor and properties and provide the private fields in which the metadata is stored. My proposed AS3 language extension gets rid of this boiler plate code. The idea is to infer the following Java code:

This is done by adding the parameter definition “(mass:Number, radius:Number)” after the enum’s identifier. So the AS3 preprocessor code is simply:

The preprocessor would then turn this into something like the following code:

The Planet enum type can then be used to encapsulate the calculation of weight on the planets in a really neat way. Planets.values yields an array suitable for supplying to a Flex component, eg a ComboBox. The selectedIndex of the ComboBox directly matches the ordinal value of the selected enum. So

Planet.values[comboBox.selectedIndex]

gives us the selected enum instance, and

int(Planet.values[comboBox.selectedIndex].
surfaceWeight(earthWeight/Planet.EARTH).
surfaceGravityString();

gives us a person’s weight in the selected planet, based on their supplied Earth weight. The following SWF shows this in action. The source code is included and accessible via the context menu:

11 thoughts on “An AS3 language extension proposal: Java-style enums

  1. Hi David,
    I agree with the proposal, as there are many areas where ‘official’ enums would be useful. Especially when building consumable APIs it would be great to have runtime type checking rather than a switch statement that runs through the possible options. (i.e. case MERCURY: do x; break; default: throw(new Error(“Unknown Planet”)); ) (sorry for the lack of formatting…)

    One question about your proposed implementation: given that a public constructor is created for the class, couldn’t I instantiate additional Planet instances at runtime? It seems that would break the intended usage of an enum.

    My expectation would be that the list is locked at compile time.

  2. @Alan,

    The preprocessor is a non-trivial task and so will be a huge waste of my time if no one uses it. I’m about half way through writing it and I’m now confident that my approach will work. So I figured it time to get feedback on whether folk would use it or not.

  3. @Chris,

    In the working version, I’d anticipate using the “hidden class” trick of putting a class outside the package to lock the enumeration set. Also I’d like the values property to emit an immutable collection. I’m not sure on how best to do that yet though.

  4. @David

    To make the values property immutable you could return a copy of the array rather than a reference.

    public function get values():Array
    {
    return _values.slice();
    }

    The returned array could still be edited, but it wouldn’t effect the value of the property on the class.

  5. BTW it occurs to me that this could also be implemented as a template or snippet generator for the IDE (FlashBuilder? FDT? IntelliJ IDEA?). In fact I’d like to work on that…

  6. @Alan,

    Sounds an interesting idea if you could get it to work. However the work flows I have in mind involve using Ant etc to automatically build things, so I don’t think the IDE snippet generator idea would work for me unless it can also be run outside the IDE.

  7. @Paul,

    It’s the whole “get people to vote for it” idea that puts me off submitting ideas to Adobe’s JIRA database. For the idea to be implemented, one needs lots of votes. As I see it, to get lots of votes one needs to be well known in the flash community and thus able to drum up the votes.

    So I figure I’m better off developing a framework that does it, getting people using it and then asking them to vote for it to be added to the language. I’m likely to get more votes that way 🙂

Comments are closed.