Tuesday, January 15, 2008

Enums in ActionScript 3

The introduction of Enums in Java 1.5 was a welcome addition. Prior to Java 1.5, one had to simulate Enums with some special patterns. In ActionScript 3 there is no native enum construct in the language. So we need to apply patterns similar to what we did in Java prior to 1.5. While similar, the pattern for ActionScript is a bit different.

Let's start with the basic Enum pattern in ActionScript:

package enumexample
{
public class Color
{
public var _value:String;

public function Color(val:String):void {
this._value = val;
}

public static const RED:Color = new Color("RED");
public static const BLUE:Color = new Color("BLUE");
public static const GREEN:Color = new Color("GREEN");
}
}


The issues with the above Enum implementation are:
  • The constructor is public. So one could do: var c:Color = new Color("FOO"); which violates the notion of the Color Enum constants being restricted to RED, GREEN or BLUE. ActionScript does not allow private constructors.
  • Color does not have a default no-arg constructor which is needed if an instance of Color is de-serialized by the Flash Player from data from the back-end e.g. when using LCDS's RemoteObject to invoke a Java method that returns an instance of Color (see this for LCDS Enum support). For default serialization based on property-value pairs, not only do we need a no-arg constructor but we also need to make _value public or provide a setter. Both these are undesirable because one could change an enum as follows: var c:Color = Color.RED; c._value = "MAROON";
  • If an Enum cannot guarantee uniqueness of enum constant instances, object comparisons based on == will fail. var c:Color = new Color("RED"); if (c == Color.RED); // false. ActionScript does not have the notion of operator overloading.
  • When a Color instance is de-serialized, an instance is first created using the default no-arg constructor and the _value property is then populated. There is no object substitution mechanism available in ActionScript like the readResolve() Java serialization mechanism. So created instances will fail the == comparison as Enum constant instance uniqueness cannot be guaranteed.

The solution I use in conjunction with LCDS RemoteObject is to have Color implement Externalizable and have readExternal() and writeExternal() methods read/write value for _value. In addition, the class is "locked" after the initial construction of the valid Enum constant instances - see the lock member in the Color class below. An exception is thrown when an attempt is made to construct an Enum instance after it is locked. However, since the de-serialization will construct an Enum instance with no args, the exception is not thrown if no args are specified to the constructor. Unfortunately there is no way to detect in the constructor that the instance is being created in the context of de-serialization. The _value member is made private. An equals() method is added which is the way to compare enum instances rather than using ==. However, this is just a guideline/convention and the use of == cannot be enforced. Here's what Color looks like finally - the best one can do given the limitations of the language.

package enumexample
{
[RemoteClass(alias="javaenumexample.Color")]
public class Color implements IExternalizable
{
private var _value:String;
private static var lock:Boolean=false;

public function Color(val:String=null):void {
if (lock && val != null)
throw new Error("Cannot instantiate Enum");

this._value = val;
}

public function get value():String {
return this._value;
}

public static const RED:Color = new Color("RED");
public static const BLUE:Color = new Color("BLUE");
public static const GREEN:Color = new Color("GREEN");

{
lock = true;
}

public function equals(enum:Color):Boolean {
if (enum == null)
return false;

return enum.value == this._value;
}

public function readExternal(input:IDataInput):void {
this._value = input.readUTF();
}

public function writeExternal(output:IDataOutput):void {
output.writeUTF(this._value);
}
}
}

Saturday, January 5, 2008

Why Software Quality Sucks

It was an important customer demo at a big industry trade show. We had worked franticly all through the previous night to get the systems setup for this demo. The demo began very well but halfway through, the program crashed. It was a disaster! Since the demo was for a large and important potential customer, there were a whole bunch of my company suits (non-techie executives) present and they were clearly upset. Apparently they had seen this all too often and couldn't understand why we developers were so incapable of producing bug-free software, and why we should be paid so much money for the junk we produce! At the hospitality suite that night, after everyone was happily buzzed and relaxed, I accosted some of these suits to try and explain to them what had happened and provide excuses for the failed demo. After the usual excuses about demo'ing with the latest unstable dev build, lack of sufficient resources to code, this other team not delivering their fixes on time, bad hardware etc. (all of which they had probably heard many times before), the conversation drifted on to a more generic discussion on software and bugs. I found myself trying to impress upon them the difficulty of building bug-free software. Now this was easy and I felt confident I could convince them because I had Bill Gates on my side. That's right, Bill Gates of Microsoft. It so happened that around the same time as this trade show, Bill Gates was demo'ing Windows 98 at COMDEX, introducing it to the whole world for the first time. And it crashed and burned in the middle of the demo! An embarrassed Gates mumbled something about needing to iron out some more bugs. I mentioned this incident to my suits. Some of them had read about it in the papers. I told them Microsoft had 2000 very bright engineers working on Windows 98 and asked rhetorically why they still couldn't guarantee bug-free code. The software we were building and demo'ing was incredibly complex large-scale, real-time, network monitoring and control systems with hardware interfaces to receive 100s of thousands of data points, and heavy-duty number crunching in mission-critical, high-availability systems. I reminded them that we had just 3 engineers working on the portion of the demo that crashed. The point was that if Microsoft, with its huge army of the world's best developers, cannot produce bug-free software, how could we, with far fewer resources to build equally complex systems, produce anything better? The suits seemed to see the point. By the end of the night I had totally convinced them that software is, by nature, very complex and it was virtually impossible to build systems of better quality than Windows. One had to just live with the fact that software systems will malfunction and crash periodically. Thanks Bill!

That was 10 years ago. Windows has come a long way since those days and we now see less of the infamous "blue screen of death". Software in general has matured more in the last decade. However, we are nowhere close to the level of maturity in commercial software where high quality is taken for granted. Any enterprise-scale software is fraught with bugs requiring continuous application of hot-fixes, patches, upgrades etc. Ask any IT professional in any company about the quality of software he supports and invariably you will hear complaints. Complaints are likely to be more vociferous when it comes to business applications software.

So why does software quality in general and business applications software in particular suck so badly? Why is it that software is not as reliable as (say) bridges? Some would argue that the software industry is still very new. After all, they argue, we've been building software for less than 50 years while we've been building bridges for 1000s of years. Others would argue that software is much more complex than building bridges or cars, and as complexity increases, so does the probability of defects. There are some who would point to lack of standardization in the way certain common software elements are built resulting in defects when trying to integrate elements into one application. Then there is the camp that feels that a significant number of software engineers lack the proper training and skills and that the software industry is probably the only industry where we don't make a distinction between technicians and engineers (think of electrician versus electrical engineer, plumber versus civil engineer etc.) - in software, anyone who works with code is a software engineer and problems arise when technicians try to do the job of engineers.

While all of the above reasons may be valid, I believe the fundamental reason for poor software quality is the way we build it. This is more true for applications software than systems software. In spite of all the advances in languages, IDEs, design patterns, open-source libraries, runtimes and standards, building large applications software remains horrendously tedious, labor intensive and error prone. I think we need a radical shift in the fundamental mechanics of writing code in a programming language. We need a new vocabulary for application developers to state their business logic rather than code it. Modeling tools have attempted to address some basic part of this but have been very code and programming oriented e.g. thinking in terms of classes in UML. Model Driven Architectures (MDA) never lived up to the hype and simply provide a language to describe the high-level problem without providing a real-life solution.

I have no idea what this new vocabulary and mechanics for building software would look like in its final form (although I have a name for it - Yeti), but it seems to me intuitively that it will have the following characteristics:
  • Rules would figure in it prominently, and application building will primarily involve describing business rules
  • Application logic would be expressed in a natural language syntax
  • Application builders would not be programming (as we know it) in languages such as Java, C++ or JavaScript
  • Applications would be able to process incomplete information employing fuzzy logic, and learning

Maybe I'll never see Yeti in my lifetime. Maybe Yeti simple cannot exist given the basic von Neumann model for computers.
Or maybe not.