[Harmony proxies] Thoughts on function proxies

# David Bruant (15 years ago)

I've been thinking about Function proxy use cases lately. Things that the spec do and that could be convenient to emulate as well or just things that could be useful.

  • [[Construct]]-less functions. All Array.prototype methods are like that as well as all global object methods (parseInt...) as well as a most of built-in methods. In some way, if you want to define function which wouldn't make sense as constructors (Math functions are a caricature of that), [[Construct]]-less functions would be a good way to raise error if someone, by accident, write "new blabla()" or even "new blabla". It has been suggested here: esdiscuss/2011-March/013019 I think that it was a bit too hacky. I would suggest more of a syntax like: var pf = Proxy.createFunction({}, myCall, null);

  • [[Call]]-less constructors Already possible throughpf = Proxy.createFunction({}, null, myConstructor);

  • "new A" behaves exactly like "A". This can be found for Arrays for instance. Already possible through pf = Proxy.createFunction({}, myCall, undefined);

Finally, I'd like to add a note on constructors. On the proposal is written: "If no constructTrap is provided, new proxy(...args) is reified as calling the proxy's callTrap with |this| bound to a new object delegating to proxy.prototype". In order to clarify, I think that instead of "proxy.prototype" it would be better to say "the result of calling the get trap on the proxy with argument 'prototype'". The get trap is the equivalent tothe [[Get]] internal method used in ES5.1 13.2.2step 5. Or maybe saying that the [[Construct]]algorithm (13.2.2) will be used.

# David Bruant (15 years ago)

Le 15/03/2011 00:52, David Bruant a écrit :

Hi,

I've been thinking about Function proxy use cases lately. Things that the spec do and that could be convenient to emulate as well or just things that could be useful.

  • [[Construct]]-less functions. All Array.prototype methods are like that as well as all global object methods (parseInt...) as well as a most of built-in methods. In some way, if you want to define function which wouldn't make sense as constructors (Math functions are a caricature of that), [[Construct]]-less functions would be a good way to raise error if someone, by accident, write "new blabla()" or even "new blabla". It has been suggested here: esdiscuss/2011-March/013019 I think that it was a bit too hacky. I would suggest more of a syntax like: var pf = Proxy.createFunction({}, myCall, null);

  • [[Call]]-less constructors Already possible throughpf = Proxy.createFunction({}, null, myConstructor);

Spoke too quickly. This throws a TypeError both in proposal and FF4 implementation. I would argue that this can be useful if I want to define "just a constructor". In most cases, people use function as functions or constructor, I have rarely seen both (except for Array or other built-in constructors which are, as said, built-in). [[Call]]-less functions would be a way to prevent what is intended to be a constructor to be called as a function.

# Tom Van Cutsem (15 years ago)

I have no objections to the use cases you're proposing, but in the interest of keeping the Proxy.createFunction method somewhat simple, why isn't the following sufficient:

// [[Construct]]-less functions: var f = Proxy.createFunction(handler, callTrap, function() { throw "can't construct"; });

// [[Call]]-less functions: var f = Proxy.createFunction(handler, function() { throw "can't call"; }, constructTrap);

Distinguishing between |null| and |undefined| to trigger one default behavior or the other feels a bit subtle to me. Are there precedents for this?

As for the clarifying note on constructors: agreed. It doesn't hurt to be explicit about this.

Cheers, Tom

2011/3/15 David Bruant <bruant at enseirb-matmeca.fr>

# Brendan Eich (15 years ago)

On Mar 16, 2011, at 1:11 AM, Tom Van Cutsem wrote:

Hi,

I have no objections to the use cases you're proposing, but in the interest of keeping the Proxy.createFunction method somewhat simple, why isn't the following sufficient:

// [[Construct]]-less functions: var f = Proxy.createFunction(handler, callTrap, function() { throw "can't construct"; });

// [[Call]]-less functions: var f = Proxy.createFunction(handler, function() { throw "can't call"; }, constructTrap);

+1 on leaving users of this case to write it out.

Distinguishing between |null| and |undefined| to trigger one default behavior or the other feels a bit subtle to me. Are there precedents for this?

Not in ECMA-262.

# David Bruant (15 years ago)

Le 16/03/2011 09:11, Tom Van Cutsem a écrit :

Hi,

I have no objections to the use cases you're proposing, but in the interest of keeping the Proxy.createFunction method somewhat simple, why isn't the following sufficient:

// [[Construct]]-less functions: var f = Proxy.createFunction(handler, callTrap, function() { throw "can't construct"; });

// [[Call]]-less functions: var f = Proxy.createFunction(handler, function() { throw "can't call"; }, constructTrap);

It is sufficient, you are completely right :-) And as noted by Brendan, it is actually indeed better that the user can customize the thrown message.