<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1256">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<div>
<div>
<div style="font-family:Calibri,sans-serif; font-size:11pt"></div>
</div>
<div dir="ltr">
<hr>
<span style="font-family:Calibri,sans-serif; font-size:11pt; font-weight:bold">From:
</span><span style="font-family:Calibri,sans-serif; font-size:11pt"><a href="mailto:jason.orendorff@gmail.com">Jason Orendorff</a></span><br>
<span style="font-family:Calibri,sans-serif; font-size:11pt; font-weight:bold">Sent:
</span><span style="font-family:Calibri,sans-serif; font-size:11pt">2014-06-17 15:22</span><br>
<span style="font-family:Calibri,sans-serif; font-size:11pt; font-weight:bold">To:
</span><span style="font-family:Calibri,sans-serif; font-size:11pt"><a href="mailto:allen@wirfs-brock.com">Allen Wirfs-Brock</a></span><br>
<span style="font-family:Calibri,sans-serif; font-size:11pt; font-weight:bold">Cc:
</span><span style="font-family:Calibri,sans-serif; font-size:11pt"><a href="mailto:es-discuss@mozilla.org">EcmaScript</a>;
<a href="mailto:erights@gmail.com">Mark Miller</a></span><br>
<span style="font-family:Calibri,sans-serif; font-size:11pt; font-weight:bold">Subject:
</span><span style="font-family:Calibri,sans-serif; font-size:11pt">@@new</span><br>
<br>
</div>
</div>
<font size="2"><span style="font-size:10pt;">
<div class="PlainText">Allen asked me to fill out what @@new would mean. Here it is.<br>
<br>
<br>
## How `new X` works<br>
<br>
`new X(...args)` ==== `X[@@new](...args)`<br>
<br>
<br>
## How it works for ES5 builtin constructors<br>
<br>
`Number(value)` is specified in one section.<br>
<br>
`Number[@@new](value)` is specified in another section.<br>
<br>
To support subclassing, `Number[@@new]()`, unlike ES5 [1], would set the<br>
new object's prototype to `this.prototype` rather than `Number.prototype`.<br>
Otherwise it all works just like ES5.<br>
<br>
The same goes for Object, Array, Function, Date, and the other builtins.<br>
<br>
<br>
## How it works for regular functions<br>
<br>
`Function.prototype[@@new](...arguments)` is called. It works like this:<br>
<br>
1.  Let proto = `this.[[Get]]("prototype", this)`.<br>
<br>
2.  If proto is not an object, throw a TypeError.<br>
<br>
3.  Let obj = ObjectCreate(proto).<br>
<br>
4.  If the this value or any object on its prototype chain is an ECMAScript<br>
    language function (not a class), then<br>
<br>
    a.  Let F be that object.<br>
<br>
    b.  Let result = `F.[[Call]](obj, arguments)`.<br>
<br>
    c.  If Type(result) is Object then return result.<br>
<br>
5.  Return obj.<br>
<br>
For regular functions, this behaves exactly like the `[[Construct]]` internal<br>
method in ES5 [2]. Step 4 is there to support regular functions and ES6 classes<br>
that subclass regular functions.<br>
<br>
<br>
## How it works for ES6 classes<br>
<br>
The special `constructor` method in ClassDeclaration/ClassExpression syntax<br>
would desugar to a static @@new method. This class:<br>
<br>
    class Point {<br>
        constructor(x = 0, y = 0) {<br>
            this.x = x;<br>
            this.y = y;<br>
        }<br>
    }<br>
<br>
would amount to this:<br>
<br>
    class Point {<br>
        static [Symbol.new](x = 0, y = 0) {<br>
            var obj = super[Symbol.new]();<br>
            obj.x = x;<br>
            obj.y = y;<br>
            return obj;<br>
        }<br>
    }<br>
<br>
As in the current drafts, ES6 would have to do something mildly fancy (see [3]<br>
and step 8 of [4]) to perform the desugaring.<br>
<br>
If a class has no `constructor` method, it inherits the base class's static<br>
@@new method.<br>
<br>
The "super Arguments" call syntax in the ES6 drafts would be constrained to<br>
appear only at the top of a constructor, as in Java:<br>
<br>
    class PowerUp {<br>
        constructor(name, price) { ... }<br>
    }<br>
<br>
    class RocketPack extends PowerUp {<br>
        constructor() {<br>
            super("Rocket Pack", 1000);<br>
            this.fuel = FULL_TANK;<br>
        }<br>
    }<br>
<br>
The RocketPack constructor would behave like this:<br>
<br>
        static [Symbol.new]() {<br>
            var obj = super[Symbol.new]("Rocket Pack", 1000);<br>
            obj.fuel = FULL_TANK;<br>
            return obj;<br>
        }<br>
<br>
This has different runtime semantics compared the `super()` syntax in the<br>
current ES6 draft, but it serves the same purpose.<br>
<br>
And that's all.<br>
<br>
<br>
## Benefits<br>
<br>
*   As with Allen's proposal, we would drop [[Construct]] and the `construct`<br>
    trap.<br>
<br>
*   Instances of builtin classes are never exposed to scripts before<br>
    their internal slots are fully initialized.<br>
<br>
*   @@create can be dropped entirely, but we retain the benefit to implementers<br>
    that all Maps (for example) can have the same in-memory layout, and other<br>
    objects can't become Maps at runtime.<br>
<br>
*   Base class constructors are always called.<br>
<br>
*   The ES6 draft language in [5] step 5, and many other similar places, would<br>
    be backed out. ("If Type(O) is Object and O has a [[NumberData]] internal<br>
    slot and the value of [[NumberData]] is undefined, then...")<br>
<br>
*   The current ES6 draft specifies new builtin constructors (Map, Set,<br>
    WeakMap) to throw a TypeError if called without `new`. This new convention<br>
    could be reversed to what ES5 does with Function and Array: `Map()` would<br>
    be the same as `new Map()`. User-defined classes could work this way too.<br>
    I think developers would appreciate this.<br>
<br>
*   These productions would be dropped from the ES6 grammar:<br>
<br>
        MemberExpression : new super Arguments<br>
        NewExpression : new super<br>
<br>
    If for whatever reason users want these, they can call<br>
    `super[Symbol.new]()`. But I think they will no longer be needed.<br>
<br>
    This would reduce the number of `super` forms to these 3:<br>
<br>
        super.IdentifierName  // allowed in all methods<br>
        super[Expression]     // allowed in all methods<br>
        super(arguments)      // only allowed in constructors<br>
<br>
<br>
[1]: <a href="http://people.mozilla.org/~jorendorff/es5.1-final.html#sec-15.7.2.1">
http://people.mozilla.org/~jorendorff/es5.1-final.html#sec-15.7.2.1</a><br>
"ES5 new Number ( [ value ] )"<br>
[2]: <a href="http://people.mozilla.org/~jorendorff/es5.1-final.html#sec-13.2.2">
http://people.mozilla.org/~jorendorff/es5.1-final.html#sec-13.2.2</a><br>
"ES5 [[Construct]]"<br>
[3]: <a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-static-semantics-constructormethod">
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-static-semantics-constructormethod</a><br>
"ES6 Static Semantics: ConstructorMethod"<br>
[4]: <a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-classdefinitionevaluation">
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-classdefinitionevaluation</a><br>
"ES6 Runtime Semantics: ClassDefinitionEvaluation"<br>
[5]: <a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number-constructor-number-value">
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number-constructor-number-value</a><br>
"ES6 Number ( [ value ] )"<br>
_______________________________________________<br>
es-discuss mailing list<br>
es-discuss@mozilla.org<br>
<a href="https://mail.mozilla.org/listinfo/es-discuss">https://mail.mozilla.org/listinfo/es-discuss</a><br>
</div>
</span></font>
</body>
</html>