My ECMAScript 7 wishlist

Brendan Eich brendan at mozilla.org
Fri Sep 26 09:04:36 PDT 2014


Brendan Eich wrote:
> Dean Landolt wrote:
>> Out of curiosity, wouldn't Object.observe require implementors to add 
>> precisely this kind of hook into the vm anyway?
>
> No, but O.o has its own costs. See
>
> http://lists.w3.org/Archives/Public/public-script-coord/2014JulSep/0204.html 
>

To say a bit more, as Andreas wrote at the link above, O.o has 
multifarious costs todo with mutation and notification.

An unstratified and *general purpose* __noSuchProperty__ trap would 
impose costs on property sets as well as gets. Why "as well as"? Because 
of the "override mistake" where a prototype non-writable data property 
prevents assignment of a shadowing property; and where (symmetric to the 
data property case) a prototype accessor's setter must be called. If nSP 
is defined to do other than throw, e.g., to reify a property on demand 
from some peer property-space, then it must be called for both set and 
get in the missing case.

You could define nSP (maybe someone will, it's still tedious to guess 
here :-/) to apply only to get, but assuming it would work as its name 
and interface suggest -- for more than merely throwing an error when 
called -- I'm proceeding as if it must be called (if present) for 
missing in-not-own property on set as well as get.

The costs should accrue only if some object on the object at hand or 
along its prototype chain has nSP set on it, but that doesn't help much 
for implementors. Splitting out prototype chain walking for all gets and 
sets imposes high cost of code duplication and specialization in modern 
engines. So-called inline caches must be forked to handle both cases, if 
you want good performance for objects "below" the one with nSP.

Andreas can say more, but this general problem of pervasive costs and 
complications due to unstratified traps is exactly the reason we put 
metaprogramming APIs on Proxies, mostly (legacy accessors, good old o[x] 
for computed name x, and a few others aside).

(BTW, complaining about complexity of Proxy and Reflect is off topic, a 
move-the-goalposts attempt that makes me grumpy. Library code hides the 
details. The issue we're trying to get to is user-facing functionality, 
not implementation complexity inside the black box the user faces.)

When I say "TC39 wanted to let the ecosystem handle this" it was first 
and foremost about not rushing library design by committee, or even by 
champions, into a spec, when the the greater number of developers could 
do something better, search multiple paths in the design space, 
cooperate and compete, and meet the demand.

But there was also a desire not to jam more unstratified traps into 
objects, with their optimized hot paths. That's why proxies were added. 
If they can't meet the main use case that Nicholas had in mind, we 
should find out the hard way, from real code, not just from advance 
speculations.

If the main use case is to emulate (for one's own object-based 
abstractions) Python and other languages that do not allow obj.typo to 
pass without runtime error, then a library to add a proxy just below 
Object.prototype and above one's prototypal (constructor <=> class) 
hierarchy might be enough. It won't satisfy all possible use-cases, but 
that's a positive if it hits the main target and spares us unstratified 
traps hitting hot paths.

/be


More information about the es-discuss mailing list