Ok... hmm... well... I misread your initial post. You wanted to enforce the condition on the argument proto object, not the object returned by Proxy.createFunction. My apologies, here's my fixed response:
Le 24/02/2011 11:42, David Bruant a écrit : > Le 24/02/2011 02:32, David Herman a écrit : >>>> The simple instanceof check seems simpler and reasonably intuitive. >>> By "hardcoding" p instanceof Function === true >> I'm not proposing this -- it's already true. Try it out in SpiderMonkey: >> >> js> (Proxy.createFunction({}, function(){}, function(){})) instanceof >> Function >> true >> >>> you're breaking your >>> user expectation of finding the Function.prototype methods ("call", >>> "apply" or any further addition) in the object. >> I think I haven't made myself clear. Certainly, users generally expect >> invariants like: >> >> if (x instanceof y) and (key in y.prototype) then (key in x) >> if (y === Object.getPrototypeOf(x)) and (key in y) then (key in x) >> >> But proxies *already* break these invariants. It's *already* possible to >> write a proxy that doesn't have a property that its prototype has. You can >> do this *both* with Proxy.create(), which lets you provide a prototype but >> act as though you don't have properties of the prototype, *and* with >> Proxy.createFunction(), which insists that your proxy is an instanceof >> Function but again lets you act as though you don't have the properties of >> Function.prototype. >> >> None of this has anything to do with my suggested extension, which is >> allowing a user-specified prototype to Proxy.createFunction. >> >>>>> With your solution, by removing Function.prototype from the chain, proxy >>>>> functions couldn't be .call()-ed or .apply()-ed >>>> That's already true, even without my extension: >>>> >>>> js> var proxy = Proxy.createFunction({}, function(){}, function(){}) >>>> js> proxy.call(this) >>>> typein:11: TypeError: getPropertyDescriptor is not a function >>> The bug is in your code: >> No, there's no bug. The point of my code was to demonstrate that it's >> already possible to break the above invariant. >> >> If you want to promote as best practices that people should *strive* to >> uphold the invariant, even though it isn't enforced by the language, that's >> fine. But allowing user-specified prototypes for Proxy.createFunction >> doesn't change this. It's still up to the proxy writer to ensure that they >> delegate to the prototype, regardless of whether the prototype is >> Function.prototype or a descendant of Function.prototype. > This is currently true that it's up to the writer, but is likely to > become half-false: > Previously (starting here: > https://mail.mozilla.org/pipermail/es-discuss/2011-January/012603.html) > we've been discussing the idea that getPropertyNames and > getPropertyDescriptor become derived traps and that their default > behavior would be to climb the prototype chain. This way, by default, > the prototype delegation occurs, so it wouldn't be up to the proxy > writer to ensure prototype delegation. > But the proxy writer can decide to override getPropertyNames and > getPropertyDescriptor (or any trap that would) anyway and then mess with > prototype delegation, I agree. > > >>> When you do "proxy.call(this)", the "proxy.call" getter is trapped as >>> the "get" trap. Since you do not define it (your handler objectis >>> empty), the default get trap is called (see here : >>> http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults). >>> In this default get trap, the first thing that is done is a call to >>> this.getPropertyDescriptor ("this" refers to the handler object which is >>> empty in your example). And here, the error is thrown by the engine >>> since handler.getPropertyDescriptor isn't a function because it's undefined. >> Well, of course! That's my point. Proxies do not force you to respect >> prototype delegation. > Ok, I thought you made a mistake. > >>> This code is ugly, because my get handler methods assumes that the proxy >>> object is reachable from the lexical scope which could not be the case >>> (I could have used the "rec" argument, but that's not very clean). There >>> is an ongoing discussion to make the proxy object available as an >>> argument in each trap. This way, the get trap could be rewritten as: >>> get: function (rec, name, proxy){ >>> return Object.getPrototypeOf(proxy)[name]; >>> // Object.getPrototypeOf(proxy) is Function.prototype by definition here >>> } >>> This is actually one more argument in the direction of making this happen. >> That seems like a non sequitur; in what you've written, I don't see any >> argument against allowing Proxy.createFunction() to accept a user-specified >> prototype. >> >> Again: the whole design of the proxy system *already* requires you to >> implement the delegation manually if you want to respect the prototype >> chain. But you don't have to respect the prototype delegation chain. That's >> true for both Object.create() and Object.createFunction(). >> >> All I'm proposing is allowing you to specify a descendant of >> Function.prototype as your prototype link, rather than Function.prototype >> itself. > (...) > > 4) Make sure that proto contains Function.prototype in its chain and > throw an error if it isn't the case That's what you're suggesting from the beginning if I understand well. >> Either way, it's up to the programmer to decide whether they want to respect >> prototype delegation in their traps. > Indeed. Actually, since it's currently up to the programmer to > re-implement delegation, what are you expecting from choosing your > prototype object? Can't you just use it in your handler object? I'm just > talking about currently (current spec state and current FF4 implementation). > For the longerer term, if, as discussed, getPropertyNames and > getPropertyDescriptor become derived traps with the suggestion default > implementation, it completly makes sense to add an additional argument, > with the still pending issue of how to enforce the result of instanceof > (I'm actually a fan of the 4th solution). David _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss