ECMAScript 4 Object Initializers and Type Annotations
My previous post was about ECMAScript 4 object initializers and fixtures. In this post, I'm going to talk about another new feature of ECMAScript 4 object initializers: type annotations. That's right, in ES4 you'll be able to place type annotations on object initializers. To recap, an object initializer, a.k.a. an object literal, is often used in ActionScript 3 instead of the new operator to create an instance of the Object class. For example:
var techWriter:Object = {fname:"Francis", lname:"Cheng", company:"Adobe"};
In ActionScript 3.0, you can use object initializers exclusively with the Object class. Once this new feature of ES4 gets rolled in to ActionScript, however, you will be able to use object initializers with other classes. Here's how it will probably work: place a type annotation after the closing curly brace. Let's say I have a simple class named Employee:
class Employee {
var fname;
var lname;
var company;
}
With ECMASCript 4, I'll be able to create an instance of Employee using an object initializer:
// ECMAScript 4th Edition code
var techWriter:Employee = {fname:"Francis", lname:"Cheng", company:"Adobe"}:Employee;
One thing to keep in mind is that this will only work if all the fields of the object literal are of the form "fieldName:value". So what's the point of including this capability? The rationale comes from the idea of "evolutionary programming", which refers to the idea of moving from a more informal, scripting-based way of programming to a more structured and formal way of programming. Say you start with a simple script that provides rudimentary interactivity on your web page. As time goes by, you may decide to add more features to the script. At some point, you may find that the script is getting so complex that some formal structure would help. The idea of evolutionary programming is that the language should help you transition from the informal style to the formal style.
Type annotations on object initializers is an example of a feature that facilitates the transition from informal to formal programming style. In the example above, you can see how I moved from using a simple instance of the Object class to the more formal structure of an Employee class. Another feature that helps with this type of transitional programming is structural types, which allows you to create an simple type without creating a class. To give you a better sense of what evolutionary programming means, let's step through the transition again, but this time with a structural type thrown into the mix.
First, I start with an instance of the generic Object class:
var techWriter:Object = {fname:"Francis", lname:"Cheng", company:"Adobe"};
Second, I decide to get a little more formal by creating a structural type to represent employees:
// ES4 structural type definition
type Employee = {fname:String, lname:String, company:String}
Third, I can now create instances of the Employee type with an object initializer or with the new operator:
// ES4 object initializer
var techWriter:Employee = {fname:"Francis", lname:"Cheng", company:"Adobe"}:Employee;
// ES4 new operator can be used with structural types
var techWriter2:Employee = new Employee("Francis", "Cheng", "Adobe")
Finally, I can replace the structural type with a class:
class Employee {
var fname;
var lname;
var company;
}
So both structural types and type annotations on object initializers provide flexibility in the transition from using plain Object instances to instances of a class. For example, after I define the Employee class, there's no need for me to rewrite the instantiation code I wrote in step three because the code works for both the structural type and the class.
Here's a list of relevant links:
Comments
Wow. That's awesome. But I don't think it's such a nice style to do this type of "evolutionary programming". Since AS3 has a Function object, could you technically make a full blown class with one line? How hard will it be to debug this stuff?
Posted by: Danny Miller | May 15, 2008 05:24 PM
Sweet! This actually allows to create new types (classes) at runtime. It should also be possible to add function declarations to the object describing the type, right? This would allow to add methods to a type. A nice use case would be dynamic, typed proxies that could be used for AOP style method interceptions. Very nice!
Posted by: Dirk Eismann | May 15, 2008 11:33 PM
Does this mean we can create classes at runtime as suggested by Dirk?
Posted by: William from Lagos | May 16, 2008 01:17 AM
This will be awesome. I just recently (and often) had a problem where I wanted to store a simple object (property list) as a property of a formal Class, but wasn't sure of final property list, and a formal class would have been overkill (and time consuming to create - and I honestly just didn't feel like creating it).
This is great because I could simply define the type inline in my class, and then adjust it as needed during development - which is sort of exactly what I do now - only I'd be able to more robustly flush out the types of the properties of that defined type, and be able to rely on more robust constraints on the properties (that was not specifically mentioned in your post as an advantage, I'm inferring that from the code snippet).
Very cool stuff. I can't wait for ES4.
Posted by: Kevin N. | May 16, 2008 08:56 AM
Danny: I believe that you will be able to include a field that contains a reference to a Function object, but that wouldn't necessarily make it a "full blown class", as you call it. All types in ES4 will have an associated runtime meta-object that describes that type. Using a structural type as you suggest would create a RecordType, whereas using the 'class' keyword would create a ClassType. In some respects their behavior is identical, but there are differences between the two that are outlined on the ecmascript.org wiki. As for debugging, part of the rationale for transitioning to a more formal programming style is that mistakes are caught earlier, so I think the hope is that debugging will generally get easier as you move more toward formal classes.
DirK and William: I could be mistaken, but I think that's what Danny was talking about: adding a field that is typed as a function to a structural type definition. I think that may be possible, but I don't think it will be exactly the same as declaring a class, for the reason I mention above. You may be able to instantiate it as you would with a class definition, but there may be differences in terms of method binding and enumerability. I don't think all of these details have been thoroughly specified, so I'm hoping these issues will all become clear (to me) as we move closer to finalization of the spec.
Thanks for the comments and questions, they definitely help me understand these issues better.
Posted by: Francis Cheng | May 16, 2008 12:32 PM