July 25, 2012 - TC39 Meeting Notes

Herby Vojčík herby at mailbox.sk
Sat Jul 28 05:37:33 PDT 2012



David Bruant wrote:
> Le 28/07/2012 13:43, Herby Vojčík a écrit :
>> David Bruant wrote:
>>>       var a = [];
>>>       a.push = function(elem){
>>>           if(condition(elem)){
>>>               // do something like change the elem value then do an
>>> actual
>>> push
>>>               // or throw an error
>>>               // or just ignore this value to avoid duplicates, for
>>> instance
>>>           }
>>>           else{
>>>               Array.prototype.push.call(this, elem)
>>>           }
>>>       };
>>>
>>>       // use a.push (there is an implicit contract on only using .push to
>>> add elements)
>>>
>>> (...)
>>>
>>> * I could use Object.defineProperty, but the above code is definitely
>>> more readable and intuitive.
>> Well, yes. But from the philosophical PoV, imho, you should do
>> Object.defineProperty here, because that is what you do (your intent
>> is not "put a value to a's push property").
> My intent is "I want a custom 'push' property for this particular
> array", because I'm filling the array afterwards using .push calls. I
> don't know what I "should" be doing from a philosophical point of view,
> but the code written above describes my intention pretty well. If I saw

To be precise, [[Put]] and [[DefineProperty]] are different intents. 
Dveelopers may not like it, because they used to [[Put]], but it is 
probably needed to distinguish them.

[[Put]] is high-level contract (a, update your 'push' facet with value), 
[[DefineProperty]] is low-level contract (a, add/update your slot named 
'push' with value).

I am inclined to see [[Put]] used to shadow methods as an abuse of 
high-level interface to do low-level patching.

But of course, unless there is nice sugar, everyone uses [[Put]] since 
it's easier to write (and read).

> a call to Object.defineProperty instead, my first reaction would
> certainly be "but why isn't a regular assignment used here?". A comment
> could be added to explain the [[CanPut]], but that's what I would call
> "boilerplate comment".
>
> So far, to the general question "why is Object.defineProperty used
> instead of a regular assignment used here?", the only answer I find
> acceptable is "defining custom configurable/writable/enumerable",
> because these are things local to the code that have no syntax for them.
> In most cases, getter/setters can be defined in object literals.
> Adding "the prototype may be frozen, thus preventing shadowing" to the
> acceptable answers makes local code review harder.

:-/ But that is how it is, no?

>> Though not very constructive, I'd say this is the case where
>>
>> a.{
>>    push(elem) {
>>      ...
>>    }
>> };
>>
>> is definitely missing.
> I remembered that .{ semantics was a [[Put]] semantic, so it wouldn't
> solve the problem. Did I remember something wrong?

Of course. Mustache has the same semantics as extended literal, so it 
was [[DefineProperty]] with appropriate enum/conf/writ (and setting home 
context for methods, so in fact it did defineMethod).

> Arguably, I could use a different name than "push". But it doesn't
> change the problem:
> If I add an 'x' property to my array and later in the history of ES, an
> Array.prototype.x property is added, my code will break by virtue of
> engines updating... hmm... That's a worse situation than I initially
> thought.
>
> David

Herby


More information about the es-discuss mailing list