In a word... wow. You've got me thinking hard here. Those are some peculiar
use cases, and they do a great job of highlighting why someone might forego
using `class`. One thing both proposal-class-fields and
proposal-object-members have in common is that the focus is on producing
instance-private fields. All 3 of the scenarios you presented lay outside
of that focus for one reason or another.

> Adding the same “slot” to multiple classes which don’t inherit from each
other

I'm a little confused by this one. Are you saying you want multiple
non-hierarchally related classes to have an instance private field with
shared name, such that the same private field name refers to a distinct and
separate field on each instance of every such class, but where any such
instance can have that field referenced by that shared name from any member
function of the corresponding classes? (Wow that was wordy to write out...)
If this is what you meant, you're describing friend classes. The top-down
processing nature of ES makes this a difficult thing to create a clean
syntax for without risking leaking the private state or fundamentally
altering how ES is processed. Mutual friendship is even harder.

... and yet I just thought of a way to do it. By telling you this I'm
leaving myself to consider writing a proposal containing 2 new keywords:
`befriend` and `friendly`. I don't know if this can be done with the
existing proposal being what it is. However, with my proposal, there's a
chance. The `friendly` keyword would declare that an object is prepared to
share select information with any object that befriends it. The `befriend`
keyword would allow an object to request friendship with an existing
friendly object. I'm not sure this is a good idea, though. This means that
any object declared 'friendly' is automatically insecure as all it takes to
gain access to the selected members of its private space would be to
'befriend' it.

> Selectively sharing access to private state through functions declared
outside the class body

The example you gave above still declares the functions in question inside
the `class` body, so that's not really a solution. If the example you gave
actually solves your use case, then what you're asking for here isn't even
needed. If, however, that was a bad example, then it sounds like you're
looking for friend functions. See the previous section.

> Adding slots dynamically, e.g. when adding mix-in methods that may
initialize a new slot if necessary when called, since subclassing is not
always appropriate

Sounds to me like you'd love for `class` syntax to look like this:

```js
class [<identifierName1>] [extends <identifierName2>] [mixes
<identifierName3>[, <identifierName3>[, ...]]] { ... }
```
so that the private fields of the objects in the `mixes` list are added to
the set of private fields provided by the `class` definition directly. That
would also require another proposal, but I think that can be done
regardless of which instance-private fields proposal gets accepted.

On Sat, Jul 28, 2018 at 12:49 PM Darien Valentine <valentin...@gmail.com>
wrote:

> To put this another, much briefer way, here’s a hypothetical model for
> associating private state with objects that would cover me. Privacy would
> be provided...
>
> 1. in the form of symbolic keys whose presence cannot be observed (i.e.,
> they would not be exposed by `getOwnPropertySymbols`)
> 2. and which have a syntactic declaration so that one can be sure they are
> really getting private keys (i.e., an api like `Symbol.private()` wouldn’t
> work)
>
> ```
> const bar = private();
>
> // alternatively: const #bar; could be anything so long as it’s syntactic
>
> class Foo {
>   constructor() {
>     this[bar] = 1;
>   }
> }
>
> // etc
> ```
>
> The keys would be typeof 'symbol'; the only difference being that they are
> symbols which are flagged as private when created. They would be permitted
> only in syntactic property assignments and accesses. Existing reflection
> utilities would disallow the use or appearance of such symbols both to
> ensure privacy and to maintain the invariant that they are always simple
> data properties:
>
> ```js
> Reflect.defineProperty({}, #bar, { ... }); // throws type error
> Object.getOwnPropertyDescriptors(someObjWithAPrivateSlot); // does not
> include it
> foo[bar] = 2; // fine
> ```
>
> This is significantly simpler than what’s in flight both in terms of
> syntax and mechanics, which makes me suspicious that I’m probably ignoring
> things that other people find important. However it would bring parity to
> ES objects wrt being able to implement genuinely private slots in userland
> with the same flexibility as what is done internally.
>
> In total, this entails a new primary expression, a boolean flag associated
> with symbol values, and an extra step added to several algorithms
> associated with Object and Reflect.
> _______________________________________________
> 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

Reply via email to