[ES Harmony Proxies] type of function proxies which would not have a call trap

# David Bruant (15 years ago)

In ES5 11.4.3, which defines the semantics of typeof, is written that native objects (as proxies will be since they'll be within the scope of the spec) which do not implement a [[call]] trap should return "object" with typeof. Currently, the proxy spec doesn't separate the case when the call trap is defined or not.

Does not defining the call trap mean that [[call]] isn't implemented or does it mean that it is defined to a stub method?

In FF4b10, here are a couple of results:

typeof Proxy.createFunction({}, function(){}, function(){}); "function"

typeof Proxy.createFunction({}, function(){}, null);

TypeError: null is not a function

typeof Proxy.createFunction({}, function(){}, undefined);

TypeError: undefined is not a function

typeof Proxy.createFunction({}, function(){}); "function" (Is this inconsistent with passing explicitely undefined?)

typeof Proxy.createFunction({}, undefined);

TypeError: undefined is not a function

typeof Proxy.createFunction({}, null);

TypeError: null is not a function

typeof Proxy.createFunction({});

TypeError: createFunction requires more than 1 argument

In order to allow more flexibility, I would suggest to allow undefined/null as allowed values in order to not define either the [[call]] or [[construct]] internal method. This would obivously allow to create function proxies with a [[Construct]] but no [[Call]]. The ES5 spec would say that this is an "object". However, since there is no such case (native objects with [[Construct]] but no [[Call]]) that I am aware of, would it make sense to add a value ("constructor"?) for such cases?

# Tom Van Cutsem (15 years ago)

In ES5 11.4.3, which defines the semantics of typeof, is written that native

objects (as proxies will be since they'll be within the scope of the spec) which do not implement a [[call]] trap should return "object" with typeof. Currently, the proxy spec doesn't separate the case when the call trap is defined or not.

Does not defining the call trap mean that [[call]] isn't implemented or does it mean that it is defined to a stub method?

The [[call]] trap is currently mandatory for function proxies. The [[construct]] trap is optional, and defaults to calling the [[call]] trap with |this| bound to a new object that inherits from |proxy.prototype|. (I would interpret this optional [[construct]] trap as being a stub method, not as being a "missing" [[construct]] built-in method)

In FF4b10, here are a couple of results:

typeof Proxy.createFunction({}, function(){}, function(){}); "function"

typeof Proxy.createFunction({}, function(){}, null); TypeError: null is not a function

typeof Proxy.createFunction({}, function(){}, undefined); TypeError: undefined is not a function

typeof Proxy.createFunction({}, function(){}); "function" (Is this inconsistent with passing explicitely undefined?)

AFAICT, explicitly passing |null| or |undefined| is not the same as omitting the argument so this is all expected behavior.

typeof Proxy.createFunction({}, undefined); TypeError: undefined is not a function

typeof Proxy.createFunction({}, null); TypeError: null is not a function

typeof Proxy.createFunction({}); TypeError: createFunction requires more than 1 argument

In order to allow more flexibility, I would suggest to allow undefined/null as allowed values in order to not define either the [[call]] or [[construct]] internal method. This would obivously allow to create function proxies with a [[Construct]] but no [[Call]]. The ES5 spec would say that this is an "object". However, since there is no such case (native objects with [[Construct]] but no [[Call]]) that I am aware of, would it make sense to add a value ("constructor"?) for such cases?

I'm not sure whether we want to increase the complexity of function proxies if this allows proxy writers to implement combinations for which there exists no precedent (either in the spec. or in host objects in the wild). If a use case does come up, it seems to me we can always revise the API later (as long as we don't interpret passing |null| or |undefined| as 2nd argument to createFunction as denoting a default [[construct]]).