to Bob: Minor correction. One other thing both proposals agree on is that dynamic addition of private properties is a bad idea. So the use of Object.defineProperty() is simply a non-starter.
On Sat, Aug 4, 2018 at 2:40 PM Ranando King <king...@gmail.com> wrote: > to Bob Myers: > This is exactly the kind of private both proposal-class-fields and > proposal-object-members is proposing. The main differences between the two > are the syntax and the fact that mine also allows such fields to be defined > directly on objects. > > to Michael Theriot: > Turns out that if the implementation is sound, the same mechanism that > works for class declarations also works for object declarations. The only > extra bit required is that the language parser has to recognize the feature. > > On Sat, Aug 4, 2018 at 2:29 PM Michael Theriot < > michael.lee.ther...@gmail.com> wrote: > >> I also agree private properties / instance variables should not be >> class-exclusive. >> >> I was a big fan of the syntax used in the JavaScript Classes 1.1 proposal >> (https://github.com/zenparsing/js-classes-1.1#1-instance-variables) and >> always felt like it could have been painlessly extended to plain old >> objects. >> >> On Fri, Aug 3, 2018 at 11:30 PM, Bob Myers <r...@gol.com> wrote: >> >>> > `private`, `protected`, `class`, and a few other such keywords have >>> all been part of ES since long be for the TC39 board got their hands on >>> it. They hadn't been implemented, but they were all a very real part of >>> ES. >>> >>> Whoa. Is that just misinformed or intentionally misleading? They have >>> never been "part of ES" in any meaningful sense. It was not that they had >>> not been implemented; it was that they had not even been defined. To say >>> they are a "real part of ES" is a strange interpretation of the meaning of >>> the word "real". The notion that we would choose features to work on based >>> on some designation of certain keywords as reserved long ago, and that they >>> are now "languishing", is odd. Why not focus on "implementing" enum, or >>> final, or throws, or any other of the dozens of reserved words? >>> >>> Having said that, I think it is a valid general principle that as >>> language designers we should be very reluctant to use magic characters. >>> `**` is fine, of course, as is `=>`, or even `@` for decorators. >>> Personally, I don't think the problem of access modifiers rises to the >>> level of commonality and need for conciseness that would justify eating up >>> another magic character. We also don't want JS to start looking like Perl >>> or APL. >>> >>> Speaking as a self-appointed representative of Plain Old Programmers, I >>> do feel a need for private fields, although it was probably starting to >>> program more in TS that got me thinking that way. However, to me it feels >>> odd to tie this directly to `class` syntax. Why can't I have a private >>> field in a plain old object like `{a: 1}` (i.e., that would only be >>> accessible via a method on that object? We already have properties which >>> are enumerable and writable, for example, independent of the class >>> mechanism. Why not have properties which are private in the same way? >>> >>> The problem,of course, is that even assuming the engines implemented the >>> `private` property on descriptors, I obviously don't want to have to write >>> `Object.create({}, {a: {value: 22, private: true})`. So the problem can be >>> restated as trying to find some nice sugar for writing the above. You >>> know, something like `{a<private>: 22}`. That's obviously a completely >>> random syntax suggestion, just to show the idea. Perhaps we'd prefer to >>> have the access modifiers be specifiable under program control as an object >>> itself, to allow something like >>> >>> ``` >>> const PRIVATE = {private: true}; >>> >>> const myObject = {a(<PRIVATE>: 2; } >>> ``` >>> >>> But what would the precise meaning of such as `private` descriptor >>> property be? In operational terms, it could suffice to imagine (as a >>> behavior, not as an implementation strategy) that objects would have a flag >>> that would skip over private properties when doing property lookups. I >>> think the right implementation is to have a private property look like it's >>> not there at all when access is attempted from outside the object (in other >>> words, is undefined), rather than some kind of `PrivatePropertyAccessError`. >>> >>> The above approach ought to be extensible to class notation: >>> >>> ``` >>> class Foo ( >>> bar<PRIVATE>(): { return 22; } >>> } >>> ``` >>> >>> which would end up being something like >>> `Object.defineProperty(Foo.prototype, "bar", {value() {return 22; }, >>> private: true})`. >>> >>> Or when classes get instance variables: >>> >>> ``` >>> class Foo { >>> bar<PRIVATE> = 22; >>> ``` >>> >>> Was anything along these lines already brought up in this discussion? >>> >>> Bob >>> >>> >>> On Sat, Aug 4, 2018 at 12:30 AM Ranando King <king...@gmail.com> wrote: >>> >>>> > It certainly doesn't look or feel like JS - it feels more like Java >>>> or C#. >>>> >>>> `private`, `protected`, `class`, and a few other such keywords have all >>>> been part of ES since long be for the TC39 board got their hands on it. >>>> They hadn't been implemented, but they were all a very real part of ES. Now >>>> that `class` has been implemented, it makes little sense to leave behind >>>> the `private` and `protected` keywords when we are trying to implement >>>> their functionality. >>>> >>>> > `private` looks like an identifier, and IMHO getters, setters, and >>>> async functions suffer the same issue of the keyword seeming to blend in a >>>> little with surrounding code. >>>> >>>> Have you ever thought that `var` or `let` look like identifiers? The >>>> `private` and `protected` keywords serve the same role as `var` and `let`: >>>> declaring a variable within a given scope or context. If you think there is >>>> a good logical or rational reason to avoid using the keywords that have >>>> been embedded in the language and left languishing, waiting for their >>>> meaning to be implemented, then I'm willing to entertain that. If the >>>> reason is based on mere feeling or emotion, well. I will only entertain >>>> such arguments if my reason for doing things a certain way is equally >>>> emotion based. Nothing I'm aware of in this proposal falls into that >>>> category. I have logical reasons for every choice I've made. >>>> >>>> >> 2. `protected` on an object literal is next to useless. I've used >>>> that kind of feature almost never. >>>> >>>> > And how would that be accessible? >>>> >>>> As you said, the vast majority of the time, this feature will go >>>> unused. However, when it's needed, it would look something like this: >>>> >>>> ```js >>>> var a = { >>>> protected sharedData: 1, >>>> increment() { ++this#.sharedData; }, >>>> print() { console.log(`sharedData = ${this#.sharedData}`); } >>>> }; >>>> >>>> var b = { >>>> __proto__: a, >>>> decrement() { --this#.sharedData; } >>>> }; >>>> ``` >>>> >>>> Setting `b.__proto__ = a` causes `b.[[PrivateValues]].__proto__ = >>>> a.[[PrivateValues]]`, `b.[[DeclarationInfo]].__proto__ = >>>> a.[[InheritanceInfo]]`, and `b.[[InheritanceInfo]].proto = >>>> a.[[InheritanceInfo]]`. So it all just works. >>>> >>>> > I saw `obj#['key']`, which *strongly* suggests dynamic keys are >>>> supported. >>>> >>>> Dynamic **_keys_** are supported. Dynamic **_properties_** are not! >>>> Please don't conflate the two. Dynamic keys are calculated property names. >>>> I am definitely supporting that. Dynamic properties refers to the ability >>>> to add and remove properties from an object at any time. I am not >>>> supporting that for private/protected members (unless someone can logically >>>> convince me it's a good idea). >>>> >>>> On Fri, Aug 3, 2018 at 1:02 PM Isiah Meadows <isiahmead...@gmail.com> >>>> wrote: >>>> >>>>> Inline >>>>> >>>>> On Fri, Aug 3, 2018, 11:12 Ranando King <king...@gmail.com> wrote: >>>>> >>>>>> > 1. It's *super incredibly boilerplatey* and verbose syntactically. >>>>>> >>>>>> I'm not sure what you mean by "boilerplatey". As for being verbose, >>>>>> I'm just using the keywords everyone understands for this purpose. IMO, >>>>>> there's no advantage in trying to find some shorthand to do the same >>>>>> thing >>>>>> just because it saves a keystroke or two when it makes the code >>>>>> significantly more difficult to understand. >>>>>> >>>>> >>>>> But on the same token, it's verbose enough that I feel readability >>>>> starts to suffer substantiallly. `private` looks like an identifier, and >>>>> IMHO getters, setters, and async functions suffer the same issue of the >>>>> keyword seeming to blend in a little with surrounding code. But those are >>>>> more like decorating the function than the name. >>>>> >>>>> Based on reading the several meeting notes, I don't believe the >>>>> keyword has been especially popular there, either. It certainly doesn't >>>>> look or feel like JS - it feels more like Java or C#. >>>>> >>>>> >>>>>> > 2. `protected` on an object literal is next to useless. I've used >>>>>> that kind of feature almost never. >>>>>> >>>>>> I get where you're coming from with that. I don't see it being used >>>>>> very often (kinda like `with`), but it has to be there. If someone wants >>>>>> to >>>>>> use the facilities of `class` without the limitations of the keyword, and >>>>>> the intent is to build vertical hierarchies, they'll need the "protected" >>>>>> keyword on their prototype definition to share private data with >>>>>> descendant >>>>>> factories. >>>>>> >>>>> >>>>> And how would that be accessible? Because you can't expose it via the >>>>> same way you do in classes without basically making them public (and >>>>> several workarounds suffer similar issues). >>>>> >>>>> > I also find it odd you're supporting private dynamic properties. >>>>>> >>>>>> How'd you get to the idea that I'm supporting dynamic private >>>>>> properties? >>>>>> >>>>> >>>>> I saw `obj#['key']`, which *strongly* suggests dynamic keys are >>>>> supported. >>>>> >>>>> > I actually think it's odd there is no attempt to implement dynamic >>>>>> properties in the other "private properties" proposals. >>>>>> >>>>> >>>>>> It's not that odd. There are issues around inheritance when a >>>>>> subclass can remove the `protected` properties of its base. Further, >>>>>> exactly how do you add a new `protected` property at runtime? Under both >>>>>> proposal-class-fields and proposal-object-members, there is never any >>>>>> direct access to the private container record, so use of >>>>>> `Object.defineProperty` will never work. IMO, any attempt to implement >>>>>> dynamic private properties in any sensible and consistent fashion would >>>>>> require somehow exposing the private data record to the code. That's a >>>>>> recipe for a private data leak. Not worth it. >>>>>> >>>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss@mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss@mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss