Determine if a value is Callable/Constructible

classic Classic list List threaded Threaded
43 messages Options
123
Reply | Threaded
Open this post in threaded view
|

RE: Determine if a value is Callable/Constructible

Domenic Denicola
I don’t think [Symbol.call] is a very good mechanism. A new syntactic form would make more sense.

It doesn’t seem right that you should have to introduce an observable prototype property just to get [[Call]] behavior. (Or a constructor property, if you change the syntax to `static [Symbol.call]() { … }`.)

And it raises the question of what happens when I add a [Symbol.call] property to other objects. What does it even mean? If I do `var obj = { prototype: { [Symbol.call]() { console.log("foo"); } } }`, can I now call `obj()`? Is `typeof obj === "function"`? Very strange stuff. Presumably not very VM-friendly either, but that's just a guess.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Determine if a value is Callable/Constructible

Domenic Denicola
In reply to this post by Caitlin Potter
Great to get the ball rolling. Here's some issues I'd bring up at the meeting, so we can get a head start:

- As discussed recently in https://esdiscuss.org/topic/reflect-getownpropertysymbols, right now Reflect only holds counterparts to the proxy traps. I think this is kind of a nice property. Do we want to expand Reflect into a dumping ground for all "reflective" operations? That's been implied many times on the list, but so far hasn't happened, from what I can see. On the other hand, I don't have any good ideas for where else to put these things. (Maybe Function.isConstructor? Not sure it scales.)

- Reflect.isCallable seems pretty pointless, when you can just do `typeof x === "function"`. YAGNI IMO. Note that it also doesn't match your earlier description from https://esdiscuss.org/topic/determine-if-a-value-is-callable-constructible#content-0, so it presumably doesn't solve those use cases. (But that definition can't really be workable, since all of the things you mention as not being callable are actually callable, in the same way `function f() { throw new TypeError(); }` is callable.)

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Caitlin Potter
In reply to this post by Yehuda Katz
>>But in either case, these (IsCallable / IsConstructor) are pretty basic qualities of objects that a Reflection* api ought to be able to read into, imho.
>
>What Allen is saying is that the implementation of "throw if constructor" doesn't work by not implementing [[Call]], but rather by implementing [[Call]] to
>throw, so those reflective APIs would say the wrong thing, and that this is observable via proxies.

It’s a fair point, constructors do have a [[Call]] internal method — there’s no reason this needs to be described this way though. Instead of the extra step for classConstructors in 9.2.1, class constructors could just as easily not have a [[Call]] method at all (by default). I guess what I’m getting at is, right now they aren’t “really” callable, it’s just that the way their non-callable-ness is expressed makes them appear callable (which probably should not be the case). Since they’re intrinsically not callable (currently), they shouldn’t be treated as callable.

What Domenic is saying later on makes sense, the magic “call-code” method (should it ever exist) shouldn’t be a property of the class prototype, so a special syntactic form would work better (but also be kind of awful, too).

>
> Allen, can you say more about why you spec'ed it that way?
>  
>
> >
> >
> >> On Mar 29, 2015, at 11:51 PM, Caitlin Potter <[hidden email]> wrote:
> >>
> >> ...
> >>
> >> Reflect.isConstructor(fn) -> true if Class constructor, generator, or legacy (and non-builtin) function syntactic form
> >> Reflect.isCallable(fn) -> true for pretty much any function, except for class constructors and a few builtins
> >
> > I’ve already seen another situation (node’s Buffer) where code could be simplified by using a ES6 class definition but where that is prevented because a class constructor throws when called.
> >
> > Just to clarify something.  Class constructors actually are “callable”.  You can observe this by the fact that Proxy allows you to install an “apply” handler (the reification of the [[[Call]] internal method) on a class constructor.   The the fact that an object can be [[Call]]’ed is already reflected  by the typeof operator.  Class constructors throw when called because at the last minute we choose to make their [[Call]] do an explicit throw not because they aren’t callable.
> >
> > There is no intrinsic reason why we needed to mandate that class constructors should throw when called.  We even provided a simple and straight forward way (new.target===undefined) that a ES constructor body can use to determine whether it was called or new’ed.
> >
> > I think we should just drop that throws when called feature of class constructors..
> >
> > (The restriction was added to future proof for the possibility of inventing some other way to provide a class with distinct new/call behavior. I don’t think we need nor can afford to wait for the invention of a new mechanism which will inevitably be more complex than new.target, which we already have.)
> >
> > Allen
> >
> >
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Determine if a value is Callable/Constructible

Domenic Denicola
If you made them non-callable by not implementing [[Call]], then typeof would no longer return "function", which would be ... O_o.

> -----Original Message-----
> From: es-discuss [mailto:[hidden email]] On Behalf Of
> Caitlin Potter
> Sent: Monday, March 30, 2015 11:25
> To: Yehuda Katz
> Cc: [hidden email]
> Subject: Re: Determine if a value is Callable/Constructible
>
> >>But in either case, these (IsCallable / IsConstructor) are pretty basic
> qualities of objects that a Reflection* api ought to be able to read into, imho.
> >
> >What Allen is saying is that the implementation of "throw if
> >constructor" doesn't work by not implementing [[Call]], but rather by
> implementing [[Call]] to throw, so those reflective APIs would say the wrong
> thing, and that this is observable via proxies.
>
> It’s a fair point, constructors do have a [[Call]] internal method — there’s no
> reason this needs to be described this way though. Instead of the extra step
> for classConstructors in 9.2.1, class constructors could just as easily not have a
> [[Call]] method at all (by default). I guess what I’m getting at is, right now
> they aren’t “really” callable, it’s just that the way their non-callable-ness is
> expressed makes them appear callable (which probably should not be the
> case). Since they’re intrinsically not callable (currently), they shouldn’t be
> treated as callable.
>
> What Domenic is saying later on makes sense, the magic “call-code” method
> (should it ever exist) shouldn’t be a property of the class prototype, so a
> special syntactic form would work better (but also be kind of awful, too).
>
> >
> > Allen, can you say more about why you spec'ed it that way?
> >
> >
> > >
> > >
> > >> On Mar 29, 2015, at 11:51 PM, Caitlin Potter <[hidden email]>
> wrote:
> > >>
> > >> ...
> > >>
> > >> Reflect.isConstructor(fn) -> true if Class constructor, generator,
> > >> or legacy (and non-builtin) function syntactic form
> > >> Reflect.isCallable(fn) -> true for pretty much any function, except
> > >> for class constructors and a few builtins
> > >
> > > I’ve already seen another situation (node’s Buffer) where code could be
> simplified by using a ES6 class definition but where that is prevented because
> a class constructor throws when called.
> > >
> > > Just to clarify something.  Class constructors actually are “callable”.  You
> can observe this by the fact that Proxy allows you to install an “apply” handler
> (the reification of the [[[Call]] internal method) on a class constructor.   The
> the fact that an object can be [[Call]]’ed is already reflected  by the typeof
> operator.  Class constructors throw when called because at the last minute
> we choose to make their [[Call]] do an explicit throw not because they aren’t
> callable.
> > >
> > > There is no intrinsic reason why we needed to mandate that class
> constructors should throw when called.  We even provided a simple and
> straight forward way (new.target===undefined) that a ES constructor body
> can use to determine whether it was called or new’ed.
> > >
> > > I think we should just drop that throws when called feature of class
> constructors..
> > >
> > > (The restriction was added to future proof for the possibility of
> > > inventing some other way to provide a class with distinct new/call
> > > behavior. I don’t think we need nor can afford to wait for the
> > > invention of a new mechanism which will inevitably be more complex
> > > than new.target, which we already have.)
> > >
> > > Allen
> > >
> > >
> >
> > _______________________________________________
> > es-discuss mailing list
> > [hidden email]
> > https://mail.mozilla.org/listinfo/es-discuss
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Caitlin Potter

> If you made them non-callable by not implementing [[Call]], then typeof would no longer return "function", which would be ... O_o.


s/Object (implements [[Call]]) | “function” /Object (implements [[Call]] or [[FunctionKind]] is classConstructor) | “function”/g

Problem solved!

I jest — but making a constructor identifiable as a function while still noting that it’s not “really” callable is certainly possible


> On Mar 30, 2015, at 11:27 AM, Domenic Denicola <[hidden email]> wrote:
>
> If you made them non-callable by not implementing [[Call]], then typeof would no longer return "function", which would be ... O_o.
>
>> -----Original Message-----
>> From: es-discuss [mailto:[hidden email]] On Behalf Of
>> Caitlin Potter
>> Sent: Monday, March 30, 2015 11:25
>> To: Yehuda Katz
>> Cc: [hidden email]
>> Subject: Re: Determine if a value is Callable/Constructible
>>
>>>> But in either case, these (IsCallable / IsConstructor) are pretty basic
>> qualities of objects that a Reflection* api ought to be able to read into, imho.
>>>
>>> What Allen is saying is that the implementation of "throw if
>>> constructor" doesn't work by not implementing [[Call]], but rather by
>> implementing [[Call]] to throw, so those reflective APIs would say the wrong
>> thing, and that this is observable via proxies.
>>
>> It’s a fair point, constructors do have a [[Call]] internal method — there’s no
>> reason this needs to be described this way though. Instead of the extra step
>> for classConstructors in 9.2.1, class constructors could just as easily not have a
>> [[Call]] method at all (by default). I guess what I’m getting at is, right now
>> they aren’t “really” callable, it’s just that the way their non-callable-ness is
>> expressed makes them appear callable (which probably should not be the
>> case). Since they’re intrinsically not callable (currently), they shouldn’t be
>> treated as callable.
>>
>> What Domenic is saying later on makes sense, the magic “call-code” method
>> (should it ever exist) shouldn’t be a property of the class prototype, so a
>> special syntactic form would work better (but also be kind of awful, too).
>>
>>>
>>> Allen, can you say more about why you spec'ed it that way?
>>>
>>>
>>>>
>>>>
>>>>> On Mar 29, 2015, at 11:51 PM, Caitlin Potter <[hidden email]>
>> wrote:
>>>>>
>>>>> ...
>>>>>
>>>>> Reflect.isConstructor(fn) -> true if Class constructor, generator,
>>>>> or legacy (and non-builtin) function syntactic form
>>>>> Reflect.isCallable(fn) -> true for pretty much any function, except
>>>>> for class constructors and a few builtins
>>>>
>>>> I’ve already seen another situation (node’s Buffer) where code could be
>> simplified by using a ES6 class definition but where that is prevented because
>> a class constructor throws when called.
>>>>
>>>> Just to clarify something.  Class constructors actually are “callable”.  You
>> can observe this by the fact that Proxy allows you to install an “apply” handler
>> (the reification of the [[[Call]] internal method) on a class constructor.   The
>> the fact that an object can be [[Call]]’ed is already reflected  by the typeof
>> operator.  Class constructors throw when called because at the last minute
>> we choose to make their [[Call]] do an explicit throw not because they aren’t
>> callable.
>>>>
>>>> There is no intrinsic reason why we needed to mandate that class
>> constructors should throw when called.  We even provided a simple and
>> straight forward way (new.target===undefined) that a ES constructor body
>> can use to determine whether it was called or new’ed.
>>>>
>>>> I think we should just drop that throws when called feature of class
>> constructors..
>>>>
>>>> (The restriction was added to future proof for the possibility of
>>>> inventing some other way to provide a class with distinct new/call
>>>> behavior. I don’t think we need nor can afford to wait for the
>>>> invention of a new mechanism which will inevitably be more complex
>>>> than new.target, which we already have.)
>>>>
>>>> Allen
>>>>
>>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [hidden email]
>>> https://mail.mozilla.org/listinfo/es-discuss
>>
>> _______________________________________________
>> es-discuss mailing list
>> [hidden email]
>> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Kevin Smith
In reply to this post by Domenic Denicola
It doesn’t seem right that you should have to introduce an observable prototype property just to get [[Call]] behavior. (Or a constructor property, if you change the syntax to `static [Symbol.call]() { … }`.)

And it raises the question of what happens when I add a [Symbol.call] property to other objects. What does it even mean? If I do `var obj = { prototype: { [Symbol.call]() { console.log("foo"); } } }`, can I now call `obj()`? Is `typeof obj === "function"`? Very strange stuff. Presumably not very VM-friendly either, but that's just a guess.

I'd imagine that you'd re-spec [[Call]] for class constructors to basically do `this[Symbol.call](...args)` instead of just throw.  It would therefore only have an effect within class constructors.  Is that still weird?

Kevin

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Yehuda Katz
In reply to this post by Domenic Denicola


Yehuda Katz
(ph) 718.877.1325

On Mon, Mar 30, 2015 at 8:09 AM, Domenic Denicola <[hidden email]> wrote:
I don’t think [Symbol.call] is a very good mechanism. A new syntactic form would make more sense.

It doesn’t seem right that you should have to introduce an observable prototype property just to get [[Call]] behavior. (Or a constructor property, if you change the syntax to `static [Symbol.call]() { … }`.)

A new syntactic form sounds good to me :)
 

And it raises the question of what happens when I add a [Symbol.call] property to other objects. What does it even mean? If I do `var obj = { prototype: { [Symbol.call]() { console.log("foo"); } } }`, can I now call `obj()`? Is `typeof obj === "function"`? Very strange stuff. Presumably not very VM-friendly either, but that's just a guess.



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Determine if a value is Callable/Constructible

Domenic Denicola
In reply to this post by Kevin Smith
From: Kevin Smith [mailto:[hidden email]]

> I'd imagine that you'd re-spec [[Call]] for class constructors to basically do `this[Symbol.call](...args)` instead of just throw.  It would therefore only have an effect within class constructors.  Is that still weird?

At least it's explicable, but it's still pretty weird I think. I mean, we don't specify [[Construct]] by saying that it does `new this.prototype.constructor(...args)` or similar. The asymmetry is jarring.

And it's weird to have this symbol with such a generic name that doesn't work for anything except class syntax. I'd expect symbols to be for re-usable protocols... that's fuzzy intuition though, I admit, and might be contradicted by existing examples.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Yehuda Katz
On Mon, Mar 30, 2015 at 8:54 AM, Domenic Denicola <[hidden email]> wrote:
From: Kevin Smith [mailto:[hidden email]]

> I'd imagine that you'd re-spec [[Call]] for class constructors to basically do `this[Symbol.call](...args)` instead of just throw.  It would therefore only have an effect within class constructors.  Is that still weird?

At least it's explicable, but it's still pretty weird I think. I mean, we don't specify [[Construct]] by saying that it does `new this.prototype.constructor(...args)` or similar. The asymmetry is jarring.

And it's weird to have this symbol with such a generic name that doesn't work for anything except class syntax. I'd expect symbols to be for re-usable protocols... that's fuzzy intuition though, I admit, and might be contradicted by existing examples.

I like the idea of a special syntactic form a lot. One of the nice things about `constructor` is that it's easy to explain "you [[Construct]] with the constructor". We can't use `call` similarly any more, but I totally agree something like it would be pretty nice.

On the flip side, it's not entirely clear that allowing people to override [[Call]] on an existing function is a no-go. Changing the `typeof` via installing a symbol definitely seems like bad juju though.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Axel Rauschmayer
In reply to this post by Domenic Denicola
If you made them non-callable by not implementing [[Call]], then typeof would no longer return "function", which would be ... O_o.

In some way, that would even be correct – depending on what you expect a function to be: something callable or something constructible. Alas, there is currently no simple way to distinguish “callable” and “constructible”.

-- 
Dr. Axel Rauschmayer
[hidden email]
rauschma.de




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Kevin Smith
In reply to this post by Yehuda Katz
I like the idea of a special syntactic form a lot. One of the nice things about `constructor` is that it's easy to explain "you [[Construct]] with the constructor". We can't use `call` similarly any more, but I totally agree something like it would be pretty nice.

Unfortunately, we can't use a magic method name.  Just to throw out a couple of other ideas though: 

Parens sans method name:

    class C {
      constructor() { /* new me */ }
      () { /* call me */ }
    }

Contextual keyword after constructor:

    class C {
      constructor() { /* new me */ }
      constructor call() { /* call me */ }
    }

With a "dot" instead:

    class C {
      constructor() { /* new me */ }
      constructor.call() { /* call me */ }
    }



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Determine if a value is Callable/Constructible

Domenic Denicola
In reply to this post by Axel Rauschmayer
From: Axel Rauschmayer [mailto:[hidden email]]

> In some way, that would even be correct – depending on what you expect a function to be: something callable or something constructible. Alas, there is currently no simple way to distinguish “callable” and “constructible”.

Why do you say they're not callable?

Is this function callable?

    function f() {
      throw new TypeError("cannot call f because you're not pretty enough");
    }

what about


    function f() {
      throw new TypeError("Class constructors cannot be invoked without 'new'");
    }

?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Caitlin Potter
In reply to this post by Kevin Smith
>Unfortunately, we can't use a magic method name.  Just to throw out a couple of other ideas though: 

>Contextual keyword after constructor:
>
>    class C {
>      constructor() { /* new me */ }
>      constructor call() { /* call me */ }
>    }

This one looks like the most readable — I would make a slight adjustment:

    class C {
      constructor() { /* new me *. }
      call constructor() { /* call me */ }
    }

(just for the purpose of readability)

I think it might be hard to mix this up with computed property names, so `call [‘constructor’]()` might be a no-go? same with `[‘constructor’] call()` tbh

On Mar 30, 2015, at 12:20 PM, Kevin Smith <[hidden email]> wrote:

I like the idea of a special syntactic form a lot. One of the nice things about `constructor` is that it's easy to explain "you [[Construct]] with the constructor". We can't use `call` similarly any more, but I totally agree something like it would be pretty nice.

Unfortunately, we can't use a magic method name.  Just to throw out a couple of other ideas though: 

Parens sans method name:

    class C {
      constructor() { /* new me */ }
      () { /* call me */ }
    }

Contextual keyword after constructor:

    class C {
      constructor() { /* new me */ }
      constructor call() { /* call me */ }
    }

With a "dot" instead:

    class C {
      constructor() { /* new me */ }
      constructor.call() { /* call me */ }
    }




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Caitlin Potter
In reply to this post by Domenic Denicola
>On Mar 30, 2015, at 12:20 PM, Domenic Denicola <[hidden email]> wrote:
>
>Why do you say they're not callable?
>
>Is this function callable?
>
>   function f() {
>     throw new TypeError(“f immediately throws");
>   }

I think there’s a distinction here.

`function f() {}` might throw when called, but that’s in the author of the function’s control.

`class C {}` will always throw when called (in the current draft), so you can’t “really” consider it callable. No user-authored code is invoked when [[Call]]-ing a class constructor

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Axel Rauschmayer
In reply to this post by Domenic Denicola
In some way, that would even be correct – depending on what you expect a function to be: something callable or something constructible. Alas, there is currently no simple way to distinguish “callable” and “constructible”.

Why do you say they're not callable?

As in “makes sense to call”. In the past, `typeof x === 'function'” was an adequate test for checking whether it makes sense to call `x`. Since ES6, it isn’t, anymore. That’s why the checks proposed by Caitlin will be nice to have.

-- 
Dr. Axel Rauschmayer
[hidden email]
rauschma.de




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Determine if a value is Callable/Constructible

Domenic Denicola
From: Axel Rauschmayer [mailto:[hidden email]]

> As in “makes sense to call”. In the past, `typeof x === 'function'” was an adequate test for checking whether it makes sense to call `x`.

I tried to explain explicitly why I don't think this is true.

> Since ES6, it isn’t, anymore.

I disagree. The situation has not changed at all.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Caitlin Potter
>On Mar 30, 2015, at 1:44 PM, Domenic Denicola <[hidden email]> wrote:
>>From: Axel Rauschmayer [mailto:[hidden email]]
>>As in “makes sense to call”. In the past, `typeof x === 'function'” was an adequate test for checking whether it makes sense to call `x`.
>
I> tried to explain explicitly why I don't think this is true.
>
>>Since ES6, it isn’t, anymore.
>
>I disagree. The situation has not changed at all.

As I said above:

```js
var called = false;
function F() {
  called = true;
  throw new TypeError(“can’t call F()”);
}

F(); // Throws, but `called` is true

called = false;
class C {
  constructor() {
    called = true;
    throw new TypeError(“can’t call C()”);
  }
}

C(); // Throws, but `called` is false, because the constructor was never invoked
```

That distinction means that you can’t “really” [[Call]] a constructor, it’s just that the reason is slightly different from trying to [[Call]] an Array instance (or something)
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Determine if a value is Callable/Constructible

Domenic Denicola
The distinction you're really pointing to here is the distinction between user-generated throwing functions and runtime-generated ones. Both are called. User-generated ones you could edit the source code of and insert a `called = true` line first, whereas runtime-generated ones you could not. But that's not a real material difference in call-ability.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Determine if a value is Callable/Constructible

Caitlin Potter
I think we’re on the same page that the runtime is the one doing the throwing, but that doesn’t really matter. The point is, if you can’t actually invoke the authored code, you can’t really call the authored code “call-able”. To the VM, the difference doesn’t matter a whole lot, but to human beings, it does. It’s disingenuous to call it “call-able” if the authored code can’t be “called”. (A proxy trap doesn’t really make it “callable” either, it just allows different code to be “called” in its place).

It could still be identified as a “function” for compat with ES5, but the behaviour is different from any other sort of function, it should be identifiable as different.

> On Mar 30, 2015, at 1:54 PM, Domenic Denicola <[hidden email]> wrote:
>
> The distinction you're really pointing to here is the distinction between user-generated throwing functions and runtime-generated ones. Both are called. User-generated ones you could edit the source code of and insert a `called = true` line first, whereas runtime-generated ones you could not. But that's not a real material difference in call-ability.
>

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Determine if a value is Callable/Constructible

Domenic Denicola
> It could still be identified as a “function” for compat with ES5, but the
> behaviour is different from any other sort of function, it should be
> identifiable as different.

Right, but again, I don't think the behavior is any different from `function f() { throw new TypeError(); }`, so whatever the test you write returns for classes, my position is that it should return the same thing for `f`.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
123