Architectural Atrocities, part 7 / MXMLC WTF (6): Some types are less equal than others

An object of type Number, int, uint and Boolean cannot contain null. You may find it obvious, but I find it weird and disturbing. Disturbing enough to include it in my series on architectural atrocities in ActionScript.

Edit: I can’t really decide if this is an Architectural Atrocity or an MXMLC WTF, so I have made it both. This really has to do with the language specification and not the ActionScript API:s, but it is an architectural issue too.

ActionScript is a fully object oriented language. More so than many other object oriented languages. Most object oriented languages have what is called primitives, these are data types that are not objects, but primitive data representing things like integers and floating point numbers. The reason for having primitives is to be able to optimise calculations. But this also means that some types in the language are not objects, and you cannot say that the language is strictly object oriented.

Wait, you say, ActionScript (as of 3.0) also has primitives! There is int and unit! No, those aren’t primitives. Don’t belive me? Here is the proof:

trace(new int(3).toString());

or even better:

trace(3 is Object);

These two examples prooves that int‘s are objects since you can new instances and you can run methods on them (this is more or less the definition), the runtime also says they are objects of a type that is decended from Object.

So int‘s are objects, just as everything else in ActionScript (including functions and classes). If something is an object, it can be null, it should be that simple. This is why I find this disturbing, having types in the language that are neither primitives nor objects is weird. These particular types are special, but it’s not really clear why, or how they are different and that isn’t a good thing in a language or API.

I assume that the reason why they can’t be null is because of some optimisation that is done behind the scenes. Some languages, like newer versions of Java has a feature called autoboxing, which makes primitives work like objects in certain contexts, so you don’t notice that they are different, perhaps this is what is going on in ActionScript too? Java does it in a much cleaner way, however, since there are actually two distinct types – you can’t do int x = null but Integer x = null is legal, and it’s clear why.

You may find this to be a trifle, who needs variables of type Number or int to be null anyway? Most of the time you don’t, and you can work around it if you do, but that is not a reason for accepting inconsitencies in a language. And why should Number work in this way when String doesn’t?

Addition (16 march 2007):

Here is a code example to clarify the issue

This code will not compile:

function something( value1:Number, value2:Number=null ) : void {
  if ( value2 == null ) {
    value2 = value1;
  }
  // ...
}

However, this code will:

function something( value1:Number, value2:Object=null ) : void {
  if ( value2 == null ) {
    value2 = value1;
  }
  // ...
}

There is no functional difference between these two examples, one compiles, but not the other, the only difference is that the latter contains less type information.

Edit (18 march 2007): I changed the code examples above to use two parameters instead of one, it’s more clear that way. Say that you wanted to make a constructor for rectangular objects with the parameters describing the lengths of the sides, if the second argument was omitted you could use the first for both sides, making the rectangle a square – a standard method overloading example.

Addition (18 march 2007):

The problem here is also that I can’t think of a way of using default parameter values to implement optional parameters if those parameters are of type Number, int or uint (and perhaps Boolean, although I find it less of an issue). The way you normally do it is as in the example above, by passing null to signify “not set”. With the number types you can’t pass null because the compiler doesn’t allow it, nor can you use NaN, Infinity, or any other constant that I can think of, because those are not compile time constants. It seems you have to use a magic number, which is a big no-no. This really sucks.

Footnote: There is another oddity on the same line as this one lurking in the ActionScript 3.0 specification: only variables of type * can be undefined. This one I actually endorse, having both undefined and null is a bit weird, especially since they are equal (although not identical).

Before you comment, please think this through. I don’t mean to be patronising but be sure you know the difference between a class, an object, a variable and a type first. I’m not interested in workarounds, nor solutions to “the problem”. This article is here to cast light on an inconsistency in the ActionScript 3.0 language, and also to discuss some object oriented principles.

5 Responses to “Architectural Atrocities, part 7 / MXMLC WTF (6): Some types are less equal than others”

  1. Mark Lapasa Says:

    Re: No autoboxing in Flash.

    I am no Flash Player engineer but I am pretty sure there is a good reason why autoboxing is not an ActionScript feature. This is my explanation…

    Primatives in Java are stored on the stack which is the 2nd fastest place for accessing data. Objects that are instantiated using the ‘new’ kewyword are stored in the 3rd fastest place in memory, the heap. In order for primatives to be manifested into objects (for the purposes of late binding, is my guess), they need to be in the same memory space as instantiable objects. Thus, primatives get wraped into their respective wrapper classes in the heap.

    i.e. an ‘int’ in the stack, will get stored as an ‘Integer’ in the heap.

    (J2SE5 now introduces autoboxing to handle this type of conversion because in the past it used to be a lot more explicit coding/downcasting.)

    The Flash Player, being the C++ plug-in it is, is probably stored in the memory’s heap. Because the “Flash Virtual Machine” (AVM) runs under the same process as the browser, it’s working memory space is the heap and cannot write to the stack. Thus when the AVM creates it’s objects or primatives, it’s really writing it in the heap. I mention all of this because in this case, autoboxing does not make sense in Flash.


    Re: An object of type Number, int, uint and Boolean cannot contain null.

    If you don’t like not being able to set a low-level data type to null, there is no reason why you can’t leverage the OO-ness of ActionScript and be able to create your own high-level data abstraction that will satisfy your requirement.

    I find the idea of Boolean storing a 3rd value null, in addition to true and false to be illogical. It’s like asking for a 3-way light switch that’s either on, off, or … null.

    If you could provide a use-case where having a primative set to null would be an advantage and that the work-arounds would have a detremental affect on the O-running time or code readability/maintence, that would be great.


    Having explained that primatives are probably heap objects, this could add fuel to your argument that primatives are really ought to be able to set to null. I understand maybe you might want to have a primative variable that is stripped of any data by deferencing it to null. However, really your beef should not be with ActionScript but with ECMA, the standard which ActionScript strives for…specifically ECMA-262.

  2. Theo Says:

    Although your explanation may be correct, I don’t care about where they are stored, it’s still a language specification issue. ActionScript and ECMAScript (which are the same to me, I don’t particularly critisise either over the other) should not let technical details get in the way of consistency. If they are primitives, don’t treat them as objects, and if they are objects don’t treat them like primitives.

    And about heap vs stack, you are probably right in that the objects are stored in the web browser’s heap since that is where the ActionScript interpreter lives, but that dosen’t mean that they are stored in the ActionScript interpreter’s heap, because those are very different things. You mention that AVM is a virtual machine, but you forget that that means that it has it’s own (virtual) registers, heap and stack and just because they are all allocated in the browser’s heap doesn’t mean that they are equal.

    Now, I’m pretty sure that all objects in ActionScript are actually stored in the heap (the AS interpreter’s heap, that is), since there would have to be some real clever magic for closures to work otherwise.


    I do agree that a boolean with the value null can be a bit odd at first glance, but you just have to think of null as “not set” (which is what “undefined” was supposed to mean), and it should be a runtime error to use such a boolean, just as it should be when trying to run a method on something that is null. Compare this to Boolean (not boolean) in Java, or how you would store booleans in a database (where you can disallow NULL, but also use it to mean “not set”, which is handy).

    And no, I don’t want a higher level structure representing my booleans. I want booleans to be booleans, and I want them to be objects, just like they are. But I want the compiler and the runtime to accept boolean references to be null, because I see no reason why not.

    An example (similar to the code that got me to write this post) of where I would want to have a primitive with the value null:

    function something( aValue : Number = null ) : void { if ( aValue == null ) { aValue = 3; } // … }

    Another example would be null as the default value of all instance variables, so that a runtime error was raised if something wasn’t initialised properly. I’ve never liked the default values that primitives get, it makes for sloppy initialisation.

    In the example above I could use Infinity or NaN (testing with isNaN) or a magic number, but that is not what this is about, this is a discussion about the language and API, not the specific problem. I find the above example perfectly reasonable, because if I change “Number” to “Object” it would compile, and nothing that the runtime can tell me (using describeType or testing with “… is Object”, for example) can tell me why it wouldn’t work.

    If you instead try this code:

    private function something( aValue : Object = null ) : void { if ( aValue == null ) { aValue = 3; } // … }

    It would compile, but more importantly, if you add

    trace(describeType(aValue));

    It will tell you that aValue is of type int. So it’s only a matter of the type of the variable, nothing else. This is really, really, ugly and inconsistent.

  3. matthew Says:

    I agree. Also, it seems to me that since uint and int are not actually primitives, they should be capitalized like everything else.

    However, I’m not sure I understand what you mean by “I can’t think of a way of using default parameter values to implement optional parameters if those parameters are of type Number, int or uint…With the number types you can’t…use NaN.”

  4. Theo Says:

    Well, NaN works for Numbers, but not for ints and uints. When I wrote it I may have missed the NaN/Number case.

  5. Troy Says:

    I feel your pain, I have a background and Java/C# and many years of AS2 mental yoga, hitting the issues you outlined left me going WTF? Shortly after I found I couldn’t extend core classes.

    In doing some performance testing in comparisons, uint/int seem to be hybrid/bastards they are sometimes value mock primitives types other time reference able full blown Objects types.

    I presume they made this choice, is to appeal to C/Java/.Net programmers making the transition, porting code from other languages. They are in spirit like those concepts in other languages.

Leave a Reply