Insurrection (was: ES4 draft: Object)
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
> 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
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
> 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
> 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.
More information about the Es4-discuss