On Nov 26, 2012, at 12:36 AM, David Bruant wrote:

> Le 25/11/2012 15:32, Axel Rauschmayer a écrit :
>> 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.
> An interesting question I still haven't found a satisfying answer to is: is 
> the additional power of current proxies useful? and worth the cost? Because 
> the current freedom of proxies is the root cause of invariant checks that 
> even good proxy citizens have to pay.

One of the motivating use cases for Proxies is self-hosting exotic built-ins 
and host objects such as current Web API objects.  If the standard built-in 
Proxy abstraction isn't expressive enough for that job (and also efficient 
enough) then we haven't achieve the goal of supporting that use case.

If that happens what I suspect will happen is that some implementations will 
provide a non-standard, less restrictive, more expressive alternative to the 
standard Proxy.  That seems quite doable because it would just be another 
alternative exotic object  MOP binding for the engine to support.   I'd prefer 
that we provide a standard, interoperable abstraction rather than seeing 
non-interooperable solutions to this use case.

Allen






> 
> David
>> 
>> 
>> [[[Sent from a mobile device. Please forgive brevity and typos.]]]
>> 
>> Dr. Axel Rauschmayer
>> a...@rauschma.de
>> Home: http://rauschma.de
>> Blog: http://2ality.com
>> 
>> On 25.11.2012, at 12:44, Tom Van Cutsem <tomvc...@gmail.com> 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 <erig...@google.com>
>>> +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 <dtrib...@gmail.com> 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
>>> es-discuss@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>> 
>> 
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to