Allen Wirfs-Brock wrote:

On May 24, 2012, at 1:50 PM, Erik Arvidsson wrote:

I think it is impossible to achieve Waldemar's goal with syntactic
sugar only. I also don't think that is reason enough to block ES6
classes. The requirements he wants cannot be expressed with ES5
semantics.

I'm actually rather this disinclined to play this game. As soon as you
put "const" in front of "class" you have a whole new construct within
which you can define pretty much any syntax and semantics you want as
long as you think users will find them acceptable. Hence there is very
little need to "prove" anything here.

But, who can resist a design challenge...

The big issues Waldemar wanted were (as far as I remember):

1. Reading a non existent property should throw:

const class C {}
const c = new C;
console.log(c.foo); // throw to catch typos

This is a major change in semantics of JS and it was shot down for ES5
strict so I don't think it has any chance of getting accepted ever.

The specification framework is all in place to support this. Objects
created via a const class constructor could be an alternative version of
[[Get]] (http://ecma-international.org/ecma-262/5.1/#sec-8.12.3 remember
to say "thank you Jason") that throws in step 2.


2. No way for an object to escape the constructor before the
constructor was "done":

BTW you can not guarantee this at all. Because of super constructors that are not const. imo.


const class C {
constructor() {
this.x = doSomething(this); // oops, this.y is not yet initialized
this.y = doSomethingElse();
}

lots of ways to approach this, but a simple way to prevent a value from
escaping is simply to not provide any way to reference it. Hence, don't
bind |this| in the body of a const constructor. Provide an
alternativenon value producing way to refer to the uninitialized
instance within the constructor body. For example, __this__ (I'm being
intentionally ugly) that can only occur as the base of a Reference that
is produced by the LHSExpression on the left of a = operator. eg:

Why use any ugly thing like __this__, when plain 'this' could be used as well (and static analysis will only allow it to be use as the base of a Reference that is produces by the LHSExpression)?

(correct me if I am wrong and have missed something, but it seems to me 'this' is fine as-is when I know the context is const-constructor)


const class C{
constructor() {
__this__.x = 0;
__this.__y = doSomething(this); //oops, this isn't defined here
}
}

or with additional sugar:

const class C{
constructor() {
initialize { //new special form
__this__.x = 0;
__this.__y = doSomething(this); //oops, this isn't defined here
} then {
CManager.memorize(this); //ok to reference this here
};
}
}

class C {
  constructor() {
    const; // constant part
    this.x = 0;
    this.y = doSomething(this); //oops
    var; // variable (modifiable) part
    CManager.memorize(this);
  }
}

Alternatives here include read barriers but that also requires
declarative instance properties so we know ahead of time what to
poison.

3. Shape guarantee:

const class C {
constructor() {
if (Math.random() < .5)
this.x = true; // Half of the times there will not be an x property.
}

The problems with these is that no other dynamic language has these
kind of requirements. JS developers get by without them today. If we
designed a new language I think they would be nice features to have
(ahem Dart) but our goal is to improve ECMAScript and not replace it.
We should not try to make all languages fit into the same box.

Smalltalk objects have a fixed shape...

Building upon the approach above

const class C{
instance {x,y} //announce the shape
constructor() {
__this__.x = 0;
__this.__y = doSomething(this); //oops, this isn't defined here
//post condition: x and y are initialized. Can be either statically
proven or dynamically checked
}
}

class C {
  constructor() {
    const {x,y}; // constant part, annoucing the shape
    this.x = 0;
    this.y = doSomething(this); //oops
    //post condition: x and y are initialized. Can be either statically
    var; // variable (modifiable) part
    CManager.memorize(this);
  }
}




At this point I think it is up to Waldemar and supporters of his
requirements to come up with concrete proposals how these things can
fit into ECMAScript. (Thanks Russel for starting this thread.)

And since there are so many possible ways of doing this and max/min
classes constrains so little, it is hard to see why this should be a
blocking issue.

Allen

Herby
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to