Converting an existing object to a proxy

Tom Van Cutsem tomvc.be at gmail.com
Fri May 27 02:40:14 PDT 2011


Since I gather this proposal is meant primarily to support "observable"
objects, two remarks:

1) Are proxies the appropriate building block performance-wise? From the
notes, it seems that current proxies are not a good building block because
of performance issues. Are the performance issues related to the membraning
needed for maintaining object identity, or are they more fundamental?

2) IIUC, one of the more interesting uses of observables would be to make
e.g. DOM nodes observable. That raises the issue of whether Proxy.createFrom
can be applied to Host objects, and of so, how to deal with built-in [[...]]
properties.

I tend to agree with David about having a separate observable API, if that
is indeed the driving use case. That API can be very similar to the Proxy
API though. Racket's "chaperones" come to mind: a chaperone is a strictly
less powerful kind of proxy, one that is not allowed to arbitrarily change
the result of the original operation (and IIRC, a chaperone also cannot stop
the original operation from taking place on the target object).

Cheers,
Tom

2011/5/27 David Bruant <david.bruant at labri.fr>

>  Le 27/05/2011 04:13, Mark S. Miller a écrit :
>
> On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan <cormac at cs.ucsc.edu>wrote:
>
>> [documenting/expanding some ideas briefly discussed at today's meeting]
>>
>> The current proxy proposal has a method to create a new proxy:
>>
>> var proxy = Proxy.create(handler, proto);
>>
>> We could extend this proposal to allow an existing object to be
>> converted to a proxy, via:
>>
>> var proxy = Proxy.createFrom(object, handler, proto);
>>
>  I am surprised by this proposal since a design goal of proxies was to not
> be able to turn existing objects into proxies.
> 4th "driving force" of the proxy proposal:
> "security: avoid enabling arbitrary ES objects to be able to intercept the
> properties of another object"
>
> The API itself (Proxy.create, Proxy.createFunction) seems to have been
> design with this in mind.
>
>
>
>
>> Here, the return value 'proxy' is the same address as the argument
>> 'object'.
>> The original object thus becomes a proxy. Any state of the original object
>> is discarded.
>>
>  The notion of object "state" is not defined anywhere in the ES5 spec.
> What is your definition of an "object state" ?
>
>
>
>> This extension appears to support additional applications, such as
>> registering an observer on an existing object. The target object would
>> first be cloned, then the target object would be converted into a proxy
>> that
>> dispatches to the cloned object, but which also notifies observers about
>> accesses/updates to the (now proxified) object.
>>
>  Is this the only use case?
> If so, would it rather make sense to provide a specific Object event API
> for existing objects? It would allow to observe accesses/updates without
> turning the object into a proxy with arbitrary handler methods.
>
>
>
>
>> There are a number of open issues relating to security etc:
>> In particular, what objects can be proxified in this way - perhaps not
>> frozen object,
>> or objects with non-configurable properties or with unique names.
>>
>
>  In today's meeting, I made two suggestions along these lines:
>
>  * Given the current proxy semantics, we should allow this only if the
> object-to-be-proxified is extensible and has no non-configurable own
> properties.
> * We have on occasion discussed modifying the proxy proposal so that
> individual properties could be fixed rather than just the proxy as a whole.
> (Note: I am not in favor of such a change, but it could be done soundly.)
> Given that this change to proxies were done, then we should allow
> proxification only if the object-to-be-proxified is extensible, period.
>
>  In both cases, as you state, one effect of the operation is to remove all
> configurable own properties from the object. In both cases, we can adopt the
> rationale that the object-to-be-proxified could not have taken any action
> inconsistent with it always having been a proxy.
>
>  In both cases, we need the further restriction that it is a kind of
> object that can be emulated by a proxy. Today, this is technically only
> objects of [[Class]] "Object" or "Function", but we're talking about
> relaxing that in any case.
>
>
>>
>> A design goal is that for any object that could be proxified,
>> we can replace it with a proxy in a way that is semantically transparent.
>>
>  If you provide the ability to put any functions in the handler object,
> there in no such thing as "semantically transparent". The handler methods
> can do whatever they wants; they are functions. Moreover with an API like
> Proxy.createFrom(object, handler, proto), the handler methods would need
> some help to initialize their internal proxy state in order to align with
> the object passed as argument.
>
> Maybe that what you were suggesting was to use a forwarding handler by
> default as handler and to put the handler argument as "this.target"?
>
> Even in this case, if creating proxies, an external user of the same object
> has no guarantee whatsoever of seeing no semantic difference since, for
> instance, any handler trap could throw an error when called.
>
> My very first (mis)understanding of proxies was that they were an object
> access/update event API and that the handler functions were nice event
> handler. They are not. They are much more powerful. They are not an
> /addition/ to regular internal object methods. They are a /replacement/ of
> it.
>
> However, I agree that an object event API is a valid use case (I have
> actually had a need for that a couple of days ago), but I don't think it
> should be a proxy extension. In my opinion, it should be its own
> library/API. Maybe implementable/standardizable with proxies + "become"
> internal function (see slide 56 at [1]), but its own thing.
>
> I would be much more in favor of something like:
> ----
> Object.observe(o, observers);
> ----
> Observers would be an object that looks like a proxy handler called on
> every object interactions, but wouldn't be able to interact with the object
> internal methods. It would just be an addition to internal methods rather
> than a replacement as it's the case with proxies.
> There wouldn't be any restriction based on property attributes (enumerable,
> configurable, get, set...) or extensibility.
> One question to discuss is to know if they should be called before or after
> (or one observer method for each?) internal calls.
>
> Of course, if there is another use case than object access/update events,
> maybe that turning existing objects into proxies is a good idea, but if
> there isn't, I think that a specific API may be safer.
>
> David
>
> [1] http://www.slideshare.net/BrendanEich/metaprog-5303821?from=ss_embed
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110527/2dfacaee/attachment.html>


More information about the es-discuss mailing list