<div class="gmail_quote">2012/11/29 Dean Tribble <span dir="ltr"><<a href="mailto:dtribble@gmail.com" target="_blank">dtribble@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_quote"><div>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).</div>
</div></blockquote><div><br></div><div>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).</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_quote"><div class="im">
<div> </div><blockquote style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid" class="gmail_quote"><div class="gmail_quote"><div>CLOS method combinations allow a composer to distinguish between "before", "after" and "around"-style composition:</div>

<div>- "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.</div></div>

</blockquote><div> </div></div><div>You <em>can</em> 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).</div>
</div></blockquote><div><br></div><div>Indeed. I think notification proxies would benefit from both before + after notification so any cleanup of virtual properties can be done directly.</div><div><br></div><div>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 invariants.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_quote"><div class="im">
<div> </div><blockquote style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid" class="gmail_quote"><div class="gmail_quote"><div>- "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.</div>


<div>- "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.</div>

</div></blockquote><div> </div></div><div>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.</div>
</div></blockquote><div><br></div><div>You're right, around doesn't subsume before+after in that regard. Thanks for clarifying.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_quote">
<div> </div><div>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.</div>
</div></blockquote><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_quote"><div>
</div><div class="im"><blockquote style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid" class="gmail_quote"><div class="gmail_quote"><div>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.</div>

<div> </div></div></blockquote></div><div>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.</div>
</div></blockquote><div><br></div><div>It does. It just feels awkward, after having been able to express these abstractions more directly with the current Proxy API for so long.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_quote"><div class="im">
<div> </div><blockquote style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid" class="gmail_quote"><div class="gmail_quote"><div>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:</div>

<div><br>Virtual objects, hence "around"-style:</div><div>- self-hosting "exotic" objects such as Date, Array (i.e. self-host an ES5/ES6 environment)</div><div>- self-hosting DOM/WebIDL objects such as NodeList</div>

<div> </div></div></blockquote></div><div>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.</div>
</div></blockquote><div><br></div><div>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.</div><div><br>
</div><div>Cheers,</div><div>Tom</div></div>