Home  >  Development  >  features

The Charges Against ActionScript 3.0

AddThis Social Bookmark Button

Note: this article continues the discussion started by Colin's earlier Inside RIA article, ActionScript 3.0: Is it Hard or Not?

Actionscript 3

Adobe has made some impressive progress transitioning Flash from plug-in to platform over the past couple of years. The foundation is now in place: there's a proper programming tool (Flex Builder), a desktop runtime (AIR), and a mature language (ActionScript 3.0). Adobe is even working on its own line of killer apps—a prerequisite for any platform. Photoshop Express, Buzzword, and AMP are already live, with surely more to come. Meanwhile, Flash Player's evolution continues at a dizzying pace. Astro, a.k.a. Flash Player 10, is set to introduce basic 3D, high-performance graphics effects, dynamic sound generation, and a new text engine that supports right-to-left and vertical text layout. (And there was much rejoicing.)

But despite all the talk of GPU blitting, pixel shading, and ligatures, a non-negligible percentage of the Flash community is rightfully asking: is Adobe still committed to the simple, agile authoring practices on which Flash was founded? It's a rational enough concern. After all, Flash built its success on "ease of use." Some 11 years ago, the tagline on the Flash 2 box read: "The Easiest Way to Create Fast Web Multimedia." Originally, Flash was purpose-built for people who wanted to make things move without years of animation training, or who wanted to create interactivity and programmatic behavior without a degree in computer science. A decade of loyalty later, those same people—call them the "everyday Flashers"—are now wondering how, or even if, they fit into Adobe's new platform strategy.

Although the general concern over Flash's ease of use is natural, much of it is based on fear, not facts. Despite doomsday predictions that Adobe is abandoning its core Flash user base my impression is that Adobe thinks very highly of the "everyday Flashers." In fact, if the new tweening model and inverse kinematics support in Flash are any indication, Adobe's Flash team seems thoroughly committed to improving content-creation workflows. Approachable authoring experiences, however, take time to develop and refine in the context of new features. In fact, for some kinds of content, the most approachable authoring experience might one day have nothing to do with the Flash authoring tool. As the Flash platform evolves, it seems logical to expect a variety of content-specific authoring tools to emerge, from both Adobe and third parties. Adobe is already developing at least one such tool for the Flash platform, codenamed Thermo.

But for now, huge numbers of Flashers still have to get their work done in the Flash authoring tool as it stands today, taking the good with the bad. More than a year has passed since Flash CS3 was released to widely positive reviews, but many Flash users are still frustrated by some of the workflow changes introduced by ActionScript 3.0. The truly problematic changes are relatively few, but together they have a deep effect on the typical Flash user's daily job.

In the spirit of working toward solutions, and of giving a formal voice to the collective grumbling of everyday Flashers, this article provides a guide to The Charges Against ActionScript 3.0. The list of accusations follows; mostly it applies to the Flash authoring tool, not to Flex Builder.

  1. The removal of on()/onClipEvent() from Flash CS3 makes creating simple interactivity hard.
  2. Getting rid of loaded .swf files is hard.
  3. Casting DisplayObject.parent makes controlling parent movie clips hard.
  4. The removal of getURL() makes linking hard.
  5. The removal of loadMovie() makes loading .swf files and images hard.
  6. ActionScript 3.0's additional errors make coding cumbersome.
  7. Referring to library symbols dynamically is unintuitive.
  8. Adding custom functionality to manually created text fields, to all movie clips, or to all buttons is cumbersome.
  9. The removal of duplicateMovieClip() makes cloning a MovieClip instance (really) hard.

Note that the title of this article, "The Charges Against ActionScript 3.0," is something of a misnomer. In many cases, ActionScript 3.0 as a language is accused of crimes it has never committed. Many of the problems in the preceding list are best solved not at the language level, but at the tool level. For example, the ActionScript 3.0 navigateToURL() function is clearly an improvement over its predecessor, getURL(), but navigateToURL() is also more difficult for nonprogrammers to use. The solution is not to revert to the inferior getURL(), but rather to provide an easier workflow in Flash for adding hypertext links to buttons. A new "link" tool could provide a Flash 4-style menu interface for creating links while completely obscuring the underlying ActionScript 3.0 code. Or maybe the time has come for someone to make an entirely new application for building simple Flash websites and animations. Such a tool could even be written in ActionScript, and deployed as an AIR app. But I digress...

The following sections describe the preceding charges, their possible solutions, and suggested courses of action for both Adobe and the Flash community. If you're affected by these issues, I'd like to encourage you to take the actions suggested. Also feel free to add to this discussion by leaving a comment below. With any luck, collectively we might be able to affect Adobe's future decision making.

For the record, I should point out that despite the issues discussed in this article in my opinion ActionScript 3.0 is vastly superior to ActionScript 2.0 and ActionScript 1.0. Growing pains aside, ActionScript 3.0 is the language of choice for any Flash-platform project. Now, on to the charges.

Charge #1: The Removal of on()/onClipEvent() from Flash CS3 Makes Creating Simple Interactivity Hard

The Accused: Flash CS3
The Verdict: GUILTY

Before the release of Flash CS3, you could add interactivity to movie clips and buttons using the on()/onClipEvent() visual-coding system. For example, imagine an animation whose final frame has a Replay button. When the button is clicked, its parent timeline starts playing at frame 1. In Flash 8, here are the steps you'd follow to implement the Replay button's functionality:

  1. Select the button.
  2. Enter the following code into the Actions panel:
    on (release) {
        this._parent.gotoAndPlay(1);
      }

In Flash CS3, in an ActionScript 3.0 .fla file, here are the equivalent steps:

  1. Assign the button an instance name, "replayBtn".
  2. Select the frame containing the button.
  3. In the Actions panel, define a function to listen to the button's MouseEvent.CLICK event:
    function replayBtnClickListener (e) {
       gotoAndPlay(1);
    }
  4. Still in the Actions panel, register replayBtnClickListener for the button's MouseEvent.CLICK event:
    replayBtn.addEventListener(MouseEvent.CLICK, replayBtnClickListener);

The Flash CS3 approach makes development harder for inexperienced programmers in four different ways. First, it requires an understanding of function creation and function references. Second, it uses a more complicated event name for the mouse click ("MouseEvent.CLICK" versus "release"). Third, in the Flash 8 scenario, the button can be moved or copied from one place to another while retaining its code; in Flash CS3, the button and code have to be moved separately. Fourth, the on() approach creates a listener and automatically registers that listener in one phrase of code, whereas the ActionScript 3.0 approach separates the listener creation and registration. To be fair, ActionScript 3.0 actually also supports inline listener creation and registration:

replayBtn.addEventListener(MouseEvent.CLICK, function (e) {
   gotoAndPlay(1);
});

But ActionScript 3.0's inline syntax is less intuitive, is more prone to error, and leaves the program with no reference to the listener.

The preceding four issues are not trivial. Flash CS3 is sorely lacking a reliable, clean, visual system for assigning interactive behavior to graphical assets on stage. Nevertheless, I don't think that on() and onClipEvent() should be reintroduced. Here's why: first, although they are convenient and easy to understand, excessive use of on()/onClipEvent() can easily lead to a messy, unmaintainable .fla file. Second, on()/onClipEvent() introduces its own syntax for event handling, which complicates the language needlessly. Third, on()/onClipEvent() doesn't even do a good job at providing an "easy-to-use" tool for creating interactivity. To use on()/onClipEvent(), the Flash user still needs to learn the on() syntax itself, and has to remember (or look up) the available events ("press", "release", etc.).

But if resurrecting on()/onClipEvent() isn't the right thing to do, what is?

What Should Adobe Do?

Adobe should reintroduce a visual system for producing interactivity—but should modernize it. Get it right this time. Make a system that's even more helpful for nonprogrammers than on()/onClipEvent(). Make it write real ActionScript 3.0 behind the scenes, and let users move objects and behavior together (or choose not to, at their discretion). Here's just one idea: if a user clicks on a button, give her a list of supported events in a pull-down menu. Let the user choose the event and provide the "response" by selecting from a group of actions (go to URL, stop timeline, etc.). At compile time, change the response code to real ActionScript 3.0 code in the button's container class. And let the user see that code at author time via a central code viewer for all buttons in the .fla file, with the option to navigate to individual buttons.

Regardless of the actual interface, the Flash authoring tool needs its visual-coding system back. I firmly reject the notion that because ActionScript is becoming more powerful we should all "grow up" and learn to use MouseEvent.CLICK and event listeners. Such nonsense is programming egotism. What we should all do is use the right tool for the job. Simple content should be easy to build.

Does Adobe agree? At the grass-roots level, definitely. The Flash authoring team is very much in touch with their users, and the on()/onClipEvent() issue is well known internally. In February 2008, I met with Richard Galvan (the Flash authoring tool product manager), and he assured me that the topic of visual coding is considered significant. Unfortunately, "doing things right" takes time. Reviving on()/onClipEvent() in its old, insufficient form would be comparatively easy. But conceiving of, implementing, and testing a new and improved ActionScript 3.0 approach isn't trivial. Mr. Galvan couldn't commit to any time frame for an improved on()/onClipEvent() feature, but we both agreed that Adobe ought to build one. Hopefully, he'll be able to help convert that intention into action within the next version or two of Flash.

What Should We Do?

As a community, we'll need some patience while Flash evolves. Flash Player might be at version 9, but as a whole, the "Flash platform" is realistically only at version 1. During the Flash Player 9 time frame, Adobe released ActionScript 3.0, Flex 2.0, and AIR 1.0. That's a lot of new technology. Things will improve over time, particularly if the community voices its needs strongly. If you want your buttons back, post a comment at the end of this article. Adobe has a history of listening to sincere petitions for improvements in Flash (see the MovieClipLoader, Failure to Unload, and Make Some Noise campaigns).

In the meantime, I'm looking forward to Thermo, which will have a visual coding system. Mr. Galvan pointed out that Flash will naturally be in a good position to learn from Thermo's successes and failures, so it's worth giving feedback on that product even if you don't intend to use it regularly. And remember to keep an eye on labs.adobe.com, where Adobe previews its new tools.

Charge #2: Getting Rid of Loaded .swf Files Is Hard

The Accused: ActionScript 3.0
The Verdict: GUILTY

Prior to ActionScript 3.0, when a parent .swf file loaded a child .swf file, it could subsequently remove that child by calling removeMovieClip(). Calling removeMovieClip() stopped the child's events and play heads, which typically allowed it to be purged from memory (i.e., garbage-collected). In Flash Player 9, there is no removeMovieClip() equivalent. Instead, to remove an .swf file from memory in Flash Player 9, the programmer must manually deactivate and dereference it, ensuring that:

  • The parent .swf file has no references to the child .swf.
  • Flash Player has no references to the child .swf.

A parent .swf file can, of course, remove its own references to the child, but it cannot guarantee that 1) the child has not created a reference to itself in the parent (normally by registering a listener), and that 2) Flash Player itself has no references to the child .swf. Flash Player will hold a reference to the child if the child has registered for input or system events, or has active processes running, such as a sound playing or a file downloading. Hence, to remove a child .swf file, the programmer must follow these steps:

  1. Manually deactivate the child's active processes.
  2. Manually remove the child's system and input listeners.
  3. Manually dereference the child.

Although nice in theory, the manual approach poses several practical problems:

  • Manual deactivation of the child (i.e., removing its event listeners, stopping sounds, stopping timelines and timers, closing network operations, etc.) can be a lot of work, adding complexity and development time to a project.
  • Manual deactivation of the child is error-prone because the child might have dozens or hundreds of active input-event listeners, network connections, animations, and timers to track and disable. If the programmer forgets to unregister just one Event.ENTER_FRAME listener, the child .swf will never be purged from memory.
  • Adobe currently does not publish an authoritative list of things to deactivate before a child .swf can be purged, so developers are often left guessing when their content fails to be removed from memory.
  • Parent .swf files that load child .swf files from third-party sources cannot guarantee that the third-party child will deactivate itself properly. Hence, building applications and sites that aggregate third-party content is hazardous in Flash Player 9.

What Should Adobe Do?

In the short term, Adobe needs to:

  • Publish a list of everything that needs deactivation in a loaded .swf file before that .swf can be purged from memory. Until such a list is published, I'll maintain one on my blog—but my list is, by definition, insufficient because it is neither official nor exhaustive.
  • Update the ActionScript Language Reference, adding a warning to every item in the API that requires deactivation when used in a loaded .swf. For example, under Sound.play(), Adobe should add this warning: "An .swf file that starts a sound cannot become eligible for garbage collection until that sound has stopped playing."
  • Institute an internal documentation procedure guaranteeing that the preceding two publications are kept up-to-date as new features are added to each Flash runtime.

In the long term, Adobe needs to invest the engineering resources required to develop an API for deactivating a child .swf, and perhaps also for brute-force purging of a child .swf from memory. Such an API will be hard to get right and hard to maintain, but I think it's required if Flash is to retain its status as an agile, approachable platform. Flash's current success is partly based on its low barrier of entry for content creators. Presumably, then, adding helpful tools that keep the platform approachable is worth the effort.

Fortunately, thanks in part to the efforts of Grant Skinner, who recently championed the need for better unloading, Adobe is already actively exploring the issue of display-object deactivation and garbage collection. Flash Player 10 beta already includes a fix for a serious garbage collection bug reported by Mr. Skinner (.swf files with timeline code can't be garbage-collected). Flash Player 10 beta also provides a direct API for requesting garbage collection, in both the debug and release versions. Further, according to Flash Player engineer Werner Sharp, Adobe is investigating whether it's feasible to add two new deactivation features in future Flash runtimes:

  • A general deactivation method for halting a child .swf file's active processes. This feature has partly already come to fruition; see unloadAndStop() in Flash Player 10's release notes and the additional information provided by Mr. Skinner.
  • An API for loading an .swf file into a "content sandbox" (a term originally proposed by Mr. Skinner). When loaded into a content sandbox, the child .swf would be prevented from accessing both its parent and the stage, thus preventing the child from creating references that would prevent it from being garbage-collected.

Together, the preceding two experimental features would drastically reduce the effort required to manually purge a loaded child from memory.

In addition to the changes already being explored, I'd like to see Adobe bring back the ability to completely remove all content from Flash Player before loading a new .swf file. That is, ActionScript 3.0 needs an equivalent for this ActionScript 2.0 code:

loadMovieNum("newContent.swf", 0);

For more thoughts on deactivating and purging loaded content from Flash Player, see the following resources:

What Should We Do?

Until an .swf-deactivation API becomes part of Flash Player, developers creating loaded content should:

  • Learn to know and love the .swf deactivation list. Every child .swf file should supply a custom-made deactivate() method that must be called before the parent dereferences that child.
  • Consider loading .swf files from a separate subdomain so that their parent and stage access is limited (thanks to Mr. Skinner for recommending this technique).
  • Use Flex Builder 3's profiler tool to track every application's object usage, memory consumption, and performance.

Charge #3: Casting DisplayObject.parent Makes Controlling Parent Movie Clips Hard

The Accused: Flash CS3
The Verdict: GUILTY

Since movie clips were introduced in Flash 3, child movie clips have been able to control their parent timelines. For example, the original "actions" required to play a parent timeline looked like this:

Begin Tell Target ("../")
  Play
End Tell Target

In Flash 5, those actions were replaced by object-oriented code that looked like this:

this._parent.play();

In Flash CS3, the underscore was removed from "_parent", so the code now looks like this:

this.parent.play();

However, if you try that code in Flash CS3, you'll get this error:

1061: Call to a possibly undefined method gotoAndStop through a reference
 with static type flash.display:DisplayObjectContainer.

Why? Because the datatype of the "parent" variable is DisplayObjectContainer, not MovieClip. To make the code work, this.parent must be cast to the MovieClip datatype, as follows:

MovieClip(this.parent).play();

The preceding error message and its resolution are perfectly logical to computer scientists—but completely confounding to most animators. Ironically, it is the animators, not the programmers, who typically need to control timelines. Flash 3 let nonprogrammers control parent timelines with ease. Flash CS3 broke that long-standing tradition. Something has to be done. Animators want their easy timeline control back.

What Should Adobe Do?

At the very least, Adobe should enhance the Flash compiler so that it inserts an automatically generated cast wherever feasible, allowing error-free access to a parent's variables and functions. Here's how the automatic insertion could work:

  • First, check whether all author-time instances of a given symbol have the same type of parent; if so, cast to that parent's class wherever necessary
  • For symbols whose instances have incompatible types of parents, wherever irresolvable references to parent functions or variables are made, generate a nice, nonprogrammer-readable error.
  • If the programmer uses a manual cast, honor that cast instead of attempting to insert one automatically.

In the future, Adobe should also consider adding GUI tools for assigning common behaviors to both parent and child movie clips. The current Script Assist feature is too cluttered to be useful for simple interactions.

Of course, it's easy to ask Adobe to "add GUI tools for creating simple interactions," but it's hard to actually design and implement them. Making the right GUI tools available to the right audience in the right contexts is something of a software-industry Holy Grail. And it's not as though the Flash team hasn't clearly tried to add nonprogrammer tools before (see normal mode, designer view, slides, and behaviors). But I think there's still room to explore.

What Should We Do?

Submit the following Flash feature request via Adobe's wish form:

    Product Name: Flash
    Product Version: CS4
    Request: Easy Parent Timeline Control

On a movie clip timeline, please allow error-free access to the parent's variables and functions by adding an automatic cast wherever feasible.

You might also want to leave a comment on Richard Galvan's blog.

As a brute-force workaround to the parent casting issue, developers can consider turning off strict error-checking mode by unchecking Strict Mode, under File→Publish Settings→Flash→ActionScript 3.0 Settings→Errors. Note, however, that disabling strict mode also suppresses all compile-time type checking, and is not recommended for projects with nontrivial code.

Charge #4: The Removal of getURL() Makes Linking Hard

The Accused: ActionScript 3.0, Flash CS3
The Verdict: ActionScript 3.0, NOT GUILTY; Flash CS3, GUILTY

In ActionScript 1.0 and 2.0, the code required to make a link to http://www.oreilly.com looked like this:

getURL("http://www.oreilly.com");
In ActionScript 3.0, the equivalent code looks like this:
navigateToURL(new URLRequest("http://www.oreilly.com"));

The ActionScript 3.0 code is a little more verbose, but it also provides more features and has a cleaner API for sending variables to the destination URL. Nevertheless, some developers miss the convenience of getURL(). Fortunately for them, it's easy to re-create getURL() with a little custom code. Example 1 shows how. It contains an ActionScript 3.0 getURL()-equivalent function for loading a URL into a browser. Note, however, that unlike the real getURL(), Example 1's version does not support sending a movie clip's timeline variables to a server-side application. If you need to send variables to a server in ActionScript 3.0, you should use navigateToURL()'s much cleaner variable-sending API.

Example 1: An ActionScript 3.0 getURL()-Equivalent Function

package {
   import flash.net.*;
 
   public function getURL (url:String, 
                           window:String = "_self"):void {
      var u:URLRequest = new URLRequest(url);
      navigateToURL(u, window);
    }
}

To use the preceding getURL() replacement, copy the code into a file named "getURL.as" and then place that file in the root of your program's classpath. If you're not familiar with the classpath, just place getURL.as in the same directory as your .fla file (Flash CS3) or in your main source directory (Flex Builder). Once the file is in place, you can use getURL() like this:

getURL("http://www.oreilly.com");
getURL("http://www.oreilly.com", "_blank");

What Should Adobe Do?

From a language perspective, Adobe has done the right thing already. ActionScript 3.0's navigateToURL() function is cleaner than the legacy getURL(), and it provides more features. However, from a tool perspective, there's work to be done. For the benefit of newer programmers and nonprogrammers, future versions of Flash authoring should provide a simplified GUI for creating hypertext links in Flash content.

What Should We Do?

Programmers: learn to use navigateToURL(), particularly when sending variables. Some keystroke-frugal coders will want to use a simple pass-through function such as the one shown in Example 1.

Nonprogrammers: wait for Adobe to introduce new workflows for creating simple interactivity. Tell Adobe you want easy-to-use linking tools by submitting the following Flash feature request via Adobe's wish form:

    Product Name: Flash
    Product Version: CS4
    Request: Easy Links

Please make an easy-to-use tool for creating hypertext links. The current navigateToURL() function is too hard to use.

Charge #5: The Removal of loadMovie() Makes Loading .swf Files and Images Hard

The Accused: ActionScript 3.0
The Verdict: GUILTY (but there's a workaround)

In ActionScript 1.0 and 2.0, the code required to load a file named "animation.swf" into a movie clip looked like this:

theClip.loadMovie("animation.swf");

In ActionScript 3.0, there is no direct way to load an .swf file into an existing movie clip. Instead, the file must be loaded by a Loader object, and then added to a parent movie clip (or any other DisplayObjectContainer object). The code looks like this:

var l:Loader = new Loader();
l.load(new URLRequest("animation.swf"));
theParent.addChild(l);

The ActionScript 3.0 code is more consistent with the rest of the ActionScript 3.0 API, and it offers more control over the load operation, security, and loading events. Nevertheless, many developers miss the convenience of loadMovie(). Fortunately for them, it's possible to create a loadMovie() equivalent with a little custom code. Example 2 defines a custom function, loadChildAsset(), that offers most of the convenience of ActionScript 1.0/2.0 loadMovie() function. Note, however, that loadChildAsset() is not exactly the same as the original loadMovie(); instead of replacing the target, it makes the loaded asset's Loader object a new child of the specified parent. The loadChildAsset() function also returns a Loader object through which the load operation can be halted. Finally, loadChildAsset() can be passed listener functions for handling load events such as Event.COMPLETE and ProgressEvent.PROGRESS. (Note that as with any load operation, developers should not access the loaded asset until Event.INIT has occurred.)

Example 2: The loadChildAsset() Function

package {
   import flash.display.*;
   import flash.events.*;
   import flash.net.*;
   
   public function loadChildAsset (parent:DisplayObjectContainer,
                                   url:String,
                                   completeListener:Function = null,
                                   initListener:Function = null,
                                   progressListener:Function = null,
                                   ioErrorListener:Function = null,
                                   method:String=null
                                   ):Loader {
      // Create the Loader and URLRequest objects
      var l:Loader = new Loader();
      var u:URLRequest = new URLRequest(url);
      u.method = method ? method : URLRequestMethod.GET;
  
      // Add the Loader object to the parent 
      parent.addChild(l);
      
      // Output a warning for any error messages
      l.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, 
        function (e:IOErrorEvent):void {
           trace("Loading error: " + e);
         });
  
      // Register any supplied event listeners
      if (completeListener != null) {
         l.contentLoaderInfo.addEventListener(Event.COMPLETE, 
                                              completeListener);
       }
    
      if (initListener != null) {
         l.contentLoaderInfo.addEventListener(Event.INIT, initListener);
       }
  
      if (progressListener != null) {
         l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, 
                                              progressListener);
       }
  
      if (ioErrorListener != null) {
         l.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,
                                              ioErrorListener);
       }
  
      // Start the load operation
      l.load(u);
      
      // Pass the Loader object reference to the caller so the caller
      // can stop the load operation if desired
      return l;
    }
}

To use the preceding loadChildAsset() function, copy the code into a file named "loadChildAsset.as" and then place that file in the root of your program's classpath. Here's how you can use loadChildAsset() in a timeline script to load a file named "animation.swf" as a child of the current movie clip:

// Load a movie as a child of the current movie clip
loadChildAsset(this, "animation.swf");

Here's how you can use loadChildAsset() in a class file with listener functions for responding to load events:

package {
   import flash.display.*;
   import flash.events.*;
   import flash.net.*;
 
   public class SomeApplication extends Sprite {
      public function SomeApplication () {
         loadChildAsset(this, 
                        "child.swf", 
                        childCompleteListener,
                        childInitListener,
                        childProgressListener,
                        childIoErrorListener);
       }
      
      public function childCompleteListener (e:Event):void {
         trace("The file finished loading.");
       }
      
      public function childInitListener (e:Event):void {
         trace("The file has been initialized.");
       }
      
      public function childProgressListener (e:ProgressEvent):void {
         trace("Part of the file loaded.");
       }
      
      public function childIoErrorListener (e:IOErrorEvent):void {
         trace("The file could not be loaded.");
       }
    }
}

What Should Adobe Do?

In creating ActionScript 3.0, Adobe purged the language of its many inconsistencies and limitations, and established a cleaner, more feature-rich API. But in some specific cases, Adobe also purged the language of popular, easy-to-use tools such as loadMovie(). Over time, Adobe should carefully and selectively strive to reintroduce equivalents for those tools.

What Should We Do?

For now, developers looking for convenient .swf-loading tools will have to create and share custom functions, such as Example 2's loadChildAsset(). The best ideas from the community should eventually be integrated into the core Flash runtime APIs.

Charge #6: ActionScript 3.0's Additional Errors Make Coding Cumbersome

The Accused: ActionScript 3.0
The Verdict: NOT GUILTY

ActionScript 1.0 and 2.0 were notorious for their lack of runtime errors and runtime datatype checking. Trivial datatype errors went unreported at runtime, forcing programmers to manually diagnose even routine problems such as misspelled variable names and missing function arguments. ActionScript 2.0 thankfully introduced datatype checking at compile time, but continued to let datatype errors go unreported for dynamically typed variables, parameters, and return values (all of which are commonly found in small scripts and rapid prototypes).

For example, consider the following erroneous ActionScript 2.0 code. It mistakenly uses the variable name "tex" instead of "text" when attempting to display some text on-screen.

someClip.createTextField("t",0, 0, 0, 100, 100);
someClip.t.tex = "Hello world";  // Oops! Should be "text" not "tex"

When the code runs, ActionScript 2.0 does not generate an error. Instead, ActionScript 2.0 creates a new variable named "tex" on the TextField object, and assigns it the value "Hello world". As a result, the programmer is effectively stranded. No text has appeared on-screen, and there's no error explaining what went wrong. The program might have a serious logical failure or a simple typographical mistake; the programmer has no way of knowing for sure without painstakingly examining the code line by line. ActionScript 3.0, by contrast, is very vocal about errors. It dutifully informs the programmer when it cannot execute some code. For example, consider the ActionScript 3.0 equivalent of the preceding erroneous code:

var t = new TextField();
t.tex = "Hello world";

In ActionScript 3.0, the TextField class is not dynamic, so when the code runs, ActionScript 3.0 generates the following error:

ReferenceError: Error #1056: Cannot create property tex on flash.text.TextField.
    at Test()[c:\data\someProject\src\Main.as:10]

The error not only describes what went wrong ("Cannot create property tex"), but also indicates exactly where the program failed (line 10 of Main.as). As a result, the programmer can fix the error in a matter of seconds. ActionScript 3.0 reports all datatype errors, both at compile time and at runtime, so programmers can focus on logic rather than wasting time on typographical mistakes.

What Should Adobe Do?

Adobe has already done the right thing by increasing the number of errors reported by ActionScript. Now the company needs to focus on making the errors more readable for average programmers. Many ActionScript errors are too generic, or too filled with ECMAScript-specification jargon. Furthermore, the short error explanations provided in the documentation are insufficient. For example, consider the following error message from the preceding section:

Cannot create property tex on flash.text.TextField.

The message is technically correct, but it focuses on the runtime's point of failure rather than the programmer's probable intention. The error effectively says to the programmer, "You're trying to create a dynamic instance variable on a TextField object, but that's not possible because the TextField class isn't dynamic." The focus of the error message implies that the appropriate solution is to make the TextField class dynamic, thus allowing "tex" to be legally created. Of course, the programmer isn't trying to create a dynamic instance variable. The programmer simply supplied the wrong variable name for "text". The runtime should be smarter in this situation. It should account for the mistaken-variable-name case, as shown in the following potential rewrite of the error message:

Cannot assign 'Hello world' to variable 'tex' on an object of type
flash.text.TextField. Variable 'tex' does not exist and cannot be dynamically 
created because TextField is sealed. See http://www.adobe.com/go/aserror1056.

The hypothetical linked page in the preceding error message would describe the problem in more detail, and give examples of typical causes and fixes for the error. Here are a few more examples of errors that are too arcane:

  • 1061 Call to a possibly undefined method %s through a reference with static type %s.
  • 1118 Implicit coercion of a value with static type %s to a possibly unrelated type %s.
  • 1119 Access of possibly undefined property %s through a reference with static type %s.
  • 1151 A conflict exists with definition %s in namespace %s.

What Should We Do?

As developers, we should all learn to love errors. Error messages are a programmer's best friend. They don't waste time, they save it. They're not trying to be frustrating; they're trying to be helpful.

Programmers who feel intimidated or frustrated by ActionScript 3.0's new errors should consider the following analogy: suppose you're getting off a train and the person next to you notices that you left your hat behind. Would you want that person to tell you that you forgot your hat and show you where to retrieve it? Or would you prefer to start searching for your hat only once you realized it went missing? ActionScript 3.0 would tell you about your hat; ActionScript 2.0 wouldn't. (Of course, until Adobe improves its error messages, ActionScript 3.0 might appear to be screaming at you in ancient Latin, but at least you know something's wrong.)

Error messages are a natural, routine, healthy part of programming. They help you fix the obvious errors in your code so that you have more time to focus on building features and diagnosing logical problems. The more error messages a language gives you, the more time you have to get your real work done. Remember, also, that ActionScript error messages appear in the debugger versions of Flash runtimes only. The general public won't see them.

For help deciphering ActionScript 3.0's error messages, see Adobe's compiler error reference.

Charge #7: Referring to Library Symbols Dynamically Is Unintuitive

The Accused: ActionScript 3.0
The Verdict: GUILTY

Imagine you're a Flash user who has created an .fla file with 10 movie clip symbols, named "Animation0" through "Animation9". You want to display an instance of all 10 symbols at runtime. In ActionScript 1.0 and 2.0, the code you would use to create the instances would look like this (note that, for brevity, the code does not use type annotations):

for (var i = 0; i < 10; i++) {
   parentClip.attachMovie("Animation" + i, "instance" + i, i);
}

The equivalent ActionScript 3.0 code looks like this (again, type annotations have been omitted for brevity):

var Symbol; 
for (var i = 0; i < 10; i++) {
   Symbol = getDefinitionByName("Animation" + i);
   parentClip.addChild(new Symbol());
}

The ActionScript 3.0 code has several benefits over the ActionScript 1.0/2.0 version. The first is API consistency: the code for dynamically referencing a symbol is exactly the same as the code for dynamically referring to a class. Second, no instance name is required; child movie clips do not need instance names because they are normally accessed by reference. Third, no depth is required; ActionScript 3.0's depth management system automatically creates depths for objects on the display list. Nevertheless, for typical Flash users the ActionScript 3.0 version of the code is less intuitive than the ActionScript 2.0 version. The ActionScript 2.0 version uses the terminology of the Flash authoring tool, which is familiar to Flash users. It says, "Add a new 'Animation0' movie instance to parentClip." The ActionScript 3.0 code uses the terminology of formal object-oriented programming, which is unfamiliar to many Flash users. It says, "Give me a reference to the class named ‘Animation0,’ create a new object from that reference, and make that object a child of parentClip." For many Flash users, when it comes to dynamically referencing a symbol ActionScript 3.0 no longer speaks their language.

Fortunately, as shown in Example 3, it's possible to create an attachMovie() equivalent with a little custom code. Example 3 defines a custom function, addChildFromLibrary(), which adds an instance of the specified symbol to the specified parent, at the specified depth (optional).

Example 3: An ActionScript 3.0 attachMovie() Equivalent

package {
   import flash.display.DisplayObjectContainer;
   import flash.display.DisplayObject;
   import flash.utils.getDefinitionByName;
 
   public function addChildFromLibrary (parent:DisplayObjectContainer,
                                        symbolName:String,
                                        depth:int = -1):DisplayObject {
      var Symbol = getDefinitionByName(symbolName);
  
      if (depth < 0) {
         return parent.addChild(new Symbol());
       } else {
         return parent.addChildAt(new Symbol(), depth);
       }
    }
}

To use the preceding addChildFromLibrary() function, copy the code into a file named "addChildFromLibrary.as" and then place that file in the root of your program's classpath. Here's how you can use addChildFromLibrary() to replace attachMovie() in the earlier "10 animation symbols" example:

for (var i = 0; i < 10; i++) {
   addChildFromLibrary(parentClip, "Animation" + i);
}

Like attachMovie(), addChildFromLibrary() uses terminology from the Flash authoring tool, and should therefore be more intuitive for Flash users.

What Should Adobe Do?

Fundamentally, Adobe made the right choice introducing symbols-as-classes in Flash CS3, and then providing a consistent way to dynamically reference both a regular class and a class linked to a symbol. However, getDefinitionByName() is not particularly approachable for less-experienced programmers. The addChildFromLibrary() function suggested in the preceding section shows at least one way to make dynamic symbol instantiation easier to understand. The question is whether Adobe should add such a function to the built-in MovieClip class. For now, I think not. Blindly adding helper functions to MovieClip could easily lead to the kind of clutter found in ActionScript 1.0 and 2.0, where MovieClip had an inconsistent variety of instantiation methods: createTextField(), createEmptyMovieClip(), attachMovie(), and duplicateMovieClip(). The MovieClip class (or, more precisely, the DisplayObjectContainer class) should not become a factory for creating all possible types of Flash content.

That said, Adobe should monitor ActionScript ease of use closely in Flash authoring and address the key Flash-centric issues carefully as the language matures. For example, to make dynamic symbol instantiation easier to understand, perhaps the Flash API should include a factory method, makeInstanceFromSymbol(), as a simple wrapper for getDefinitionByName(). The following code shows what makeInstanceFromSymbol() might look like:

// Signature
flash.utils.makeInstanceFromSymbol(symbolName:String):DisplayObject

// Implementation
public function makeInstanceFromSymbol(symbolName:String):DisplayObject {
   return new getDefinitionByName(symbolName);
}

// Example Usage:
parentClip.addChild(makeInstanceFromSymbol("Animation" + i));

The makeInstanceFromSymbol() method would give "everyday Flashers" a more familiar syntax for dynamic symbol instantiation, without introducing inconsistency into the existing display API.

Whatever Adobe eventually does to make getDefinitionByName() more approachable, it should remain frugal when considering any addition to ActionScript's APIs. Adding too many "convenience functions" leads to language bloat, which ironically could make ActionScript less intuitive, not more intuitive. By providing a strong, consistent set of low-level tools, Adobe can patiently watch the successes and failures of community code libraries, and incorporate only those features that a) truly address the needs of most Flash users, and b) cannot be solved easily or well by third parties.

What Should We Do?

Unfortunately, until Adobe adds a Flash-centric function for dynamic symbol instantiation, Flash users will have to use the existing getDefinitionByName() function, or use a custom wrapper, such as the addChildFromLibrary() or makeInstanceFromSymbol() function listed in the preceding sections.

Charge #8: Adding Custom Functionality to Manually Created Text Fields, to All Movie Clips, or to All Buttons Is Cumbersome

The Accused: Flash CS3
The Verdict: GUILTY

Flash CS3 does not provide a way to specify the class for text fields created manually in an .fla file. Manually created text fields, therefore, cannot be augmented using traditional object-oriented programming techniques.

For example, suppose you want to add a convenience method, selectAll(), to all manually created text fields in an .fla file. Ideally, you would add selectAll() to a custom class—say, EnhancedTextField—as follows:

package {
   import flash.text.TextField;
   
   public class EnhancedTextField extends TextField {
      public function selectAll ():void {
         setSelection(0, length);
       }
    }
}

Then, in the Flash authoring tool, you would specify that all text fields should be instances of your custom EnhancedTextField class. However, Flash CS3 provides no way to specify the class for manually created text fields. Your text fields must be instances of the TextField class, and cannot benefit from your selectAll() method. In a similar vein, in Flash CS3, although an individual Library symbol's class can be specified via the Linkage Properties dialog, there is no way to specify the class for an entire category of symbol.

For example, suppose you want to add a new method, flipHorizontal(), to all movie clip instances in an .fla file. Ideally, you would add flipHorizontal() to a custom class—say, FlippableMovieClip—as follows:

package {
   import flash.display.MovieClip;
 
   public class FlippableMovieClip extends MovieClip {
      public function flipHorizontal ():void {
         scaleX = -scaleX;
       }
    }
}

Then you'd specify FlippableMovieClip as the default linked class for all movie clip symbols. But Flash CS3 provides no means of specifying the default class for all movie clip symbols.

Likewise, Flash CS3 provides no way to specify a set of enhancements for all types of graphical assets (i.e., for all movie clips, all buttons, and all text fields). For example, suppose you want to add the preceding flipHorizontal() method not just to all movie clip instances, but also to all button and text field instances in an .fla file. Effectively, you want to augment the functionality of all DisplayObject instances. In theory, one way to achieve your goal is to follow these steps:

  • Create a custom helper class—say, Flipper—for flipping display objects.
  • Compose a Flipper instance into separate MovieClip, Button, and TextField subclasses.
  • Specify those subclasses as the default classes for movie clips, buttons, and text fields in your .fla file.

Here's what the custom helper class from step 1 might look like:

package {
   import flash.display.DisplayObject;
   
   public class Flipper {
      private var d:DisplayObject;
      
      public function Flipper (displayObject:DisplayObject) {
         d = displayObject;
       }
  
      public function flipHorizontal ():void {
         d.scaleX = -d.scaleX;
       }
    }
}

And here's what the MovieClip subclass from step 2 might look like:

package {
   import flash.display.MovieClip;
 
   public class FlippableMovieClip extends MovieClip {
      private var flipper:Flipper;
      
      public function FlippableMovieClip () {
         super();
         flipper = new Flipper(this);
       }
      
      public function flipHorizontal ():void {
         flipper.flipHorizontal();
       }
    }
}

You cannot actually follow the preceding theoretical procedure, however, because Flash CS3 provides no means of specifying the default class for movie clips, buttons, and text fields, so there is no way to perform step 3.

But even if Flash CS3 did provide a means of specifying the default class for movie clips, buttons, and text fields, a typical "everyday Flasher" would not have the programming experience required to write the proposed Flipper and FlippableMovieClip classes. The Flash authoring tool needs an easier way to add custom functionality to all graphical assets in an .fla file.

What Should Adobe Do?

Adobe should add the following features to the Flash authoring tool:

  • A means of specifying the class for individual manually created text fields
  • A means of specifying the default class for all manually created text fields
  • A means of specifying the default class for one symbol type (i.e., all movie clip symbols)
  • A means of centrally augmenting all displayable assets (i.e., all movie clips, buttons, and text fields)

Here are some thoughts on how to implement the preceding features:

  • For specifying the class of an individual text field, Adobe could add a new Properties panel field.
  • For specifying the default class for all text fields, or for symbol types in an .fla file, Adobe could add new fields in the ActionScript Publish Settings dialog.

For augmenting all graphical assets, Adobe could provide a central panel for specifying functions and variables to be applied to all graphical assets. The compiler could then automatically generate the appropriate ActionScript 3.0 code from the contents of that panel.

None of the preceding ideas is particularly elegant, but they provide temporary, easy-to-implement solutions and are a first step toward better linkage between graphical assets and ActionScript code.

What Should We Do?

Each code linkage issue presented in the preceding two sections has its own workaround, as follows.

Specify the class of an individual text field

Because there is no direct way to specify a text field's class, developers wishing to control a manually created text field must pass that text field to a custom helper function or to a method of a custom helper class. For example:

selectAll(someTextField)

Specify the default class for all manually created text fields

To control all text fields in an .fla file, developers can turn to an old friend, TextField.prototype, which can forcibly inject a new method into the TextField class at runtime. For example, the following code injects a custom method, flipHorizontal(), into the TextField class:

TextField.prototype.flipHorizontal = function ():void {
   this.scaleX = -this.scaleX;
};

However, because the flipHorizontal() method is unknown at compile time, invoking it causes a strict-mode compiler error. To avoid the error, developers can disable strict-mode compilation, or invoke the method dynamically, as in:

someTextField["flipHorizontal"]();

But before using TextField.prototype, all developers should heed this warning: adding a method to any class via prototype is discouraged because it changes the meaning of the class at runtime in a way that the class's users cannot predict. Furthermore, prototype-method invocations cannot be error-checked at compile time. For example, the following code, which contains a typo, generates no compile-time error:

someTextField.["fliporizontal"]();

Before the error can be detected, the program must actually reach the preceding line of code at runtime.

Specify the default class for an entire symbol type

To control all movie clips or all buttons in an .fla file, developers are advised not to use MovieClip.prototype or SimpleButton.prototype. Instead, developers should create a MovieClip or SimpleButton subclass, and specify that subclass (or one of its descendants) as the linked class for all desired symbols. Laborious, perhaps, but it guarantees compile-time type checking and it promotes clean code.

Charge #9: The Removal of duplicateMovieClip() Makes Cloning a MovieClip Instance (Really) Hard

The Accused: ActionScript 3.0
The Verdict: GUILTY

Both ActionScript 1.0 and 2.0 included a handy tool for making an exact copy of a movie clip instance: duplicateMovieClip(). The duplicateMovieClip() function was used for everything from creating mouse trailers to generating dynamic patterns and implementing "rubber stamp"-style drawing tools. Many early Flash designers and artists achieved widespread recognition for creatively exploiting duplicateMovieClip(). Among them, Robert Hodgin was my favorite. His duplicateMovieClip()-based creatures in Flight 404 v4 are still mesmerizing.

Sadly, duplicateMovieClip() was removed from ActionScript 3.0, and there's no replacement.

What Should Adobe Do?

Adobe should add a new method, DisplayObject.clone(), to replace duplicateMovieClip(). DisplayObject.clone() should apply to all display objects, not just movie clips.

What Should We Do?

Custom versions of DisplayObject.clone()—particularly those that handle deep copies and runtime-generated vector graphics—are very hard to make. Developers should therefore vote for the addition of a native DisplayObject.clone() method in the Flash Player bug and issue management system. For simple duplication needs, developers can use Trevor McCauley's duplicateMovieClip() replacement function, duplicateDisplayObject(). Note, however, that Mr. McCauley's function does not do a deep copy, does not handle runtime-generated graphics, and does not allow arguments to be passed to the duplicated object's constructor method.

The Prosecution Rests

Thus ends the list of Charges Against ActionScript 3.0.

I hope this article has helped to crystallize the Flash community's most common criticisms of ActionScript 3.0. If you'd like to add your own issues and strategies to the discussion, please leave a comment below. Please also report any bugs or factual errors you notice in this article. Happy coding!

Comments

98 Comments

Austin said:

Man, I've been waiting for an article like this. I'm so not impressed with flash 9 cs3... it has made the workflow horrible to develop in flash, unlike flash 8 which is like second nature. I wish adobe would reconsider the changes they've made in flash 9 cs3 and fix it all for later...

I've been using flash for like 10 years now and flex, and sometimes you just cant do a project in flex because of how animation intensive it is. Thus, forced to use flash 9 cs3.... Ug.

Leif Wells said:

I've been saying this about the Atlanta Flash Community for a while: Flashers were not well prepared for Actionscript 3.0 and it shows. I have user group members literally break out in a cold sweat when we show them any Actionscript 3.0 code, and no wonder. Now they're all interested in Flash Player 10 features but a lot of them do not have the skills to use those features yet. I say "yet" in hopes that Flash CS Next will help them make the transition.

I just wish that there was a way to get Flashers (i.e. the scores of people not interested in moving to Flex) heads into Actionscript 3.0 and allow them love it as much as I do.

Charge #10: ActionScript, as a whole, is moving in the wrong direction. It's trying to be like Java, when it should stay simple and be like Ruby.

There's a common theme to the charges. I realize that ECMAScript is also moving in the wrong direction, and perhaps Adobe is taking a cue from that. Perhaps.

However, the more I use JavaScript (in its current iteration) and Ruby, the more frustrating I find ActionScript 3.0. To the point where I've finally just given up on it.

marcel said:

super nice colin.
hopefully adobe will noticed that.

marcel said:

super nice colin.
hopefully adobe will noticed that.

As someone who has worked with Flash since FutureSplash was acquired by Macromedia, and as someone with both a design / animation and programming background, I agree with Adobe's decision to go with a more structured implementation of ActionScript in Flash with AS3. I believe it is a strategic move to position Flash as a viable platform for true RIA development.

There's no reason that a toolkit couldn't be written that abstracts the API to provide some of the functionality mentioned in the article. It would streamline development for designers / animators, yet maintain the architectural integrity of AS3.

It's undeniable that the new VM is harder, better, faster, stronger. The level of complexity of the API needed to increase to provide access to the host of new features--not only for the contemporary version of Flash, but also to elegantly scale for the future.

Consider even the nomenclature of the AS2 display object hierarchy. "MovieClip"? Think about how someone from a development background (not Flash) would approach the idea of an interface comprised of "MovieClips." They're not interested in frame-based animation. They don't want to play a movie. They want to draw vector graphics on the screen. So they create a "MovieClip"? I think Adobe has done a fantastic job of maintaining cohesiveness between a logically engineered AS3 API and the legacy AS2 API that anyone who has evolved as a designer / developer with Flash would be familiar with.

I believe that AS3 allows a developer to logically approach Flash as a UI platform with some amazing capabilities. I think AS3 alone may prove to be a challenge to a designer without any programming background, but this is not unmitigable with a well-written toolkit for designers. Maybe that's the core of what I'm saying--that you can go one way but not the other. You can abstract an API to make it easier for a designer to use, but you can't go the other way and take an abstracted API and make it more powerful for developers.

Specifically related to Charge #6--that's definitely biting the hand that feeds you. SOME errors are better than NO errors. I think it was incredibly cumbersome to code to AS2 for the example that was cited in the article. I agree with the verdict NOT GUILTY.

I would also like to say that I concur with the other, arguably non-AS3, issues mentioned in the article, specifically "Failure to Unload," which has caused me much grief in the past.

My intent is not to come off as a pretentious "real Flash developer" to all you "plebeian designers" or something, nor is it to slam Colin, whom I hold in very high regard, but I hope that this provides some counter-rationale.

Steve said:

Great post. As a full-time AS3 developer who has the luxury of using Flex Builder I don't run into these issues much. But as someone who has worked with Flash for many, many years I fully understand the concern.

Specifically to your comment "Or maybe the time has come for someone to make an entirely new application for building simple Flash websites and animations. Such a tool could even be written in ActionScript, and deployed as an AIR app. But I digress..."
I would like to plug the company I work for Flypaper Studio (http://www.flypaper.com). We have taken the code out of making simple Flash content. Unfortunately it isn't Web or AIR based (makes me sad) but it does use a lot of Flash.

:) this was the same thing we talk to colleagues about the changes to AS3. The think we do is to make some wrapper object witch gives me some of the good old functionality from AS2.

Ok, I re-read the article, and I have to concede that perhaps my previous comment was slightly a knee-jerk reaction. As a Flash platform evangelist, I really appreciated the architectural changes in AS3 vs AS2. By the time I got to the bottom and read the previous comments, I forgot that Colin's "What Should ___ Do?" commentary was really well thought through and addressed both the concerns of the designer and developer.

"But despite all the talk of GPU blitting, pixel shading, and ligatures, a non-negligible percentage of the Flash community is rightfully asking: is Adobe still committed to the simple, agile authoring practices on which Flash was founded? It's a rational enough concern. After all, Flash built its success on 'ease of use.'"

I think it is a valid concern, but "ease of use" is relative versus the audience, purpose, and power of what is being evaluated. I agree that Flash should be easy to use, but that does not mean what it did 10 years ago.

"Or maybe the time has come for someone to make an entirely new application for building simple Flash websites and animations. Such a tool could even be written in ActionScript, and deployed as an AIR app."

I wonder when the convergence between Desktop, AIR (runtimes), Browser, Flash Player will happen. I feel like the industry is so confused with levels of abstraction, we're writing browsers for various OS's, that render HTML documents, which contain Flash players, that render RIA's, or animations or whatever, which can also be deployed in an AIR runtime, which can contain a browser, etc... Forgive my rant, but I just don't see things working like this sustainably for very long. Ultimately, it will come down to a contiguous platform that will allow left-to-right-brained people to interact and produce content in a continuum of connected devices. The moment we have immediate high-bandwidth connectivity everywhere is the moment the game entirely changes, and it's almost here. But I digress...

Dragon said:

Adobe. Please listen. Please...

matthew said:

In general, I'm pretty unsympathetic to charges that a programming language should be made so that non-programmers can use it. (Instead, I believe it should be made easier for programmers to use.) However, I think that some of the things you've pointed out are simply NOT more difficult, only different. Just because people are used to doing something one way, does not make it "more intuitive" or "easier." Sometimes, the familiar way is actually less intuitive, as I would argue in the case of the "on()" construct.

As you say yourself, the on() construct for clip events requires learning an entirely new syntax. What is "release" in this line? It looks like a variable. For that matter, what is "on"? On the other hand, every programmer will be able to recognize the familiar method-call syntax of addEventListener. So I can't say that I understand what you mean by "Simple content should be easy to build." What exactly makes addEventListener more difficult than "on (blah) {} "? For that matter, what makes any of the things you highlight here "harder"? Is it just that you have more to type? Or that they aren't the same as they used to be?

In fact, most of the complaints I hear about AS3 are not related to the language or even the tools (concerning which there are certainly a ton of valid complaints), but to object oriented programming itself. I realize that OOP is a mindset that some may not have naturally, but once the basics are understood, something like adding functionality to all instances of an object might not seem like such a good idea. In addition, things that might have made the language seem "hard" before (adding listeners) seem consistent and logical.

As I said, I agree that there are a ton of valid complaints about the flash API. Extending TextFields would be a nice addition (though I take issue with your statement that "manually created text fields, therefore, cannot be augmented using traditional object-oriented programming techniques." -- TextFields can be wrapped/decorated!) However, I think it's important that when compiling the list of desired improvements, our qualifications are a little deeper than "this is too hard." As you point out in the article, most perceived omissions in the API can be overcome by some custom utility classes. Would it not therefore make sense to try to focus our lobbying powers as a community on those things that we cannot address ourselves? For example, the lack of method overloading is absolutely crippling to anybody trying to author useful interfaces. (Perhaps this is why the flash API contains so little of them -- another big issue.) Otherwise, we seem doomed to fall into the same old debates -- debates that have already been argued and decided long before ActionScript.

I fail to see how it is Adobes responsibility to make programming so easy that anyone can do it, especially at the cost of language power. I wouldn't ask the Illustrator team to create tools that help me as a programmer draw beautiful curves even though I don't have the eye-hand-coordination that it takes to maneuver my tablet pen gracefully enough.

I'm not saying that's the subject of Colins article, but those who originally fired off the accusations that this article (and the one about wether AS3 is hard or not) often tend to lean towards that mentality.

Give designers better control over the timeline without writing any code at all, and stay on this path, onto which the development of AS3 was the first step.

@Austin:
Why not make the parts that are heavily animation oriented in Flash CS3, and then load them into a pure ActionScript project in Flex Builder. That way, you won't have to use Flash CS3 all the way (as you seem reluctant to doing so) but you still get to take advantage of it's animation capabilities.

John said:

I find this discussion very interesting. and I really like the idea of one of the true Flash/AS heros spearheading a community movement to effect change in the tools!

But I have to say, as a Flash-dabbler, I have struggled with Flash and AS for years! For me, a similar list of charges could have been written with each new version of Flash/AS. As a former VB programmer I was totally spoiled by an IDE that knew what I wanted to do most of the time. When I went to Flash/AS it was (and is) a nightmare trying to remember or look up the complex, detailed instructions for every simple step I wish to take. Improvements to the IDE could bring so much joy to me!

I have gotten by but it is always very painful. And I wish that it weren't so painful; I would LOVE to LOVE working in Flash/AS!

salsa said:

Great article. The IDE is very good regarding it is the first version that supports AS3.
Any way people use flash because it promotes a good balance between developers and art/graphic designer in a wide range of applications, so Adobe should be very concerned about these limitations.

Some of your charges are a bit 'AS2ish' . I have taught both AS2 and AS3. My conclusions are:

- the learning curve is a lot different:
in AS2, students start coding and doing funny things very fast, but when projects start getting more complex they tend to block;
in AS3, students struggle to understand the basic concepts and they feel a lot disappointed at the beginning, but later, after they get used to it, they develop faster, easier and in a more logical way.

- students who already knew AS2 have more difficulty learning AS3 than students who never saw Actionscript.

- students who were used to the AS2 way of coding are normally snippet coders: they solve problems by googling, copy pasting, and hammering code until it works. Students who learn AS3, after the initial rejection, tend to be much more organized, logical and they solve their problems faster just by digging the documentation

- the first reaction they have with the documentation is a "I hate this, it's worthless". After they learn the basics of AS3 they can't live without the documentation.

- students who have some background on engineering, OOP, or languages like JAVA learn FASTER than everyone else: in a matter of days they start coding AS3 like if they have done it for years.

I normally teach Actionscript to designers in a technical design school. My background is software engineering, but I try to keep a balance with the both sides of the brain while teaching to help them program as good as they design. I feel more comfortable teaching AS3 than teach AS2.

So, my conclusions are: just because we need to make more 10 characters in AS3 to make the same thing we did in AS2, doesn't mean that it's harder. It's just a different picture.

BTW, the use of the "parent" property should be prohibited... that's the biggest fight I have when teaching AS3 - I forbid my students of using "parent" on their code.

But, of course, I agree with you in some of your charges. :)

This is the single most retarded article I've read.

Moping because they are evolving the language to a true OOP programming language?

Pathetic.

lee said:

I agree with the idea, but not the charges. The AS3 API could be built ALOT easier. Instantiating new TextField's with custom formats, the drawing API, these are all left at a base level. Which is great for me, as I can write my own TextField class that easily spits out TextFields just how I want them, but even so, Adobe should develop these types of classes further.

Classes should be further developers so that people can work with the drawing API like: var circle = new Circle(100, gradient(000000, FFFFFF), 9scale);

well...the article is very interesting. In my opinion AS2 was a really improuvement over AS1 but AS3 is a very bad evolution of AS2. Many of the very good features of AS2 are now suppressed and to write a single command for a simple button I have to write many lines of code that sounds strange to me. And I really dont understand the advantages of, for example, the navigateToURL() function over getURL(). AS3 is cumbersome without any shadow of doubt.
Cheers

Charlie said:

Adobe is in a tough position. How do you satisfy two segments that have widely different views (needs) on what a programming language should be and do?

The reality is that there would be no AS3 without the adoption of AS / Flash since version 3 by non-programmers. Adobe needs to sell lots of licenses to sustain Flash development efforts on a global scale.

The reality is that the language needed to evolve to meet the requirements of advanced web applications.

For the programming professionals, the answer is simple. Learn the new language and you will quickly enjoy its benefits. While this is true, it may or may not happen. One thing that I think Adobe has been terrible at (at least over the past 15 years) is understanding that its customers do not always have the time to constantly re-learn a tool or programming language. I personally can attest to having at least 3 HTML tools discontinued forcing me to learn a new software package with substantially different interfaces, tool sets, etc... The same has happened to other software categories such as video editing apps or Mac-based apps when Apple was in trouble.

At small agencies and design shops worldwide, people wear different hats. Few have the time to fully explore a particular software package anymore. Flash attracted millions of web professionals because them get things done quickly. AS3 will do that even faster when you become proficient, but there lies the problem. Non-programmers can't build on what they have learned in the past. Essentially, their experience and knowledge feel worthless. And, this is when alternatives become attractive.

The fact that there is resistance a year+ after the launch of AS3 should worry everyone. Because without the funds non-programmers bring in, programmers will eventually lose the Flash platform. Unfortunately, this is the rule of this current game. And it is not pathetic.

Thank you Colin for elevating the issue.

P.S. Proficient programmers and other gurus can be of tremendous help by posting simple tutorials designed on helping non-programmers transition to AS3. Simple snippets like the ones featured in this article are extremely useful to AS2 users. Once a few obstacles are overcome, adoption will be easier. Let's hope.

Collin,

I couldn't agree more with what you have posted especially #6. There are some fundamental issues that Flash CS3 introduced that do make it harder for anyone coming from any previous version of Flash.

The Error messages are not one of them though. The Error messages are a fantastic help that the ActionScript provides to keep developers and designers scratching their heads rather than banging them (most of the time).

Because some errors are very cryptic and hard to understand, I have created a site documenting all the ActionScript 3 Errors with code examples and screenshots. I hope this will help developers and designers scratch rather than bang.

This article and the previous will help transitioning Flashers around the world not get the errors in the first place. Thanks again for writing this.

Curtis J. Morley

Dan Zen said:

I teach as well and agree with the previous teacher's assessment.

Students learned AS3 last year and it was easier to teach and learn because of its consistencies.

For instance, data access took up half the second term in AS2 because the LoadVars syntax seemed hard for students. After teaching the first term in AS3, data access was just a lesson and they got it right away - same old, same old.

Having said that, after they got it right away, I did provide a wrapper class that reduced the 15 consistent lines to three (or a few more with error handling) You can check that out at http://falconflash.wordpress.com - looks something like this - similar code is provided for variables and XML as well:

// in your constructor for instance
var myFalcon:Falcon = new Falcon("sample.txt", Falcon.TEXT);
myFalcon.addEventListener(Event.COMPLETE,getData);

// in the body of your class make the event method:
private function getData(e:Event) {
if (e.target.error) {
trace ("sorry, error accessing text file");
} else {
trace (e.target.data); // this is your text data!
}
}

Interestingly, we did not teach students AS2. So in case they were called to code AS2 or convert AS2, etc. we needed to give them some idea of the differences. But we had to go backwards and almost all articles were written from the standpoint of going forwards so they assumed you knew the AS2. This prompted a blog article on going from AS3 to AS2 if anyone is interested: http://tinyurl.com/5zublt

Hope I did not stray from the point of the article too much ;-) In general, many of these issues is a trade-off between consistency and brevity.

Thanks for the article Colin!

I think most of us who do AS3 40hrs a week for a living just wrote our own libraries to make this stuff easy again. The control is nice but, some syntactic sugar would be nice for everyone else. I am more concerned about there being no documentation tool and having to depend on FlashDevelop for my IDE. I don't want to switch to Flex. If I have to go to flex why not just use silverlight. Flash is great because it allows me to place graphics on stage as I would in Photoshop or Illustrator. So, the power tools need to be in place as well. Write now they are missing both the simple and the hardcore. What the heck!

John said:

@Charlie
"At small agencies and design shops worldwide, people wear different hats. Few have the time to fully explore a particular software package anymore. Flash attracted millions of web professionals because them get things done quickly. AS3 will do that even faster when you become proficient, but there lies the problem. Non-programmers can't build on what they have learned in the past. Essentially, their experience and knowledge feel worthless. And, this is when alternatives become attractive."

You nailed it with this comment (and I think it is key in Colin's point). I work at a small company. I do sales, project management, accounting...oh and I also do all of the server-scripting and Flash programming for our projects! I love the job but I'll never have the time to properly master AS3. So I rely heavily on people like Colin and other Flash/AS masters to provide me with bite-sized solutions I can drop into my projects.

I hope I don't sound too lame but I'm not trying to amaze the world or blaze new trails...just trying to deliver nice, working solutions to our customers as quickly and as cost-effectively as possible!

Derek said:

I think the frustration with learning AS3 is having to learn it all over again. If you are like me, and program in javascript, VB, C#, AS2, SQL, Java, PHP and various other program specific tools--it just gets crazy trying to learn and work at the same time. I love Flash--all my favorite projects have been built on it.

The problem is that Flash changes the more than any other program. Then Adobe starts spitting out tools like crazy. All my other tools have been more consistant. I can maintain old projects and build my skills with new features with old and new projects. However, Flash and actionscript have always been all or nothing. A leap of faith because it is not just an upgrade, it is revamp.

Bottom line is that it is time consuming for someone like me to relearn it everytime a new version comes out. Each time I try to start a new AS3 project I think, "do I really have the time to invest in this, or should just work in AS2?"

I love the idea of AS3, but it becomes tiring having to almost start over everytime a new version comes out with new ways of doing things and new work arounds.

colin moock said:

Just to be clear, I am not arguing that "a programming language should be made so that non-programmers can use it."

I am also not "moping because they are evolving the language to a true OOP programming language." Quite the contrary, I'm elated that ActionScript is now a true OOP language.

Plainly put, I am strongly in favour of hardcore programming tools. I love ActionScript 3.0, and I love that Flash has become a platform. It's great to see Adobe finally providing programmers with power tools, such as Flex Builder, the ActionScript 3.0 profiler, ASDoc, ANT intgration, data services, a proper debugger, a command-line compiler, the Flex framework, a public bug database, MXML for UI development--the list goes on. Adobe is doing a great job of catering to the programmer crowd, and their efforts are attracting an unprecedented number of new serious developers to Flash.

So let me reiterate (from the introduction):
==
For the record, I should point out that despite the issues discussed in this article in my opinion ActionScript 3.0 is vastly superior to ActionScript 2.0 and ActionScript 1.0. Growing pains aside, ActionScript 3.0 is the language of choice for any Flash-platform project.
==

Yes, professional programming tools are wonderful.

But in addition to programming tools, we need complementary tools for producing rich interactivity and motion graphics. Those tools must have an easy to use (yes, easy to use) scripting system. And that system should integrate well with the more powerful programming tools. "Easy to use" means:

1) simple, routine tasks can be accomplished quickly, with minimal effort
2) concepts in the scripting system must be approachable to designers and less experienced programmers

Flash authoring has, in the past, provided the tools for producing rich interactivity and motion graphics. And it *used* to have a simple scripting system. In Flash CS3, ActionScript 3.0 can mostly still be used in simple ways (see http://www.insideria.com/2008/01/actionscript-30-is-it-hard-or.html), but some common scripting tasks are now cumbersome or unapproachable. This article lists some of those tasks. It is not a plea for Adobe to simplify ActionScript 3.0 itself, nor to stop catering to the professional programmer. It simply recognizes a gap in Adobe's current tool suite. The issues are fixable. Programmers and designers can both be happy. (Even if they are the same person.)

colin moock said:

Derek, you wrote: "Bottom line is that it is time consuming for someone like me to relearn it everytime a new version comes out."

that's a very valid complaint, but fortunately ActionScript 3.0 is the last major core language update you'll have to learn for a long long time. the core is settled, and is based on ECMAScript 4, which is designed to have a shelf life of at least a decade. sure, new player apis will be introduced, but the existing apis will remain intact. the flash authoring experience will naturally continue to evolve, but the language will be stable. now if you want to talk about new versions of the Flash components...that would fill another article.

steven said:

I teach Flash to designers and all I can say is that with AS3 the threshold of entry as well as the intimidation factor became too high for design students. What they want to do is make something functional and beautiful without needing to spend weeks learning the basics. AS2 made that possible. AS3, to a huge degree, took it away.

Adobe did designers a huge disservice by making the AS3 documentation show only programmer-oriented, class-based solutions. Because of this, the AS3 docs are basically useless to beginners--who one would think would be the target audience for such documentation! Revising the docs to include a basic, procedural example on each page would go a long way to improving the Flash CS3 experience.

graphex said:

Charge 9 is paramount in my book. I've spent many hours trying to find a way around that little error of omission. Trevor McCauley's approach inexplicably doesn't work in some cases, leaving you with really no workaround whatsoever.
At the time of this writing, the adobe bug currently only has 4 votes - not even the number of people on a jury.
I think Adobe should first fix programming dead-ends like this before even starting on a better non-programmer GUI.

jim said:

Great article!
Please also report any bugs or factual errors you notice in this article:
Charge #7: Referring to Library Symbols Dynamically Is Unintuitive:
parentClip.attachMovie("Animation" + i, "instance" + i, 0);
--> 0 should be i or parentClip.getNextHighestDepth()

Charge #8: Adding Custom Functionality to Manually Created Text Fields, to All Movie Clips, or to All Buttons Is Cumbersome:
scaleX = scaleX;
-->misses a minus sign

radekg said:

That is really great article. Regarding point # 7:
I would love to see feature like this:

var Symbol = new Application.Library.SomeAsset();

instead of getDefinitionByName().
Application references current app. Library points to library (similar to Properties.Resources in C#) and class in linked name for asset.
Again when asset is in some directory it could be:

var S = new Application.Library.somePackage.SomeAsset();

I think this would be most intuitive.
Again - great article.

Ronny Karam said:

Flash was (to me it's still) beautiful because of its coding simplicity and easy to use features/components/etc..

When I checked the AS3 documentation for the first time, i felt in a totally different world. AS3 was oriented "exclusively" for developers when Flex was too.

So what's Adobe's plans regarding that? I have no clue. Why having 2 products that can, "overall", do the same work? I also have no clue. Maybe Adobe can answer that.

I imagine that AS2 was also something out of the designers reach when it gets to developing complex animations or applications. But as someone said previously, they could've always relied on some online experts to help them reach their goal.
Add to that the fact that AS2 didn't go out of the Flash/AS1 spirit. It stayed simple and easy to use.

Even if learning AS3 draws new horizons (especially with Player 10), still it's only meant for developers. Adobe left the designers out in the cold with the release of Flash CS3; designers have 2 options:


  1. Keep using Flash with AS2

  2. Drop Flash for another product


Harish said:

Hey Colin
I really miss the Webservice class in CS3. you have not mentioned about that here. Its more than an year CS3 is in market yet wonder what research they are making on the webservice class yet. They removed it completely from flash and forget about that and making more research on Graphics(3D, animation, kinetics, video) is that because of ADOBE(more concerned about graphics) or to improve the sale of FLEX. Adobe is trying to bring C, C++ programmers into flash but what is the reason they cant bring the webservice back in flash. Iam eagerly waiting for a good answer form you Flash guru(teacher).

Justin said:

I'm a designer. I've been battling with ActionScript since Flash4. Like many, I've spent incomprehensible amounts of time learning and re-learning ActionScript. When AS3 was released I took one look at it and threw in the towel. Since then my life has been much better.

I have no doubt Adobe have made the correct decisions with AS3 and will continue to do so. It's just sad that the advances in AS3 have left so many of us floundering in it's wake.

Perhaps one day I'll re-kindle my friendship with Flash.

AJ said:

I think the only thing I can agree to here is unloading swfs and problems we face around it. Who would want to user onClipEvent(), enough has already been said about it.

The thing missing in Flash CS3 is a good ActionScript Editor. I use FlashDevelop but it does not exist for Macs. Flex Builder can be used but its too much for just coding, it takes ages to load, while I need something as quick as a notepad. Its more of an IDE, to which its now doing justice.

AS3 is a more mature language ActionScript has ever been but Flash CS3 cannot cope with it as it does not have an editor like Visual Studio.

This scenario is more like when Microsoft introduced VB.Net and C# while neglecting VB Script crowd. I think Adobe has to move on from AS2 as well, the way MS moved away from VB script.

christian said:

Well done Colin! Using Eclipse and Flex Builder I kind of ignored those issues, especially from a designer point of view. What you clearly showed here is that it would have been REALLY easy to keep Flash IDE as a script friendly environment without renouncing to the robustness of AS3. For this reason I consider Adobe GUILTY and I'm very surprised they committed such mistakes considering the recent arrival of Silverlight.

for Francis Lukesh:
To be honest I don't use MovieClips at all in AS3, if you don't want frames just use Sprite.

Todd Dominey said:

For years I've watched how other people use the IDE, most of them that big mushy center of users that are designers with enough left-brain logic to handle a little light procedural