Paul Robertson's words, punctuated

Thoughts on development, user-centered design, code, etc. by Paul Robertson

ActionScript 3 Syntax preview

Update: Alas, I knew this would be short-lived in value when I posted it. =) Now that ActionScript 3 information has been released by Macromedia, you’ll find these links to ActionScript 3 language descriptions and differences from AS2 more useful than this preview based on the ECMAScript proposal.

I have to admit, since I first heard details about ActionScript 3, combined with the details of Flex Builder 2 (finally Flex the way I wish it was from v.1) I have been jumpy with excitement to tell people about what’s coming: coworkers, users’ group members, and even my wife has gotten an earful. I definitely consider this to be the best thing to happen yet in ActionScript development. (Maybe I should have applied for that Flex Technical Evangelist position, since that’s what I find myself wanting to do anyway!)

So, being unable to wait I dug up the ECMAScript (ECMA-262) 4th edition proposal and combed through it to find out what I could about what’s coming in ActionScript 3. Obviously Macromedia can choose what things to implement or not implement, but they have said (I’m paraphrasing here) that their goal is to be as close to the spec as they can, even the target implementation of the spec. So I think by looking at the spec we can get a pretty good idea at least from the syntax point of view what ActionScript 3 will be like. Of course, the object model is another story – for that we’ll just have to wait to see what Macromedia gives us, and what we as a developer community do with it!

So here’s my summary of the things in the ECMAScript 4th edition proposal which are not included in ActionScript 2. If you are a Macromedia employee, feel free to skip to the end to read other things that I would like to see implemented in addition to what’s in the spec.

Note: in addition to the things included here, Macromedia has publicly stated that AS3 will also support DOM Level 3 events and E4X, which are different specs (E4X is specifically an extension to ECMAScript).

Disclaimer: This is obviously just my interpretation of the ECMAScript spec; it is very possible that I missed or misinterpreted something, so this information may not be correct. In addition, Macromedia has the option of choosing to implement or not implement portions of the spec at their pleasure. Having said that, if you believe a correction is in order, please leave a comment or contact me.

Keywords

  • const - defines a constant. Must be a compile-time constant value; cannot be written to more than once.
  • export - ???
  • namespace - used to define a namespace (see below)
  • package - used to define a package (see below)
  • use - specifies a namespace to use (see below) or a pragma to use (whether to use strict mode or not is the only pragma defined in the spec)

Operators

  • as - ”a as type” where a is a variable/value and b is a type. Returns the value of a if a can be implicitly coerced to type, otherwise it returns null (or throws an exception if type can’t be null).
  • is - ”a is b” returns true if a is a member of type b, otherwise false
  • &&= - logical and assignment
  • ^^ - logical exclusive-or (xor)
  • ^^= - logical xor assignment
  • ||= - logical or assignment

Scope

The following statements now have their own local scope:

  • for (including any variables defined in for initializer or for-in iterator "binding")
  • catch (including parameter)
  • try, finally
  • if
  • in general, all block statements

Note: a variable will be "hoisted" (it will follow the scope rules of ECMAScript 3/AS2) when all of the following are true: it is defined in a var statement; the definition doesn’t specify a type; it has no attributes except true; the scope it would be hoisted into is not a class; Strict mode is not being used.

Strict mode

This is a more strict compile-time type checking mode. The following conditions are imposed by Strict mode:

  • variables cannot be read or written to until they are defined (variables must be declared)
  • variables cannot be hoisted (block-level scope is enforced)
  • function parameters are checked for number and type (method call must match method signature)
  • function definitions are constants rather than variables
  • line-break semicolon insertion is turned off
  • line breaks can be used in places where they previously weren’t allowed

Attributes (modifiers)

  • Namespace (access) modifiers
    • internal - accessible within same package only
    • private - now truly private (within class only)
    • public - as in AS2
    • Visibility
      • enumerable - indicates a property can be seen using for-in statement (default is hidden)
      • explicit - not shared via an import directive (see below)
  • Class modifiers
    • final - class cannot be subclassed
  • Member modifiers
    • static - as in AS2
    • virtual - method or property can be overriden in subclasses
    • final - method or property cannot be overridden in subclasses
    • override - method or property overrides the definition from superclass. Can also be specified as override(true), override(false) (meaning it doesn’t override) or override(undefined) meaning it may override.
  • Conditional
    • true - definition is processed
    • false - definition is not processed
  • Miscellaneous
    • prototype - function defines a class; this refers to function, and function can be used as a prototype-based constructor
    • unused - definition is not used
  • User-defined
    • you can define your own attributes, either using a const definition or other definition that defines a constant

Variables are public final by default; methods are public virtual by default.

Variables

  • When a variable is declared, internally it creates a hidden variable and defines a getter and setter to access it – so a subclass can override a variable’s getter or setter (as long as the variable is declared as non-final).

Method (function) parameters

  • Parameters are now required; if they are omitted the compiler generates an error unless the function is unchecked (see below).
  • function parameters can be identified as optional by giving them a default value in the function definition, like function(a:Number = 3, b:String = "hi"):String {}
  • optional parameters cannot come before required parameters.
  • rest expression : If ... appears after parameters, additional parameters can be accepted. A single parameter name can be specified after ... – it must be of type Array, and any additional parameters passed to the function become elements of the Array, starting at index 0. This provides an improvement/replacement for the arguments object.
  • Unchecked functions: a function can become "unchecked", which is a backwards compatibility mode that is triggered when a function is not a class method, has no specified types (return or parameter types), and strict mode is disabled at the function definition. Unchecked functions have an arguments array like in previous versions.

Classes

  • can have inner classes (classes declared inside of other classes) – these must be declared static
  • this always refers to the instance (no more scope issues/need for mx.utils.Delegate).
  • Overriding:
    • Overriding a method without using the override attribute results in a compiler warning (and using the override attribute when there isn’t a method to override also results in a compiler warning). Parameters of the overriding method must match overridden method: the parameter type must match or be unspecified in overriding method (which defaults to the overridden method’s type), but default values for optional parameters may be different.
    • You can use super to refer to the overridden method.
    • Methods can only override methods; variables can only override variables; getter/setter functions can override getter/setter functions or an instance variable.

Packages

  • package {} statement - can surround class definition to define the package that the class belongs to
  • import statement can be written import pkg = com.mydomain.mypackage to create an alias for the package (this is useful if there are classes with duplicate names in separate imported packages – you can refer to them using the alias package name e.g. pkg.MyClass)

    Note: when I originally wrote this article, I had the order reversed for the import pkg = … statement (I had the package name first and alias after). After reviewing the spec again, the way it’s written here is (I believe) the correct one.

  • The import statement can also point to a URL rather than a package name – the obvious use case for this is when a browser is the host, allowing you to import other classes (or other authors’ classes) from a central location.

Namespaces

This provides a mechanism to define certain portions of a code file – for example, certain methods of a class – as belonging to one or more namespaces. The use case presented in the spec is to provide a mechanism for creating multiple versions of code in a single file. You could define multiple versions of a method or property, or add new methods and flag them as only belonging to a certain version. Other code which refers to that code can specify which namespace (i.e. which version) of the code it is defined to use, and only the parts of the code which are flagged as belonging to that version (namespace) will be compiled.

I can see how this would be useful for the "importing other authors’ code from a url" situation – if the author updates the code, he/she can specify versions in the same file, and as long as your code points to the version it was created to work with, your code will never break. For ActionScript I don’t know if this is as useful – although I suppose this would allow authors (e.g. Macromedia) to create new versions of classes and still provide a single source file, and would avert the need for separate classpath folders like Macromedia had to do with Flash 8.

Predefined types

* Types marked with an asterisk were defined in ECMAScript 3 but not included in ActionScript 2

  • Never (the subtype of all types – the opposite of Object)
  • Integer
  • char
  • Type
  • EvalError*
  • RangeError*
  • ReferenceError*
  • RegExp*
  • SyntaxError*
  • TypeError*
  • URIError*

There is no longer a distinction between objects and primitive types (all types are objects).

String(), Integer(), Number() are now explicit coercions rather than type conversion functions.

Machine types

These are types defined in the spec, but their names are not reserved words and can be used as identifiers.

  • sbyte (signed byte?)
  • byte (8 bit integer)
  • short (16 bit integer)
  • ushort
  • int (32 bit integer)
  • uint
  • long (64 bit integer)
  • ulong
  • float (single-precision floating-point number)

Numeric literal suffixes: To specify a literal number of certain types, you need to add a suffix to the number (e.g. var x:long = 25L;). The suffixes are l or L for long; ul, uL, Ul, or UL for ulong; f or F for float.

Things I would like to see, which aren’t in the spec

Macromedia, please take note! You said you wanted to get developer feedback on the direction of ActionScript 3; well, here’s my first feedback:

Things I wish were added, but aren’t (at least, not in the standard)

  • Items explicitly mentioned in the spec as considered but deferred:
    • protected attribute
    • operator overloading
      • For me, the priorities here would be the array access operator ([]); being able to override/define implicit and explicit casts (type coercion); the equality (==) operator; then I guess the addition and subtraction operators. I haven’t ever had a need for any of the others, although I wouldn’t object to having them available.
    • various typed Arrays (including List, type[], and Array[type], among others)
  • Items not mentioned at all:
    • method overloading
      • Obviously this is much easier to "fake" now with optional parameters and the rest expression, but sometimes it’s nice to have method overloads with different return types or completely different parameters.

Things included in AS2 but not in ECMAScript 4th edition

I expect Macromedia will keep these things around in ActionScript 3, and hopefully even add a few more nice things too!

  • Interfaces - hopefully Macromedia will add support for properties/getters and setters, especially since now variables have an implicit getter/setter declared for them anyway, making the distinction between them trivial from the perspective of a user of the class.
  • dynamic and intrinsic class attributes

Comments