possible excessive proxy invariants for Object.keys/etc??
allen at wirfs-brock.com
Wed Nov 21 08:55:28 PST 2012
On Nov 21, 2012, at 3:54 AM, Andreas Rossberg wrote:
> On 21 November 2012 01:06, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
>> Tom Van Cutsem <tomvc.be at gmail.com> wrote:
>>> Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
>>>> Tom Van Cutsem <tomvc.be at gmail.com> wrote:
>>>>> c) to ensure the stability of the result.
>>>>> You can think of a + b as implementing a type coercion of the trap result
>>>>> to "Array of String". This coercion is not too dissimilar from what the
>>>>> getOwnPropertyDescriptor has to do (normalization of the returned property
>>>>> descriptor by creating a fresh copy).
>>>> Yes, premature type coercion, in my opinion. Also, a classic performance
>>>> mistakes made by dynamic language programmers: unnecessary coercion of
>>>> values that are never going to be access or redundant coercion checks of
>>>> values that are already of the property type. Why is it important to do
>>>> such checks on values that are are just passing through these traps. When
>>>> and if somebody actually gets arounds to using one of the elements that are
>>>> returned as a property key they will be automatically coerced to a valid
>>>> value. Why is it important that it happens any sooner than that.
>>> I don't know if you are familiar with the work of Felleisen et al. on
>>> higher-order contracts. In that work, they use the notion of "blame" between
>>> different components/modules. Basically: if some module A receives some data
>>> from a module B, and B provides "wrong" data, then B should be assigned
>>> blame. You don't want to end up in a situation where A receives the blame at
>>> the point where it passes that "wrong" data into another module C.
>> Yes, but ES is rampant with this sort of potentially misplaced blame. We
>> can debate whether such proper "blame" assignment is important or not, but I
>> do believe this sort of very low level MOP interface is a situation where
>> you want to absolutely minimize none essential work. I'd sooner have it be
>> a little bit more difficult to track now Proxy based bugs then to impact the
>> performance of every correctly implemented proxy in every correct program.
>> BTW this is a general statement about the entire proxy MOP and not just
>> about these particularly property key access traps.
> I'm strongly in favour of guaranteeing the contract Tom is mentioning.
> However, there is an alternative to copying: we could require the
> array (or array-like object) returned by the trap to be frozen. (We
> could also freeze it ourselves, but that might be more problematic.)
I'd be more favorably inclined towards freezing than I am towards copying. But, as you know, ES5 does not currently produce frozen objects in these situations. I feel uncomfortable about enforcing a frozen invariant for traps where that invariant is not provided by the corresponding ordinary object behavior. Perhaps I could get over that or perhaps incompatibility applying that requirement to ordinary objects wouldn't break anything.
Regardless, freezing and testing for frozen is, itself, not a cheap operation. It requires iterating over all the property descriptors of an object. If we are going to build in a lot of checks of for frozen objects perhaps we should just make frozen (and possibly) sealed object level states rather than a dynamic check of all properties. Essentially we could internally turn the [[Extensible]] internal property into a four state value: open,non-extensible,sealed,frozen. It would make both freezing and checking for frozen much cheaper.
> (The fact that ES is already full of mistakes should not be an excuse
> for reiterating them for new features.)
I think it is usually a mistake to perform complex invariant check at low levels of a language engine. Those often become performance barriers. Checking complex relationships belongs at higher abstraction layers.
More information about the es-discuss