If indeed both kinds of proxy are useful and direct proxies are more powerful, then why not only have a foundational direct proxy API and implement a tool type NotificationProxy that is based on that API.
[[[Sent from a mobile device. Please forgive brevity and typos.]]] Dr. Axel Rauschmayer [email protected] Home: http://rauschma.de Blog: http://2ality.com On 25.11.2012, at 12:44, Tom Van Cutsem <[email protected]> wrote: > Hi, > > I will refer to Dean's proposal as "notification proxies" (where traps > essentially become notification callbacks), and will continue to use "direct > proxies" for the current design where the trap can return a result (which is > then verified). > > These notification proxies remind me a lot of how one must implement > membranes with direct proxies. The general idea here is that the proxy must > use a "shadow" target as the proxy target, and the handler must refer to the > "real" wrapped target. Traps that have to do with invariants (e.g. > freeze/isFrozen, or querying a non-configurable property descriptor) require > the proxy to "synchronize" the state of the real and shadow targets, because > the proxy will verify the trap result against the shadow target. > > For such membranes, let's consider how direct proxies and notification > proxies trap an operation: > > Direct proxies: > 1) the proxy calls a trap on the handler > 2) if the operation involves strong invariants on the real target, the > handler must synchronize real and shadow target > 3) the trap returns a result > 4) if the proxy detects that the operation involves strong invariants, the > trap result is verified against the shadow target > > Notification proxies: > 1) the proxy calls a trap on the handler (as a notification) > 2) the handler must synchronize real and shadow target (regardless of whether > invariants are involved) > 3) the trap returns no result > 4) the proxy performs the intercepted operation on the shadow and returns the > result > > I agree that the big benefit of notification proxies is that they get rid of > all the complex validation logic. > > However, some reservations: > > - if traps become mere notifications, perhaps their names should change to > reflect this, e.g. "notifyGetOwnPropertyNames" instead of > "getOwnPropertyNames". This is to alert handler writers that the return value > of these traps will be ignored. > > - I think we do lose some expressiveness in the case of pure virtual object > abstractions that don't pretend to uphold any invariants. > With notification proxies, the handler must always (even in the case of > configurable properties) define concrete properties on the target. Any > virtual object abstraction is thus forced to maintain a "shadow" which must > eventually be represented as a plain Javascript object. > In other words: *all* virtual object abstractions, whether they pretend to be > frozen or not, have to make use of the "shadow target" technique, with the > burden of synchronizing the shadow upon each operation. That burden currently > doesn't exist for non-frozen virtual object abstractions (I'm using "frozen" > vs "non-frozen" here as a shorthand for "has non-configurable/non-extensible > invariants" vs "has no such invariants"). > > - Regarding the overhead of the getOwnPropertyNames trap having to create a > defensive copy of the trap result: > With notification proxies, upon trapping "notifyGetOwnPropertyNames": > 1) the trap must define all properties it wants to return on the target. If > there are N properties, there is an O(N) physical storage cost involved. > 2) the proxy applies the built-in Object.getOwnPropertyNames to the target. > Assuming the target is a normal object, the primitive allocates a fresh array > and returns the N properties. > > In the current design: > 1) the trap returns an array of property names (requiring O(N) physical > storage cost) > 2) the proxy copies and verifies this array > > I think the storage costs are largely the same. However, with notification > proxies, if the properties were "virtual", those properties do linger as > "concrete" properties on the target. Yes, the handler can delete them later, > but when is later? Should the handler schedule clean-up actions using > setTimeout(0)? This somehow does not feel right. > > I like the simplicity of notification proxies, but we should think carefully > what operations we turn into notifications only. > > More generally, notification proxies are indeed "even-more-direct-proxies". > They make the "wrapping" use case (logging, profiling, contract checking, > etc.) simpler, at the expense of "virtual objects" (remote objects, test > mock-ups), which are forced to always "concretize" the virtual object's > properties on a real Javascript object. > > Cheers, > Tom > > 2012/11/25 Mark S. Miller <[email protected]> >> +1. I think this is a really effective extension of the direct proxy >> approach, and I don't know why we didn't see it earlier. It's weird >> that this preserves all the flexibility of fully virtual configurable >> properties even though it insists that even these be made into real >> properties on the target. The trick is that placing a configurable >> property on the target doesn't commit the handler to anything, since >> the handler can remove or change this property freely as of the next >> trap. >> >> Apologies again for not yet having the time to do more than skim the >> thread at this point. But IIRC someone already suggested a similar >> change to some of the imperative traps -- perhaps freeze, seal, and >> preventExtensions. The handler would not perform these operations on >> the target, only to have the proxy check it. Rather, if the trap >> indicates that the operation should succeed, the proxy then simply >> performs the operation -- or else throws. I wonder if this philosophy >> could be extended to some of the other imperative operations as well? >> >> What expressiveness does this even-more-direct proxy approach lose? >> AFAICT, not much. At the same time, it should result in a *much* >> simpler implementation and much greater confidence that invariants of >> the non-proxy sublanguage are preserved by the introduction of >> proxies. In fact, I think it's much stronger on invariant preservation >> that the current direct proxies, while being much simpler. >> >> >> On Sat, Nov 24, 2012 at 6:49 PM, Dean Tribble <[email protected]> wrote: >> > I am looking forward to proxies in JavaScript, and had a thought on the >> > issues below. You could extend the the "direct proxy" approach for this. >> > >> > When the Proxy receives getOwnPropertyNames, it >> > 1) notifies the handler that property names are being requested >> > 2) the handler adds/removes any properties (configurable or otherwise >> > subject to the normal constraints) on the target >> > 3) upon return, the proxy invokes getOwnPropertyNames directly on the >> > target >> > (e..g, invoking the normal system primitive) >> > >> > This approach appears to have consistent behavior for configurability and >> > extensibility. For example, the trap operation above could add configurable >> > properties to an extensible target, and remove them later. It could add >> > non-configurable properties, but they are permanent once added, etc. Thus >> > there's no loss of generality. In addition to optionally setting up >> > properties on the target, the handler trap above would need to indicate to >> > the proxy (via exception or boolean result) that the getOwnPropertyNames >> > operation should proceed ahead or fail. >> > >> > This extension of the "direct proxy" approach applies to all query >> > operations, eliminates the copying and validation overhead discussed below, >> > simplifies the implementation, retains full backwards compatibility, and >> > enables most if not all the expressiveness we might expect for proxies. >> > >> > Dean > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

