ECMAScript 4 Speaking Tour


#1

From John Resig blog

ECMAScript 4 Speaking Tour

During the past two weeks I’ve given three presentations on Tamarin and ECMAScript 4. I’ve gotten a ton of great feedback, criticism, and commentary – all of which has been very helpful.

here the preso PDF
tamarin-and-ecmascript-4.pdf (234.7 KB)

and many more links to difference presentations in different JavaScript user groups.

And yeah, all this, in the end, did not happen, well… for the JS users, but it did for the AS3 users :slight_smile:.

In fact, the PDF got all the informations you need with the 2 following slides

ECMAScript 4 Goals

  • Compatible with ECMAScript 3
  • Suitable to developing large systems
  • Allow for reusable libraries
  • Merge previous efforts (ActionScript)
  • Fix ECMAScript 3 bugs
  • Keep it usable for small programs

ActionScript 3 benefited from all that

Compatible with ECMAScript 3
Yep, see the ActionScript Compiler (ASC) options: -AS3 and -ES

-AS3 = use the AS3 class based object model for greater performance and better error reporting
-ES = use the ECMAScript edition 3 prototype based object model to allow dynamic overriding of prototype properties

See the ActionScript 3 Language Specification
Chapter 21 Compatibility with ECMAScript edition 3

While we have made this edition as compatible as possible with the ECMAScript (ECMA-262) edition 3 language specification, there are certain behaviors for which there is no clear use case and keeping them as-is would have been placed an unneeded heavy burden on the new features of the language. In such cases, we have made small and calculated changes to allow the new definition to be simpler and easier to use.

21.1 this inside of nested function
In ECMA-262 edition 3, when this appears in a nested function, it is bound to the global object if the function is called lexically, without an explicit receiver object. In ActionScript 3.0, this is bound to the innermost nested this when the function is called lexically.

21.2 No boxing of primitives
In ECMA-262 edition 3, primitive values (Boolean, Number, String) are boxed in Object values in various contexts. In ActionScript 3.0, primitives are permanently sealed Objects. Unlike boxed objects, attempts to dynamically extend a sealed object results in a runtime exception.

21.3 Assignment to const is a runtime exception
In ECMA-262 edition 3, primitive assignment to read-only properties failed silently. In ActionScript 3.0, primitive assignment to read-only properties causes a runtime error to be thrown.

21.4 Class names are const
In ECMA-262 edition 3, constructor functions were writable. In ActionScript 3.0, we implement these properties with class definitions, which are read only.

21.5 Array arguments object
In ECMA-262 edition 3, the function arguments property is a generic Object. In ActionScript 3.0, arguments is an Array.

Also see The case when you don’t want Node.js where I demo how the TypeScript sources got compiled to ABC (ActionScript ByteCode), thanks to this ES3 compatibility, and then run inside the Redtamarin Shell which is basically the AVM2 (ActionScript Virtual Machine 2).

Even Funnier, a lot of dev complain and whine about “how the hell can I export AS3/Flash to HTML5/JS?” but they don’t even consider it the other way: “oh maybe there are some JS libraries out there that I could compile into my AS3 project”.

All those compilers like TypeScript, Babel, etc. have an ES3 target, imagine if AS3 dev had
something like a Node API layer in AS3, they could reuse most of the npm packages.

Suitable to developing large systems
Yep we got that real good in AS3.

Also why I consider AS3 to be “on par” with bigger languages like C# and Java,
you can write big big programs in AS3 and not go insane thanks to packages, classes, interfaces, etc.

This for example
AJVM – Java virtual machine implemented in ActionScript 3.0
yep a JVM implemented in AS3, that’s pretty big :smile:

or this too Scratch 2.0 for Raspbian
Scratch, that’s also a pretty big program

or the Flex frameworks also a big code base

or the AGAL mini/macro assembler
not big but basically a mini-VM managed in AS3 which is quite impressive

I could even argue AS3 still does it much better than ES6.

Allow for reusable libraries
Yep we got that too

Because of the AS3 programming language, the AVM2 and the possibility to pre-compile to bytecode and the tooling etc. we can manage libraries pretty well as any other big language (C#, Java, etc.).

Most of the times AS3 dev don’t even think about it, just drop the SWC you need there and you’re basically done.

Now, the whole ecosystem is pretty advanced for that, you can perfectly write AS3 libraries

  • make it compatible both for Flash and Adobe AIR (conditional compilation)
    or even Redtamarin for that matters
  • make it compatible among different SWF versions
    see Avmplus API versioning and the API metadata
    eg. [API(AR_1_0, FP_10_0)]
  • you can use namespace to version your own AS3 library
    not used often but see 12.5.2 Version control in the spec
  • you can compile again an SWC library in a lot of different way
    if you compile against playerglobal.swc you don’t include the lib for ex
    in fact there are tons of options just check your compiler options
    eg. $ ./mxmlc -help advanced
  • you can even turn an ES3 library into an AS3 library
    and even have syntax completion in your IDE

Yeah all that is pretty convenient and almost ignored by the AS3 dev because they took it for granted, but how all those JS dev kind of struggle managing their libraries.

Merge previous efforts (ActionScript)

Basically what we have in ActionScript 3 which is not 100% the same of what was planed with ECMAScript 4.

Fix ECMAScript 3 bugs

Let’s just say that JS dev are still struggling with equality confusion
eg. should I use a == b or a === c ?

And some many more things like function block scope, this, etc.

And with AS3 we don’t have to deal with that shit.

Keep it usable for small programs
Yep we have that too.

I see that a lot, especially with Redtamarin, where you can go from a little few lines shell script (with as3shebang), to a bit more elaborated program that uses 2 or 3 classes and compile to an ABC, to something bigger like a good dozen classes and reusing a couple of SWC libraries that compile to a SWF and then you make a command-line exe out of it.

See? from small to medium to big.

Also why I find AS3 a so well balanced programming language, it can do the little glue scripts you can do quickly in JS as well as the big program you could do in Java, it can do both no sweat :smile:.

Being able to write small programs is quite the feature, you got an idea? want to quickly experiment? just write some code and pop up the result etc.

In something like Flash CC / Animate CC it is super easy to just prototype and experiment.

Features

  • Classes and Interfaces
  • Packages and Namespaces
  • Type Annotations
  • Strict Verification
  • Optimization
  • Syntax Shortcuts
  • Iterators and Generators
  • Self-hosting

So yeah AS3 got a lot from ES4, but not everything

Classes, Dynamic Classes, Getters and Setters yep we got that

Catch-Alls ? we kinda got that with the Proxy class and the flash_proxy namespace, but those are more native classes implementations than part of the AS3 language.

Inheritance, final statement, Multiple inheritance via Interface, MetaClass (eg. static methods), Interfaces, Types, Function Types, Rest Arguments, … yep we got that

But even if we got the Any Type we don’t have the Union Types
eg. var test : (string, int, double) = “test”;

We don’t have Type Definitions
eg. type Point = { x: int, y: int };
but this one is not a big deal imho as you can define a Class and/or Interface to define your type

We have some kind of Nullability support eg. “Prevent variables from accepting null values”
with the number types eg. var test:uint = null; will set the variable to the default value 0

but check the spec chapter 6 Types and see this little graph

There are three fundamental program visible types (Null, Object and void). What makes these types fundamental is that their union includes all possible values in the language. Null includes null, void includes undefined, and Object includes every other value.

But things like preventing to assign null to the String type in ES4 were not included in AS3
eg. var name : String! = “John”; and name = null; // ERROR

We also don’t have __ Initialization__
eg. var name : string!; // Must be initialized

We don’t really have like
eg. type Point = { x: int, y: int }; and if ( { x: 3, y: 5 } like Point )

but … we can do something equivalent with interfaces but not exactly the same,
not the convenience of the litteral object.

We don’t really have wrap but we can use as

We don’t have Parameterized Types but we have Vector

And on and on …

Here the funny thing, most of those ES4 features that did not “made it” into AS3 was to avoid to become a bit too much incompatible with ECMAScript if it suddenly moved into another direction…

So something like let did not happen in AS3, and it appears again in ES6,
and there I gonna avoid a long tirade about function block scope :wink:
I would just say we don’t really need let in AS3 and ES really need it.

Let’s just say that when you deal with ES3 you cruelly need something like TypeScript or Flow to keep sane, but when you’re using AS3, even if the language is not “perfect”, you have enough features in the language itself to write about anything from small to big programs.

Also interesting to compare those “old” ES4 presentations to what was said about ES
in the Chrome dev summit 2017 keynote, how people quickly forget what are the reasons something happened :smile:.


#2

@zwetan I’ve read and re-read this jresig’s big picture and the ECMAScript 4 overview many times, but of course I always know AS3 is not just for large development. It should replace JavaScript. IMO AS3 is simple like ES3 and ES4 just had some more features.

Primitive types

ES3 primitive types are different than ES4 AFAIK. ES4 string is the String type, but there’s also the global string class and etc…

Equality comparison

If I understand that as a performance issue:

Let’s just say that JS dev are still struggling with equality confusion
eg. should I use a == b or a === c?

It doesn’t matter, cuz nearly any JS compiler could optimize it with type inference/tagging. Just because there are type annotations, it doesn’t mean only their references can be optimized.

More.

IMO AS3 should have ES4 generic functions. I’m not sure if I understand them deeply. The overview shows this example:

A generic function is a function object that performs run-time dispatch to one of several attached methods
based on the actual types of the argument values and the signatures of the available methods. (Generic
functions are often called multimethods.) [Little plus to read…]

generic function intersect(s1, s2); // No body here 

generic function intersect(s1: Shape, s2: Shape) {
    // general intersection method
}

generic function intersect(s1: Rect, s2: Rect) {
    // fast intersection for rectangles
}

But I hope we could also vary on argument length like it’s possible in C and Java.

Since the ecmascript.org site never loaded for me, I took its ES4 reference implementation releases (for ES4 testing) and its source in archive.org. It’s not so easy because most archives are broken and you also have to inspect the page to find the download link (but that’s easy). I did that already, though. MediaFire. Hope someone likes. :confused:


split this topic #3

A post was split to a new topic: An ActionScript 3 port of Mozilla’s Rhino JavaScript interpreter


#4

but again, not having them does not prevent you to write the code, it’s not a blocker

also you have namespace

public function intersect( s1:*, s2:* ):void
{
    //...
}

with_shape function intersect( s1:Shape, s2:Shape ):void
{
    //...
}

with_rect function intersect( s1:Rect, s2:Rect ):void
{
    //...
}

and you can use it like that

use namespace with_rect;
var r1:Rect = new Rect();
var r2:Rect = new Rect();
foobar.intersect( r1, r2 );

So it is possible but that’s quite a lot of overhead in your code and by using the any type
you can then detect the type at runtime

public function function intersect( s1:*, s2:* ):void
{
    if( s1 is Shape )
    {
        _intersectShape( s1, s2 );
    }
    else if( s1 is Rect )
    {
        _intersectRect( s1, s2 );
    }
}

private function _intersectShape( s1:Shape, s2:Shape ):void
{
    //...
}

private function _intersectRect( s1:Rect, s2:Rect ):void
{
    //...
}

and many tons of other way to do it

not that generic are bad, but it is a feature you can live without easily.

there is the rest argument

	
function functionName(parameter0, parameter1, ...rest){ 
	// statement(s) 
} 

For ecmascript.org site, I might have some archvie of sources and spec laying aroudn somewhere if someone need such thing.


#5

I know there’s the rest argument, but, say, a function definition like

void Drive(U32 km);
void Drive(U32 km, bool forward);

C++ case and also Java one.

abstract class Car
{
    abstract public void drive(int km);
    abstract public void drive(int km, boolean forward);
}

You could do it on AS3 like this:

public function drive(km:uint, forward:*)
{
	if (forward is Boolean)
	{
		// drive (km:uint, forward:Boolean)
	}
	else
	{
		// drive (km:uint)
	}
}

If this boolean won’t make much difference, you can also use a default parameter.

public function drive(km:uint, forward:Boolean = false)
{
	if (forward)
	{
		// drive (km:uint, forward:Boolean)
	}
	else
	{
		// drive (km:uint)
	}
}

which better debugs.


By hearing what you say, it means that most ActionScript 3.0 compilers only optimize what is typed. So, well, it’d really have extra runtime opcodes. I also think generics are easy to live w/o and it costs nothing for changing the function name in situations where intersect (s1:Shape, s2:Shape) = intersectShape, between others.


#6

It’s all about OO Design, in my opinion AS3 is expressive enough to cover all the cases and stay simple and cover/fix the “bad things”/bugs of ES3.

That said, each programming language can influence with its features how things are done,
but again I would say what is important if to not forget about the OO Design.

For ex in JS you will see this pattern when passing parameters to a function to use named arguments

see ES6 In Depth: Destructuring

Practical applications of destructuring

Function parameter definitions

As developers, we can often expose more ergonomic APIs by accepting a single object with multiple properties as a parameter instead of forcing our API consumers to remember the order of many individual parameters. We can use destructuring to avoid repeating this single parameter object whenever we want to reference one of its properties:

function removeBreakpoint({ url, line, column }) {
  // ...
}

This is a simplified snippet of real world code from the Firefox DevTools JavaScript debugger (which is also implemented in JavaScript—yo dawg). We have found this pattern particularly pleasing.

Configuration object parameters

Expanding on the previous example, we can also give default values to the properties of the objects we are destructuring. This is particularly helpful when we have an object that is meant to provide configuration and many of the object’s properties already have sensible defaults. For example, jQuery’s ajax function takes a configuration object as its second parameter, and could be rewritten like this:

jQuery.ajax = function (url, {
  async = true,
  beforeSend = noop,
  cache = true,
  complete = noop,
  crossDomain = false,
  global = true,
  // ... more config
}) {
  // ... do stuff
};

So this get idefiend in ES6 because in ES5 dev were doing things like that

function something( options ) {
    var foo = options.foo;
    var bar = options.bar;
}

But wether JS/ES6 got this feature and AS3 does not have it does not make one or the other langaueg better or worst.

It’s like enum, you can see dev arguing to lenght that withotu enum such or such language sucks

by default in AS3 we don’t have enum and so we do things like that

public class OperatingSystem
{
    public static const UNKNOWN:String = "unknown";
    public static const WINDOWS:String = "windows";
    public static const MACINTOSH:String = "macintosh";
    public static const LINUX:String = "linux";
}

and you pass those kind of contant as parameters

public function doSomethingWith( os:String ):void
{
    //...
}

eg. doSomethingWith( OperatingSystem.WINDOWS );

This is OK’ish in the sense that those strings are organised in a class etc.
but yeah you’re passing a strign as argument and so you could pass any string
doSomethingWith( "garbage" );

but when your programming languager has enough features you can “emulate” enum

for ex

public class OperatingSystem
{

    public static const Unknown:OperatingSystem = new OperatingSystem( 0, "unknown" );
    public static const Windows:OperatingSystem = new OperatingSystem( 1, "windows" );
    public static const Macintosh:OperatingSystem = new OperatingSystem( 2, "macintosh" );
    public static const Linux:OperatingSystem = new OperatingSystem( 3, "linux" );

    private var _index:uint;
    private var _value:String;

    public function OperatingSystem( index:uint = 0,
                                     value:String = "unknown" )
    {
        _index = index;
        _value = value;
    }
}

you would do that to enforce the type of a parameter ina function

public function doSomethingWith( os:OperatingSystem ):void
{
    //...
}

eg. doSomethingWith( OperatingSystem.Windows );
and if you try to pass any other type than an OperatingSystem type
then it will be caught early by the compiler.

So you use the OO to enforce a type where it is needed because you don’t want users to pass any strings and break your program.

But there is still a flaw, users may want to extend those simili enums or create new ones and if the class is already compiled and used as a library they not gonna be able to do that.

My point here is just to say that: either your programmign language gets in your way or not.

I think AS3 has enough features, I would be caught dead writing AS1 or AS2 code because those, even if they are OK’ish, really miss features to the point it get in my way when I write code; but even if you can make a long list of “missing features” in AS3 wether it is enum, abstract class, whatever really, still AS3 does not get in my way.

After, depending on the developpers things can be more important or less important, for ex in my case if I had to chose between const and enum, I will chose const all the time because I do know enum are not that important and I can emulate them where it matters, also why I will chose AS3 over Haxe any time.