My ECMAScript 7 wishlist
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
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
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.
More information about the es-discuss