July 25, 2012 - TC39 Meeting Notes

David Bruant bruant.d at gmail.com
Sat Jul 28 06:02:56 PDT 2012

Le 28/07/2012 14:37, Herby Vojčík a écrit :
> 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.
I don't understand where you're getting at. Let's try to agree on some
definitions, first:
1) There is my intention which I described above
2) there is the JS "VM" (set of primitive operations, like [[Put]] and
3) there is syntax which is expected to be in between, allowing to
translate intentions (high-level descriptions) into the language
primitive operations.

My definition of "intention" is a fairly high-level description. As I
said, what I need is the fill my array with "push" calls. How this
method ended up here is not part of my intent, that's why I could
implement y intention with a new a.__proto__.
Then, there is the syntax. "a.push = function(elem){...}" expresses very
well my intent: it references the only object for which I want a custom
"push", it shows the 'push' name and the assignment with "=" is part of
the programming culture.

So, the way i see it, [[Put]] and [[DefineProperty]] are not intentions.
They are operations through which I may be able to implement my use
case. As it turns out, both map to one syntactic form. It could not be
the case.

> 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.
Currently, [[Put]] does shadow prototype methods and the sky hasn't
fallen. The question in debate is whether [[Put]] should shadow when the
prototype is frozen.

>> 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?
That's what the spec says, but V8 has implemented something else (and I
haven't seen an intention to change this behavior), so what the spec
says doesn't really matter.


More information about the es-discuss mailing list