Insurrection (was: ES4 draft: Object)

Dave Herman dherman at ccs.neu.edu
Tue Mar 11 05:49:52 PDT 2008


Hi Mark, I agree with a number of your objections. I hope you don't mind 
if I try to distinguish between some of the points I agree with and 
disagree with.

> The current fad in language design is expressive static type systems.
> As a result, several recent type systems have grown eat their
> language. Java 1.5 is a particularly nasty example. Simple bits of
> Java code become so overwhelmed by complex type declarations as to
> obscure the logic of the code itself. Proposed ES4 suffers from the
> same disease, though it has not (yet) come down with as bad a case as
> Java.

I'd love for us to get past the points about popularity and fads. I know 
that static types are all the rage and that dynamic languages have 
consequently suffered in the court of popular opinion. I'm a member of 
the Scheme community so I feel it acutely.

But I'm skeptical of your comparison to Java 5. Java is a statically 
typed language that gained even more types. The ES4 proposal is a 
dynamic language with optional type annotations. These are there to help 
people when they feel that types would serve to document their code and 
type checking would help improve the robustness of their code and/or 
make the kinds of ad-hoc checking (hand-written assertions) cleaner. 
When people don't feel they add value, they don't have to use them.

In Java 5, you're locked in to complex type annotations and can't get 
out. An important design goal in the ES4 type system has been to make 
the relationship between typed and untyped code relaxed enough that this 
doesn't happen.

> Even ignoring ES4's type system, ES4 adds all the following
> abstraction mechanisms to those in ES3:
> * classes
> * packages
> * units
> * namespaces

I'm sympathetic-- I've always been uncomfortable with packages and 
namespaces. (My reaction to units was more hopeful, since the global 
object is so problematic in ES3, but I'm not yet up to speed on the 
proposal.)

> If instead classes, for example, were defined purely by syntactic
> expansion to the constructs in ES3.1, then classes would inherit the
> lexical nestability of the constructs they expand into. Even Java's
> classes are lexically nestable!

Nestability is a good design goal, and I'm glad you brought it up.

Syntactic expansion has many benefits, too, of course. I just want to 
point out the main pitfall in making classes syntactic sugar. One of the 
real problems with ES3 is the inability to make guarantees about any 
bindings except for lexical ones. With vanilla ES3 objects, there's no 
way to share information between (conceptual) modules of code and 
preserve the integrity of the container, unless you either a) hide the 
data in a closure or b) copy the data into a dummy container.

Classes, in addition to being a well-understood mechanism and the de 
facto style of the JS community, should help the programmer protect the 
integrity of their bindings. For example, a class declaration in ES4 
creates "fixtures" for its properties-- meaning that the programmer can 
rely on them not being deleted. The current ad hoc approaches in use in 
ES3 can't guarantee that, and manually using closures is too heavyweight.

That said, you've hinted at alternative approaches, perhaps with 
constructs desugaring to closures of some sort:

> The namespace mechanism seems motivated by a failure to appreciate the
> power available by modest extensions of simple lambda abstraction.

I'd certainly like to hear what you're thinking here.

> Why should we prefer foo::bar::baz?
> What is gained by having two mechanisms?

Fair criticisms (and I personally feel the namespace mechanism is one of 
the most deserving of criticism). Primarily, the purpose it's serving is 
a way to protect object properties with a "key" that you can then 
control via e.g. lexical hiding. The Foo.Bar.baz pattern in ES3 doesn't 
provide a way to hide such bindings.

> When I first read the overview, I was puzzled by the lack of
> uniformity between the types [int] and [int, String]. IIUC, the first
> represents the type of all arrays *all* of whose elements are ints.

That's not my understanding. IIRC, for a type [T1,...,Tn,Tn+1] there are 
required to be zero or more array elements of Tn+1. So [int] is the type 
of arrays with zero or more ints, and [int, String] is the type of 
arrays with an int at index 0 followed by zero or more Strings.

I'll grant that this is unconventional. But it's an attempt to make the 
type structure match actual usage in JS: people use arrays both as 
arrays and as tuples. So we have a type that accomodates the idiomatic 
usage of the language.

Dave



More information about the Es4-discuss mailing list