Notification proxies (Was: possible excessive proxy invariants for Object.keys/etc??)
Tom Van Cutsem
tomvc.be at gmail.com
Sun Dec 2 08:40:44 PST 2012
2012/11/29 Dean Tribble <dtribble at gmail.com>
> As a general point, I encourage you to look for other inspiration than
> CLOS MOP for doign proxies (whose mother was really InterlispD). Meta-level
> access deeply impacts security,maintainability,
> reliability, understandability, etc. The tighter and more structured you
> can make your meta-level access, the easier it will be to to implement,
> use, and maintain (e.g., both coroutines and downward functions are more
> understandable, easier to implement, easier to secure, etc. than general
> continuations and call-cc).
I agree (side note: the CLOS MOP didn't form a direct inspiration for JS
proxies, although I'm probably influenced by having studied it).
>> CLOS method combinations allow a composer to distinguish between
>> "before", "after" and "around"-style composition:
>> - "before"-style wrapping gives you only the ability to get notified
>> before an operation happens. You can abort, but not change, the result of
>> the operation. This is what notification-proxies offer.
> You *can* change the result of the operation. You do so by modifying the
> state before the operation proceeds, of course. You could also extend the
> notification support to notify after so you could clenup (avoiding a
> callback hack).
Indeed. I think notification proxies would benefit from both before + after
notification so any cleanup of virtual properties can be done directly.
That just leaves the thorny issue that for virtual object abstractions,
having to "set-up" the target in a before-handler and "clean-up" the target
in an after-handler is really a very indirect way of expressing the
abstraction, especially if the proxy doesn't need to virtualize any
>> - "after"-style wrapping allows you to get notified of an operation
>> after-the-fact. Depending on the API, the "after"-wrapper may or may not
>> get to see the outcome of the operation, and may or may not change the
>> final outcome passed on to clients.
>> - "around"-style wrapping is the most general and allows the composer to
>> decide if and when to forward, and what result to return. It subsumes
>> before/after wrapping. This is what direct proxies currently provide.
> It does not subsume before/after wrapping, because it loses the integrity
> of before/after (e.g., the wrapper can lie and cheat, where the before and
> after cannot). That may be worth it, but it is substantially different.
You're right, around doesn't subsume before+after in that regard. Thanks
> Another variant is the "differential" version: the "differential" trap is
> like a notification, but it can also return virtual additions (or an
> iterator of additions). The proxy then invokes the primitive on the
> target, and appends (with de-dupping, etc.) the virtual additions. This
> allows the simple case to just use hte target, but also allows all of
> Allen's additional cases.
> As far as I can tell, virtual object abstractions like remote/persistent
>> objects require "around"-style wrapping, because there's otherwise no
>> meaningful target to automatically forward to.
> I thought the target in that case is an internal object to represent or
> reify the meta-state of the remote or persistent object. I think that still
> makes sense in both the persistent object and remote object cases.
It does. It just feels awkward, after having been able to express these
abstractions more directly with the current Proxy API for so long.
>> Here's a list of use cases that I frequently have in mind when thinking
>> about proxies, categorized according to whether the use case requires
>> before/after/around wrapping:
>> Virtual objects, hence "around"-style:
>> - self-hosting "exotic" objects such as Date, Array (i.e. self-host an
>> ES5/ES6 environment)
>> - self-hosting DOM/WebIDL objects such as NodeList
> I should note that I'm not advocating a notification-only style for all
> your proxy needs; having get operations able to generate virtual results
> makes lots of sense. I primary suggest it for operations that are currently
> implemented by the system (i.e., user code cannot normally intervene) and
> that might be relied on for security-relevant behavior. wrapping return
> results of user operations in a proxy makes perfect sense to me.
It's hard to force the two different use cases (wrapping vs virtual
objects) into a single API. I don't have a good answer yet on how to
resolve the trade-offs.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the es-discuss