Notification proxies (Was: possible excessive proxy invariants for Object.keys/etc??)
Mark S. Miller
erights at google.com
Sun Dec 2 09:34:22 PST 2012
On Sun, Dec 2, 2012 at 8:40 AM, Tom Van Cutsem <tomvc.be at gmail.com> wrote:
>>> - "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 for
I think we can rescue around wrapping. I'll call this approach "opaque
around wrapping". The idea is that the proxy passes into the handler
trap a proxy-generated no-argument function (a thunk) called "action".
The normal case is that the trap does stuff before calling action,
calls action with no arguments and ignoring action's results, does
stuff after action, and returns nothing. The call to action performs
the original operation on target and remembers the result. After the
trap returns, the proxy returns the remembered result of action.
Open questions that take us to different design possibilities:
1) what happens if the trap does not call action?
2) what happens if the trap calls action more than once?
3) do actions ever return anything, in case the trap wants to pay
attention to it?
4) are there any return values from the trap that the proxy would pay
5) if the original operation performed by action throws, should the
action still just return to the trap normally?
6) what happens if the trap throws rather that returning?
Two attractive possibilities:
A) A simple pure notification approach:
1) the proxy throws, indicating that the action was not performed
2) only the last successful action counts
3) a boolean, indicating whether the original operation succeeded on target
5) yes, but with false rather than true, as in #A.3 above.
6) the proxy throws, even though the action was performed.
B) Notification with fallback to virtual properties with invariant checking:
Like #A, except
1) if action is never called, then the trap return's invariants are
checked, as now.
4) only if action was never called.
I prefer #A to #B as it gains the full benefits of simplifying the
overall spec and implementation. However, #B still seems better than
current direct proxies, as the normal case gets target-maintenance and
invariant checking for free.
More information about the es-discuss