I will let Tom and Mark field this one in full, but Arrays are *not* host 
objects, they are native objects in ECMA-262 terms.

However, Allen has taken the action to reconcile and perhaps unify the spec's 
internal methods (its Meta-Object Protocol) and Proxies' MOP. This would allow 
the spec to treat arrays as if they were proxies with native handlers.

In reality, of course, a proxy is an empty object with a handler object (shared 
or not) that holdsl mutable state (somehow: closure, weakmap, whatever). Arrays 
OTOH must be efficient, dense if possible, single allocation if small, etc. No 
practical implementation would make a proxy and handler holding mutable state.

This beautiful slide of Tom's (I believe) shows the parallelism and differences:

http://brendaneich.com/brendaneich_content/uploads/selective-interception.png

In C and C++ implementations, the handler is a suite of functions or methods, 
and all the array data is in the green "object" circle, or attached to it for 
efficient access with dynamic range over length.

/be

On Jan 27, 2011, at 8:33 AM, David Bruant wrote:

> Le 27/01/2011 11:20, Tom Van Cutsem a écrit :
>> 
>> - Agreed that if we contemplate adding 'proxy' as an argument to 
>> getPropertyDescriptor and getPropertyNames, we should add it to all other 
>> traps as well.
>> - Agreed that this is the simplest way of allowing a shared handler to get 
>> at the proxy it's currently 'serving'
>> - W.r.t. a handler not being able to perform typeof/instanceof on the proxy 
>> it's intercepting: this does have the benefit of detracting programmers from 
>> writing handlers that act differently for function vs object proxies. But 
>> agreed that this functionality might be needed to fix the quirky behavior of 
>> a host object.
> This last point is actually a concern. Is the (one?) point of proxies to 
> being able to fully emulate (and by 'emulate', I also mean 'fix') host 
> objects. If so, proxies should have access to all internal 
> methods&properties. As said in ES5 8.6.2 right under Table 8:
> "Every object (including host objects) must implement all of the internal 
> properties listed in Table 8.". If we want to be able to emulate proxies, we 
> need to be as powerful with proxies.
> Question is: do we want to?
> 
> I have recently been working on emulating Arrays (they are host objects, 
> aren't they?) with proxies and native objects. I'll put the code on github 
> and provide a longer feedback in another e-mail, but the basic idea was to 
> use a forwarding proxy and implement the only method that matters: 
> defineProperty. I have almost blindly implemented+adapted 
> [[defineOwnProperty]] (ES5 15.4.5.1).
> Everything works perfectly so far. There are a few differences with native 
> arrays, though:
> - I have no control over the [[class]] internal property, so even though my 
> "proxyArrays" act like native ones, they can be discriminated quite easily.
> - I haven't tested, but according to the semantics of Array initialisers (ES5 
> 11.1.4), "[]" calls "new Array() where Array is the standard built-in 
> constructor with that name.". So even if I try window.Array = proxyArray, 
> "[]" should not create one of my arrays. This sounds perfectly fair.
> - I obviously initialize my proxyArrays with Array.prototype as prototype. I 
> haven't tested if it works; it is allowed not to, because in ES5, under each 
> array prototype method is written:
> " The *** function is intentionally generic; it does not require that its 
> this value be an Array object. Therefore it can be transferred to other kinds 
> of objects for use as a method. Whether the *** function can be applied 
> successfully to a host object is implementation-dependent. ".
> They could be reimplemented if needed to fully emulate Arrays. (I've worked 
> on that a billion years ago : 
> https://github.com/DavidBruant/ecma5array/blob/test_conformance/ecma5array.js)
> 
> So here is another question on proxies goal/rational:
> Should proxies be powerful enough to fully emulate native Arrays? (If so and 
> if ES Harmony has proxies in it, then native Array could be specified as a 
> proxy which is awesome and a half in my opinion, but that's a different 
> problem).
> 
> 
>> Re. adding 'proxy' as an optional last parameter to all traps: what worries 
>> me is that for some traps, this could be terribly confusing. Consider:
>> 
>> Object.getOwnPropertyDescriptor(proxy, name);
>> // will trap as:
>> getOwnPropertyDescriptor: function(name, proxy) { ... }
>> 
>> The reversed argument order is going to bite people.
>> Adding 'proxy' as a last optional argument is confusing in this way for 
>> get{Own}PropertyDescriptor, defineProperty, delete, hasOwn
>> It's OK for get{Own}PropertyNames, keys, fix, has, enumerate
>> get and set would then take 4 arguments, and it's unclear to me whether 
>> tacking 'proxy' to the front or to the back is better.
>> (alternatively, maybe 'get' and 'set' don't need access to the proxy after 
>> all. It seems to me that if 'receiver' has multiple proxies in its prototype 
>> chain, only the one closest to receiver is going to trigger a handler 
>> get/set trap. OTOH, without a built-in Proxy.isTrapping(obj) method, I don't 
>> think the handler can find out what object on the prototype chain is a proxy)
>> 
>> We could choose to add 'proxy' at the "right" place in the argument list 
>> depending on the trap. This trades one kind of cognitive load (unexpected 
>> argument order for some traps) for another (no uniform position of 'proxy' 
>> across all traps, and no longer an optional argument for all traps). Either 
>> way, we need to decide whether this added API complexity is worth it.
>> 
>> One more thing: giving the handler access to its proxy by default may 
>> increase chances of runaway recursion hazards, as every operation that the 
>> handler performs on its own proxy is going to call some trap on the handler 
>> itself. Ideally, we should be able to label the 'proxy' parameter with a big 
>> red warning sign saying "handle with care!". I ran into this problem already 
>> a couple of times when writing "get" traps. The 'receiver' parameter often 
>> is the proxy itself, and doing even simple things like trying to print the 
>> proxy (e.g. for debugging) will call proxy.toString, hence will recursively 
>> call the "get" trap you're trying to debug. But maybe the problem is just 
>> more exaggerated in the "get" trap since property access is so common, and 
>> it won't really be an issue for the other traps.
> I had already read that point in your proxy tutorial. It will be up to the 
> resources that people go to to learn how proxies work to tell them that they 
> should be careful with unwanted recursion.
> One important such resource is very likely to be the MDN page. I'll take care 
> of writing down all these points. Otherwise, it's a wiki, feel free to jump 
> in anytime to correct things or add examples.
> 
> Cheers,
> 
> David
> 
>> 
>> Cheers,
>> Tom
>> 
>> 2011/1/26 Brendan Eich <bren...@mozilla.com>
>> On Jan 26, 2011, at 11:02 AM, David Bruant wrote:
>> 
>> >> On the question of proxy parameters for all traps (well, receiver for get 
>> >> and set): fewer args are better, and closure capture of proxy by handler 
>> >> avoids leaking the proxy to handler friends, if that matters. Likewise 
>> >> you can't get the handler from the proxy.
>> > If you handlers are frozen, there should be no leaking, shouldn't there? 
>> > (I actually think that freezing the handler should be done in the no-op 
>> > forwarding proxy example or any handler factory, but that's another issue).
>> 
>> No default freezing is going to be imposed. :-|
>> 
>> 
>> > About the closure capturing, it works only if one proxy is using the 
>> > handler. It doesn't if several proxies share it.
>> 
>> Good point.
>> 
>> 
>> >> These aren't absolute arguments, but I remember working through the 
>> >> alternative of a leading proxy parameter, both as JS hacker using proxies 
>> >> and in terms of SpiderMonkey's C++ implementation, and it was just bigger 
>> >> and less tidy, for both "sides" (JS and C++), without enough payoff.
>> > ... what about a trailing proxy parameter? It won't change anything on the 
>> > C++ side (by comparison to a leading parameter), but will on the JS side, 
>> > because you can omit the parameter if you don't need it.
>> 
>> Not a bad idea, and the C++ gurus can take it. Tom, Mark?
>> 
>> /be
>> 
> 

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to