Tom Van Cutsem (2014-06-13T10:33:39.000Z)
Interesting. It'd be nice if we could further simplify the Proxy/Reflect
API. Given the local nature of these changes, we might still include it in
ES6 if we achieve quick consensus.

As Allen mentioned, this came up a number of times in TC39 meetings and I
believe the fear for exotic objects that require control over [[Construct]]
was the biggest show-stopper. If more knowledgeable people like Boris can
vouch for the fact that this isn't the case, that would remove the biggest
roadblock.

Scott is right: Reflect.construct essentially directly calls [[Construct]],
so the Reflect API already provides the power to construct objects without
the new operator. There are no security concerns that I can spot. Cc'ing
Mark.

One important detail:

Jason proposes:
    new C(...args) => C[Symbol.new](...args)

Allen proposes:
   new C(...args) =>  C.apply(C[Symbol.create](), args)

I prefer Jason's transformation for the following reason: imagine a proxy
that wants to implement e.g. a flyweight pattern (i.e. it wants to pool or
cache objects, rather than constructing a fresh object for each call to
|new|). This is trivial to do with Jason's transformation, because the
proxy is in control of *both* object allocation and initialization. With
Allen's transformation, we need to jump through some hoops if the cached
object returned by Symbol.create depends on args (which is common for
flyweights), as they only get passed in after Symbol.create returns.

We can debate whether C[Symbol.new] should be called with args collected in
an array or spliced. I have no preference.

Cheers,
Tom




2014-06-12 22:56 GMT+02:00 C. Scott Ananian <ecmascript at cscott.net>:

> On Thu, Jun 12, 2014 at 3:21 PM, Allen Wirfs-Brock
> <allen at wirfs-brock.com> wrote:
> > It's not obvious to me why we would need @@new in addition to @@create
> (which is pretty much equivalent to saying it's not clear to me why we need
> [[Construct]]). For the ordinary case, @@new would just be another level of
> method lookup and invocation that would be required on each new.  While we
> expect implementations to (eventually)  optimize all of this, we still
> tried to minimize the amount of boiler plate work required for each new.
>
> From my perspective, it's about simplifying the language.  I like the
> fact that 'new C' is "just" sugar for an ordinary method invocation on
> C.  It would simplify the presentation of the spec as well: various
> places that currently state special behavior for "new XYZ" forms could
> instead describe the ordinary method XYZ.@@new.   And as Jason points
> out, this conceptual simplification of the language translates into
> concrete API simplifications for reflective operations like Proxies.
>
> I don't think there are any special security issues involved, since I
> can already do: `let x = Reflect.construct.bind(Reflect, C)` and pass
> that around.
>   --scott
>
> (fwiw, Crockford's "Simplified JavaScript" in
> http://javascript.crockford.com/tdop/tdop.html and my own
> "TurtleScript" subset of JavaScript in
> https://github.com/cscott/TurtleScript both did away with the new
> operator.  TurtleScript replaced it with `Function#New`.)
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140613/45a0fe93/attachment.html>
domenic at domenicdenicola.com (2014-06-20T19:36:46.996Z)
Interesting. It'd be nice if we could further simplify the Proxy/Reflect
API. Given the local nature of these changes, we might still include it in
ES6 if we achieve quick consensus.

As Allen mentioned, this came up a number of times in TC39 meetings and I
believe the fear for exotic objects that require control over [[Construct]]
was the biggest show-stopper. If more knowledgeable people like Boris can
vouch for the fact that this isn't the case, that would remove the biggest
roadblock.

Scott is right: Reflect.construct essentially directly calls [[Construct]],
so the Reflect API already provides the power to construct objects without
the new operator. There are no security concerns that I can spot. Cc'ing
Mark.

One important detail:

Jason proposes:

    new C(...args) => C[Symbol.new](...args)

Allen proposes:

    new C(...args) =>  C.apply(C[Symbol.create](), args)

I prefer Jason's transformation for the following reason: imagine a proxy
that wants to implement e.g. a flyweight pattern (i.e. it wants to pool or
cache objects, rather than constructing a fresh object for each call to
|new|). This is trivial to do with Jason's transformation, because the
proxy is in control of *both* object allocation and initialization. With
Allen's transformation, we need to jump through some hoops if the cached
object returned by Symbol.create depends on args (which is common for
flyweights), as they only get passed in after Symbol.create returns.

We can debate whether `C[Symbol.new]` should be called with args collected in
an array or spliced. I have no preference.