Le 25/11/2012 12:44, Tom Van Cutsem a écrit :
(...)
I agree that the big benefit of notification proxies is that they get
rid of all the complex validation logic.
However, some reservations:
(...)
- I think we do lose some expressiveness in the case of pure virtual
object abstractions that don't pretend to uphold any invariants.
I don't think this is true. As Mark said:
"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."
This is true for any trap I think.
I however agree that this 2-trap consistency may make the exercise of
writing traps harder (but it'd take user testing to be 100% sure it's
significantly harder).
I think there might be a loss in expressiveness if forwarding to the
target throws an error. With current proxies, the trap can catch this
exception; with notification proxies, the error is thrown after the
trap, so it can't.
Now, it would require an in-depth analysis, but I intuit that all cases
where an internal operation throws have a corresponding invariant checks
(which errors aren't caught by current proxies). If that was the case,
it would mean that there is actually no loss (or a minor loss consisting
in loosing the ability to catch an error and rethrow it yourself)
Also, if you can only forward to target, there is no way you can define
custom property descriptor attributes which would be a shame in my opinion.
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.
I think that any virtual object abstraction which claims to maintain
some sort of consistency has to store the necessary bits of this
consistency somewhere. The target is as good as anywhere else.
I have to note that if the target is forced to be used as a regular
object, then things like ProxyMap [1] become pointless (because the map
is just used as a regular object, not as a map).
(...)
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.
According to Mark's comment, "later" is "next trap". It's possible to
maintain consistency, but writing the traps is a bit less easy.
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.
I have what I think to be a interesting middleground allowing to bypass
invariant checks while keeping direct proxies as they are.
My experience with writing traps with direct proxies is that traps (for
non-virtual cases) almost all and always look like [2]:
trap: function(...args){
// do something
return Reflect.trap(...args); // or equivalent built-in/syntax
}
Let's take the Object.getOwnPropertyDescriptor trap as example. With
current proxies, the trap would often end with
Reflect.getOwnPropertyDescriptor(target, name) (or "Object.", whatev's),
after the call on the target is finished, then, the engine checks the
result against the target... but that's a bit dumb.
We know we wanted to get the target result and we made the most
straightforward thing to do that guarantees invariants, but the engine
still has to check, because it can't know the result comes from calling
the Reflect operation on the target.
We could define a symbolic value (like StopIteration for iterators) that
would mean "forward to target". By essence of what forwarding to the
target means, there would be no need to perform the least invariant
check. We can call it ForwardToTarget :-)
Then traps involved in proxies preserving some consistency would look like:
trap: function(...args){
// do something
return ForwardToTarget;
}
The rule would become: "if you want to do something simple,
ForwardToTarget at the end of your trap and the invariant check cost is
gone. If you want to use direct proxies freedom (virtual objects), you
have to pay the cost of invariant checks to make sure you don't go too
wild with your freedom"
Best of both worlds for the cost of a symbol.
As a followup to my above comment about custom property descriptor
attributes, it would be nice to be able to return something like
ForwardToTargetAndCombineWith({custom1: val1, custom2:val2}) for the
getOwnPropertyDescriptor trap. More thoughts is necessary for this case.
David
[1] https://gist.github.com/3918227
[2]
https://github.com/DavidBruant/HarmonyProxyLab/blob/EventedObjectsOnDirectProxies/EventedObject/EventedObject.js#L144
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss