shortcuts for defining block-local private names, plays nicely with @foo syntax

Brendan Eich brendan at mozilla.org
Tue Jan 24 12:08:08 PST 2012


> Axel Rauschmayer <mailto:axel at rauschma.de>
> January 24, 2012 11:06 AM
> Reiterating my support for the reformed object model (ROM): I love how 
> the ROM will finally end the clashes between application data (array 
> elements, entries in objects-as-maps) and program definition (methods, 
> non-method properties). It’s a nice clean-up, with a clear migration 
> strategy.
>
>
> @() could take the place of [] for property access, if we allow string 
> operands.

You realize this is a huge change that will break a lot of code, if done 
incompatibly. If you "do both" (only certain collections misbehave when 
using [] to access properties rather than collection data), you'll still 
have breakage -- and confusion.

I'm not saying we can't do OMR or whatever it ought to be called. But we 
should not require ocean-boiling, or make a "big red switch" problem.

/be
>
> -- 
> Dr. Axel Rauschmayer
> axel at rauschma.de <mailto:axel at rauschma.de>
>
> home: rauschma.de <http://rauschma.de>
> twitter: twitter.com/rauschma <http://twitter.com/rauschma>
> blog: 2ality.com <http://2ality.com>
>
> Allen Wirfs-Brock <mailto:allen at wirfs-brock.com>
> January 24, 2012 10:24 AM
>
>
>
>
> Perhaps, but not with its current proposed meaning.  Assume you have 
> already defined a prototypal object Dictionary, then it might be 
> useful to create literal instance of it by saying something like:
>
>
> let myDict = Dictionary <| {
>     ["key1"]: 1,
>     [computedKey()]: 2,
>     [var]: 3
> };
>
> For that to work, the individual element definitions would have to 
> desugar into @elementSet method calls on the new object and Dictionary 
> would presumably have defined @elementSet.
>
> This might be combined with regular property definitions, for example:
>
> let myDict = Dictionary <| {
>     ["key1"]: 1,
>     [computedKey()]: 2,
>     [var]: 3,
>     initialLength: 3
> };
>
> However, things would break down if you wanted to add a private named 
> property using the current obj lit computed property name proposal:
>
> const myTradeMark = name.create();
> let myDict = Dictionary <| {
>     ["key1"]: 1,
>     [computedKey()]: 2,
>     [var]: 3,
>     initialLength: 3,
>     [myTradeMark]: true
> };
>
> As [myTradeMark]: true would create a dictionary element instead of a 
> property.  To get around this we would need a different way to define 
> private named properties in object literals, such as:
>
> const myTradeMark = name.create();
> let myDict = Dictionary <| {
>     ["key1"]: 1,
>     [computedKey()]: 2,
>     [var]: 3,
>     initialLength: 3,
>     @myTradeMark: true
> };
>
> I'm not convinced that this style of literal is actually that 
> practical considering that many collection abstractions would need to 
> initialize their instances before inserting elements and it isn't 
> clear how that initialization would occur for such literals.
>
> Regardless, if we want to ever have a reformed object model where [ ] 
> can be defined to mean element access we probably shouldn't also 
> depend upon [ ] for private named property definition considering that 
> any object that redefines [ ] is going to have to define and probably 
> invoke the private named elementGet/elementSet methods.  Consider the 
> http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation#a_string_keyed_map example. 
>  If @. wasn't available to use to reference private named properties 
> something like explicit Object.getProperty calls would have to be used 
> instead and it would look like:
>
> module Name from "@name";
> import {elementGet, elementSet, elementDelete} from Name;
> import iterator from "@iter";
>
> const backingStore = Name.create();
> export function StringKeyedMap() {
> Object.setProperty(this,backingStore) = Object.create(null); //note 
> @backingStore object is a "normal object" and [ ] on it does regular 
> property access
> }
> Object.setProperty(StringKeyedMap.prototype,elementGet) = function(k) 
> {return Object.getProperty(this,backingStore)[k]}
> Object.setProperty(StringKeyedMap.prototype,elementSet) = 
> function(k,v) {Object.getProperty(this,backingStore)[k]=v;}
> StringKeyedMap.prototype.size = function() 
> {Object.getOwnPropertyNames(Object.getProperty(this,backingStore).length}; 
> //I'm lazy
> StringKeyedMap.prototype.has = function(k) {return 
> {}.hasOwnProperty.call(Object.getProperty(this,backingStore),k};
> Object.setProperty(StringKeyedMap.prototype,elementDelete) = 
> function(k) {return delete Object.getProperty(this,backingStore)[k]}
> Object.setProperty(StringKeyedMap.prototype,iterator) = function() {
> // iteration yields key/value pairs
> let self = this;
> let backing = Object.getProperty(this,backingStore);
> return (function*() {for (let x in backing) {if (self.has(x)) yield 
> [x, backing[x]]}})();
> }
>
> Much less pleasant than the original example using @.
>
> Allen
> Axel Rauschmayer <mailto:axel at rauschma.de>
> January 23, 2012 7:43 PM
>
> Would [] in object literals still make sense if [] was to become a 
> data-only operator?
>
> -- 
> Dr. Axel Rauschmayer
> axel at rauschma.de <mailto:axel at rauschma.de>
>
> home: rauschma.de <http://rauschma.de>
> twitter: twitter.com/rauschma <http://twitter.com/rauschma>
> blog: 2ality.com <http://2ality.com>
>
> Allen Wirfs-Brock <mailto:allen at wirfs-brock.com>
> January 23, 2012 3:02 PM
> I think I'm largely in agreement with what you were saying below, but 
> I do have some additional thoughts I added below...
>
> On Jan 23, 2012, at 11:28 AM, Brendan Eich wrote:
>
>>> Brendan Eich <mailto:brendan at mozilla.org>
>>> January 23, 2012 11:08 AM
>>>
>>> We run into this kind of trade-off all the time, but the fact is 
>>> that right now, dot and brackets are equivalent for properties named 
>>> by strings that match the IdentifierName lexical production. This 
>>> isn't the case for private names, of course -- by design: no string 
>>> equivalent so no dot.
>>
>> This was prolog, but then I edited too much and may have been unclear:
>>>
>>> However it does not follow that a first-class private name object 
>>> value cannot be used in square brackets to access a property it names.
>>
>> This is about 
>> http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects 
>> -- an accepted proposal in Harmony and extremely likely to be going 
>> into ES6.
>
> And nothing that I'm currently proposing would take away the ability 
> to use a private name value with square brackets to access properties. 
>  However, the current private names object proposal exclusively relies 
> on the use of square brackets. My contention is that there are both 
> usability/readability and future-proofing reasons to provide a 
> different preferred mechanism such as .@ as the primarily way of 
> accessing private name keyed properties instead of requiring use of 
> the obj[privateNameValue] pattern.
>
> Also, the square bracket preference also currently shows up in the 
> object literal computed property key proposal so we already 
> have obj[privateNameValue] pattern manifesting itself as new ES6 syntax.
>
>>
>>> If we must future-proof, then it follows that .@ and even .@() must 
>>> be part of private name objects. If everyone agrees, then we have a 
>>> decision to make.
>
> Yes, that is exactly my position.
>>
>> I don't think everyone agrees on future-proofing for
>>
>> http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation
>
> Well from my reading,  there seems to be at least as much support for 
> Object Model Reformation on this list as there is for guards and we 
> seem to put considerable attention into future proofing for guards.  I 
> think extensions to property access including support for private 
> names is an area where we need to think carefully about future 
> implications.
>>
>> yet, so I wonder if we'll all agree to add.@ etc. to 
>> private_name_objects. That got into Harmony by avoiding new syntax. 
>> We do not want to go in a circle here (rather, a progress-making 
>> spiral ;-).
>>
> I agree, having no syntax helped to get agreement on 
> private_name_objects.  But now that people are experimenting with 
> coding patterns using them we are beginning to see the usability and 
> future-proofing problems of exclusively depending upon [ ] access. 
> There may now be a better understanding of how private name objects 
> usage could benefit from some syntactic affordances.  Spiraling out 
> from private name objects to include .@ and {@name:etc} seems like an 
> all around win that I would hope we could accomplish without just 
> circling around private names again. It is less clear whether we need 
> .@() or the private declaration but the seem worthwhile to consider 
> has part of the whole private name package.
>
> Allen
>
>
>
>
> Brendan Eich <mailto:brendan at mozilla.org>
> January 23, 2012 11:28 AM
>> Brendan Eich <mailto:brendan at mozilla.org>
>> January 23, 2012 11:08 AM
>>
>> We run into this kind of trade-off all the time, but the fact is that 
>> right now, dot and brackets are equivalent for properties named by 
>> strings that match the IdentifierName lexical production. This isn't 
>> the case for private names, of course -- by design: no string 
>> equivalent so no dot.
>
> This was prolog, but then I edited too much and may have been unclear:
>>
>> However it does not follow that a first-class private name object 
>> value cannot be used in square brackets to access a property it names.
>
> This is about 
> http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects -- 
> an accepted proposal in Harmony and extremely likely to be going into 
> ES6.
>
>> If we must future-proof, then it follows that .@ and even .@() must 
>> be part of private name objects. If everyone agrees, then we have a 
>> decision to make.
>
> I don't think everyone agrees on future-proofing for
>
> http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation
>
> yet, so I wonder if we'll all agree to add.@ etc. to 
> private_name_objects. That got into Harmony by avoiding new syntax. We 
> do not want to go in a circle here (rather, a progress-making spiral ;-).
>
> /be
>>
>> /be
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>> Allen Wirfs-Brock <mailto:allen at wirfs-brock.com>
>> January 23, 2012 11:01 AM
>>
>> Below...
>> Brendan Eich <brendan at mozilla.org> wrote:
>> > Allen Wirfs-Brock <mailto:allen at wirfs-brock.com>
>> > January 23, 2012 8:43 AM
>> > On Jan 22, 2012, at 7:36 PM, Tab Atkins Jr. wrote:
>> >
>> ?..
>> >
>> > const getIterator = Iterator.getIterator;
>> > myCoolObject.prototype. at getIterator = function() {...}
>>
>> Why wouldn't myCoolObject.prototype[iterator.getIterator] work?
>>
>> /be
>>
>> It would, for now.  But, I think you gave the reason for avoiding 
>> this pattern in another reply. If we ever want to adopt my Reformed 
>> Object Model proposal then we should avoid using [ ] for private name 
>> property access.  lt would actually still work fine for objects with 
>> default [ ] behavior but not for collection objects that redefine [ ] 
>> access.
>>
>> Before encouraging a new pattern like obj[Iterator.GetIterator] we 
>> should think about its future-proofing implicationa.
>>
>> Allen


More information about the es-discuss mailing list