2011/1/28 David Bruant <[email protected]>

>  Hi,
>
> I have decided to work on trying to (re-)implement native arrays with
> proxies. All the code is here: https://github.com/DavidBruant/ProxyArrayand 
> I'd like to provide some feedback.
>
> * The approach
> The basic idea was to:
> - use a forwarding proxy
> - change the defineProperty trap into an adapted version of ES5 15.4.5.1
> ([[DefineOwnProperty internal method of native array objects]])
> - reimplement the constructor.
>
> * First issue: the 'set' trap (and all derived traps)
> The very first issue I've encounter was that setting a property on the
> proxy was (obviously) forwarded on the target using the 'set' trap.
> Consequently, my defineProperty was just bypassed.
> It got me thinking of the forwarding proxy example (which is on its way to
> being standardized:
> http://wiki.ecmascript.org/doku.php?id=harmony:proxy_defaulthandler).
> Would it make sense to define a default forwarding proxy as a proxy "in
> sync" with an object? This definition would deserve to be more formalized,
> but the idea is that if you write:
> var h = new Proxy.Handler(obj);
> var p = Proxy.create(h, Object.getPrototypeOf(obj));
> then your program cannot tell the difference between obj and p besides:
> - if you do preventExtension/seal/freeze on the proxy (which fix it proxy
> and break the inner link between obj and p).
> - obj !== p
>

I think this is correct, except for the detail that if 'obj' is a function
object, you'd need to wrap it in a function proxy to make sure typeof, call
and construct are consistent for p and obj.


>
> Based on that definition, we could have a stronger definition of derived
> traps:
> Derived trap are defined as ES code using fundamental traps in order to
> respect the forwarding proxy definition. Before going any further, I'd like
> to say that it's already the case :-) In my opinion, that was the rational
> behind Mark Miller's "coherent behavior to fall back to" idea of what should
> be derived or fundamental. Coherent with what? With what we expect from
> native objects.
> To solve my problem with proxyArrays, I got rid of all derived traps
> definitions in the forwarding proxy code and it worked perfectly. It could
> make sense to do exactly the same with the default proxy forwarding handler,
> otherwise, people who just want to implement a fundamental trap (like I did)
> will have to reimplement all derived traps depending on the fundamental and
> it is very likely that their reimplementation will be the derived trap
> default definition.
>

Very interesting observation. So the issue is that the derived traps of the
"default forwarding handler" have two possible default implementations:
a) forward the derived operation to the 'target' (that is how they are
specified now)
b) implement the "default" semantics in terms of the fundamental forwarding
traps (or equivalently, the default forwarding handler has no derived traps)

The problem with a) is that child objects of the default forwarding handler
that override a fundamental trap must actually also override all derived
traps that depend on it. In some cases, the trap implementor will want to do
this anyway since the derived traps may allow a more efficient
implementation, but if not, then indeed the programmer must either
reimplement the default semantics, or delete the inherited derived trap.

The problem with b) is that if the "target" object to which the proxy
forwards is itself a proxy p2, then p2's derived traps will never be called.
Instead, only p2's fundamental traps will be called. Things won't break, but
it is suboptimal if p2 has ad hoc (presumably more efficient)
implementations for its derived traps. Presumably, even if "target" is a
native object, option a) is more efficient than defaulting to the
fundamental operations.

I have no good suggestion yet for how to address both issues. One way out
would be to provide two default forwarding handlers (e.g. a
FundamentalHandler that only defines the fundamental traps (and hence has b)
semantics for its derived traps), and a DerivedHandler that inherits from
the FundamentalHandler that adds the derived traps with a) semantics).
Depending on the required semantics, the programmer can make his/her custom
handler inherit from either one. But maybe this is just too complex a
solution.


>
> * getPropertyDescriptor
> Since this function isn't implemented in FF4 and that there is no access to
> the proxy object, it was impossible to reach the prototype. "Fortunately", I
> knew that it had to be Array.prototype. I have hardcoded the prototype chain
> walk. We have already discussed this issue in previous e-mails.
>
> I hope this feedback will be helpful.
>

Yes, very helpful!

Cheers,
Tom


>
> Thanks for reading!
>
> David
>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
>
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to