The error problem in AS3

2009 November 8
by Sven Busse

Juten Tach,

this post was inspired by a topic, i am interested a bit lately, “Functional Programming”. There is a very informative series of videos over on channel9, that covers functional programming, moderated by Erik Meijer from Microsoft Research. I have not yet made it through every bit of the topic, but one thing, that has already made a big impression on me is the statement, that functional programming emphasizes honesty of code. So what does that mean?

Honesty means, that a developer wanting to use a method for example, exactly knows, what to expect from it. In some sense, ActionScript has some limited honesty. Let’s take this method for example:

var names:Vector.<String>;

function getName(id:int):String {
   return names[id];
}

It seems to be honest about, what it returns, a String (we will see, it isn’t really honest about that). But it isn’t honest about what String. We could call this method three times with the same value for ‘id’, but we could not be sure, that we allways get the same result back, because the return value depends on the stuff, that is in the ‘names’ Vector. This is called side effect. Functional programming tries to avoid side effects where possible. The aim is, whenever i give a specific value to a method, i should get back the same result. So the method is not only honest about the type of value, but also about the value itself.

OK, so far, so good. So what’s that to do with errors in ActionScript? Let’s look at the method again from above. If you try to use a Vector with an index out of the bounds of the Vector, you get a RangeError. By the way, i was astonished to recognize, that trying to do that with an Array simply returns null, while Vector throws an error. I find that to be a bit inconsistent. Anyway, what that means is, that our method getName()  could potentially throw an error instead of returning a String, as it declares. This might sound trivial, but i find it to be absolutely non-trivial. Strict typing means, that i as a programmer can expect, that if the method says, it returns a String, it will do so. But now we find, that it might not. getName() might not return anything, if an error occurs. Now you might reply “well, simply catch the error, and you’re good”. But how am i to know, that i have to? If i am responsible for the whole code base, i might know, that this method can throw an error, but what if the method is provided by some third-party library?

So this means, that ActionScript is not completely honest about return types, because we can only hope, that a method returns, what it says, but it might as well do nothing. Java tries to circumvent this problem with the ‘throws’ clause. A method can define, that it either returns what it returns, or that it might throw an exception of a certain type. The point here is, the Java compiler will not compile a method, if it finds, that the code in that method might throw an exception, but that the method has not either catched it or declared via the ‘throws’ clause, that the exception might occur (there are exceptions to this rule, but let’s just forget about these for a moment).

We don’t have that in ActionScript. In ActionScript, any method could potentially throw an error (not to speak of error events, which enlarges the problem even more) and we simply have no chance of knowing which method might throw which error. In the light of these thoughts it comes to no surprise, that the new flash player now supports global error handling, which for me feels like fixing a sympton rather than the cause. Catching errors globally is just another way of saying: “I have no idea, where all these errors come from, so let me simply catch them all in one place.”

To end up with, i want to repeat, that Array simply returns null, when trying to use it with an index out of the bounds of the Array. So it does not throw an error like Vector does. Looking at it from a functional-programming-point-of-view, this is more honest, than what the Vector does. If i would have made my example with an Array, getName() would allways return a String (well, not really, but null can be implicitly converted to a String by the runtime, so … it’s OK). That means, that the programm does not break and the contract is valid, the method is more honest. Of course, now you might have to deal with checking for null, as Jesse Warden complaint about already. A solution to this problem could be to return a default value instead of null. Of course, this will not work in all situations.

No comments yet

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS