Bob Myers (2018-08-04T03:30:35.000Z)
>  `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 <kingmph at 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 <isiahmeadows at gmail.com>
> wrote:
>
>> Inline
>>
>> On Fri, Aug 3, 2018, 11:12 Ranando King <kingmph at 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 at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20180804/79df8551/attachment-0001.html>
rtm at gol.com (2018-08-04T10:53:26.076Z)
>  `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
rtm at gol.com (2018-08-04T10:52:24.857Z)
>  `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