Jussi Kalliokoski (2014-06-13T19:07:36.000Z)
On Fri, Jun 13, 2014 at 8:21 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>
wrote:

>
> On Jun 13, 2014, at 8:05 AM, C. Scott Ananian wrote:
>
> > On Fri, Jun 13, 2014 at 6:33 AM, Tom Van Cutsem <tomvc.be at gmail.com>
> wrote:
> >> Jason proposes:
> >>    new C(...args) => C[Symbol.new](...args)
> >>
> >> Allen proposes:
> >>   new C(...args) =>  C.apply(C[Symbol.create](), args)
> >
> > Consider also the way the spec could read.  For example, for the
> > 'Error' object, instead of having "19.5.1.1 Error ( message )" and
> > "19.5.1.2 new Error ( ...argumentsList )", in Jason's formulation
> > section 19.5.1.2 would just be "Error[ @@new ]]", aka an ordinary
> > method definition.  "If Error is implemented as an ECMAScript function
> > object, its inherited implementation of @@new will perform the above
> > steps."
> >
>
> The existence or not of @@new doesn't make a difference in that regard.
>  The only reason we current need the "new Foo(...)" specifications is
> because [[Construct]] exists and built-ins are not necessarily ECMAScript
> functions so we have to say what their [[Construct]] behavior is.
>
> If [[Construct]] was eliminated that reason would go away and there would
> be no need for the "new Foo(...) built-in specifications.
>

Yes, please. The whole concept of [[Construct]] is just very confusing in
my opinion, and makes especially little sense from the userland
perspective. For a userland function, it's practically impossible to
statically analyze whether that function is a constructor or not, consider
these for example:
https://gist.github.com/jussi-kalliokoski/7f86ff181a01c671d047 . Which of
them are constructors and which are not? And how can you tell?
IsConstructor would have to say `true` for every JS-defined function out
there to give even close to usable results, and say `false` only for
host-defined functions. If we were to then use IsConstructor anywhere, it
would deepen the gap between host objects and native objects even further,
which I don't think anyone wants. In JS itself (as it currently is),
depending on how you think about it, there either aren't constructors at
all or every function is a constructor.


> The only difference between inlining ordinary [[Construct]] into the 'new'
> operator semantics and defining the 'new' operator as invoking @@new is the
> amount of freedom anES programmer would have in defining how a @@create
> method relates to its companion  constructor function. Without @@new there
> is a fixed protocol for how @@create and the constructor function are
> invoked relative to each other.  With @@new a different protocol (including
> ones that completely ignores @@create and the constructor function) could
> be implemented in ES code.
>
> It isn't clear if there are really any use cases that could be supported
> by @@new that couldn't also be support by carefully crafting a @@create and
> companion constructor function.
>
> Anotherconcern I have with @@new, it that it exposes two extension points,
> @@new and @@create, on very constructor.  I'm afraid that it wouldn't be
> very clear to most ES programmers when you should over-ride one or the
> other.
>
> Finally, let's say that for ES6 we eliminate [[Construct]] without adding
> @@new. If after some experience we find that @@new is really needed we can
> easily add it in a backwards compatible manner.
>

To me this sounds like a very reasonable idea, +100, but of course I'm not
too well aware of how widely it's used.

One question about @@create though... What would this do:

function Foo () {}

Foo.prototype[Symbol.create] = null;

// ???
// Maybe error out, like currently host objects without [[Construct]]:
// TypeError: Foo is not a constructor.
new Foo();

- Jussi


>
> Allen
> _______________________________________________
> 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/e12d8c50/attachment.html>
domenic at domenicdenicola.com (2014-06-20T19:42:30.748Z)
On Fri, Jun 13, 2014 at 8:21 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

> If [[Construct]] was eliminated that reason would go away and there would
> be no need for the "new Foo(...) built-in specifications.

Yes, please. The whole concept of [[Construct]] is just very confusing in
my opinion, and makes especially little sense from the userland
perspective. For a userland function, it's practically impossible to
statically analyze whether that function is a constructor or not, consider
these for example:
https://gist.github.com/jussi-kalliokoski/7f86ff181a01c671d047 . Which of
them are constructors and which are not? And how can you tell?
IsConstructor would have to say `true` for every JS-defined function out
there to give even close to usable results, and say `false` only for
host-defined functions. If we were to then use IsConstructor anywhere, it
would deepen the gap between host objects and native objects even further,
which I don't think anyone wants. In JS itself (as it currently is),
depending on how you think about it, there either aren't constructors at
all or every function is a constructor.


> Finally, let's say that for ES6 we eliminate [[Construct]] without adding
> @@new. If after some experience we find that @@new is really needed we can
> easily add it in a backwards compatible manner.

To me this sounds like a very reasonable idea, +100, but of course I'm not
too well aware of how widely it's used.

One question about @@create though... What would this do:

```js
function Foo () {}

Foo.prototype[Symbol.create] = null;

// ???
// Maybe error out, like currently host objects without [[Construct]]:
// TypeError: Foo is not a constructor.
new Foo();
```