Re: !Re: proposal: Object Members

2018-08-08 Thread Ranando King
> To discover what's written into the supposedly private x, just call SetX
on an object that's not an instance of Foo.

Actually, it's fairly trivial to avoid that issue in the engine. As long as
both objects and functions know what private data they have access to, then
all you need is a check to determine whether or not the object instance has
access to the same private data as the function. If not, throw a TypeError
et voilà, no leaks. That's part of how my POC works. The real difficulty
with not having a  marker on the access comes only because JS
programmers are so very used to being able to tack a new property on to any
object they see, and readily abuse this capability to amazing effect. Given
that only the creator of an object should be able to manage its private
properties, and that these properties must always exist even if undefined
(they're considered implementation details), property access quickly
becomes a minefield as objects with private members pass through code
intent on attaching new public members, even if they're just temporary.

On Tue, Aug 7, 2018 at 4:29 PM Waldemar Horwat  wrote:

> On 08/03/2018 08:30 PM, Bob Myers 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: 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(: 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(): { 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 = 22;
> > ```
> >
> > Was anything along these lines already brought up in this discussion?
>
> Yes.  There are a couple answers:
>
> - If you have the  marker on both definitions and accesses of the
> property, then you get a proposal that's essentially isomorphic to the
> committee's current private proposal.
>
> - If you have the  marker on definitions but not accesses of the
> property, then the proposal lea

Re: !Re: proposal: Object Members

2018-08-07 Thread Waldemar Horwat

On 08/03/2018 08:30 PM, Bob Myers 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: 
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(: 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(): { 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 = 22;
```

Was anything along these lines already brought up in this discussion?


Yes.  There are a couple answers:

- If you have the  marker on both definitions and accesses of the 
property, then you get a proposal that's essentially isomorphic to the committee's 
current private proposal.

- If you have the  marker on definitions but not accesses of the 
property, then the proposal leaks private state like a sieve:

For example:

class Foo (
  x;

  SetX() {this.x = ;}
}

To discover what's written into the supposedly private x, just call SetX on an 
object that's not an instance of Foo.

There are analogous examples for reading instead of writing.

Waldemar
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-08-04 Thread Ranando King
You might want to consider it "intentionally misleading", but when I say
that they are a "real part of ES", I mean that when they are present under
certain circumstances, ES will take on behavior it wouldn't have if the
words had not been reserved. Does that mean those words are of any
practical use in the language? **NO**. However, the simple fact that the
behavior of the language changes as a result of their appearance makes them
a part of the language, albeit useless. However, all this has no logical
merit for my reason to use them. So believe what you will. I just wanted to
see how people would respond. That gives me a bit of useful information
about how to word my proposal as I make adjustments.

On Fri, Aug 3, 2018 at 10:32 PM Bob Myers  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: 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(: 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(): { 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 = 22;
> ```
>
> Was anything along these lines already brought up in this discussion?
>
> Bob
>
>
> On Sat, Aug 4, 2018 at 12:30 AM Ranando King  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 id

Re: !Re: proposal: Object Members

2018-08-04 Thread Ranando King
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  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  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: 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(: 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(): { 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 = 22;
>>> ```
>>>
>>> Was anything along these lines already brought up in this discussion?
>>>
>>> Bob
>>>
>>>
>>> On Sat, Aug 4, 2018 at 12:30 AM Ranando King  wrote:
>>>
 > It certainly doesn't look or feel like JS - it feels more like Java
 or C#.

Re: !Re: proposal: Object Members

2018-08-04 Thread Ranando King
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  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: 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(: 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(): { 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 = 22;
>> ```
>>
>> Was anything along these lines already brought up in this discussion?
>>
>> Bob
>>
>>
>> On Sat, Aug 4, 2018 at 12:30 AM Ranando King  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 w

Re: !Re: proposal: Object Members

2018-08-04 Thread Michael Theriot
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  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: 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(: 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(): { 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 = 22;
> ```
>
> Was anything along these lines already brought up in this discussion?
>
> Bob
>
>
> On Sat, Aug 4, 2018 at 12:30 AM Ranando King  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
>> reaso

Re: !Re: proposal: Object Members

2018-08-03 Thread Bob Myers
>  `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: 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(: 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(): { 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 = 22;
```

Was anything along these lines already brought up in this discussion?

Bob


On Sat, Aug 4, 2018 at 12:30 AM Ranando King  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 

Re: !Re: proposal: Object Members

2018-08-03 Thread Waldemar Horwat

On 08/03/2018 02:37 PM, Tab Atkins Jr. wrote:

Yes, they were reserved because they were the Java reserved keywords,
with the intention that we might add more Java features later in the
langauge's evolution. That has no bearing on their use today.


That's exactly what we did.  In the early days of ECMAScript we had no plans to 
use those but reserved them just in case.  Some of the ones we reserved later 
accidentally became unreserved.

Introducing a new keyword-based feature when that keyword isn't reserved leads to severe 
complications and arbitrary [no linebreak here] rules.  The nastiest cover grammars are 
some of the consequences of things like being able to use "async" as a function 
name.

Waldemar
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-08-03 Thread Tab Atkins Jr.
On Fri, Aug 3, 2018 at 2:33 PM Ranando King  wrote:
>
> A side thought:
>
> If a language reserving certain words, even to the point of generating error 
> messages related to using them under certain circumstances, doesn't 
> constitute at least part of a justification for using them, then why do 
> languages so often reserve keywords for future use? Isn't precisely the case 
> with `private`, `protected`, `public`, and `package` (and `class` prior to 
> ES6). Weren't they all holdovers from the fact that the syntax for ES was 
> mostly borrowed from Java, and kept in reserve just in case the concepts 
> behind these keywords became language features?
>
> If that's not the case, then there's no point in keeping these (or indeed 
> any) keywords in reserve.

Yes, they were reserved because they were the Java reserved keywords,
with the intention that we might add more Java features later in the
langauge's evolution. That has no bearing on their use today.

Unreserving them wouldn't provide much benefit now. But keeping them
reserved still doesn't mean we have any particular need to use them.

~TJ
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-08-03 Thread Ranando King
A side thought:

If a language reserving certain words, even to the point of generating
error messages related to using them under certain circumstances, doesn't
constitute at least part of a justification for using them, then why do
languages so often reserve keywords for future use? Isn't precisely the
case with `private`, `protected`, `public`, and `package` (and `class`
prior to ES6). Weren't they all holdovers from the fact that the syntax for
ES was mostly borrowed from Java, and kept in reserve just in case the
concepts behind these keywords became language features?

If that's not the case, then there's no point in keeping these (or indeed
any) keywords in reserve.

On Fri, Aug 3, 2018 at 4:24 PM Ranando King  wrote:

> Good argument. However, the fact that the wide adoption `private` and
> `public` in other languages constitutes an immediately understood,
> well-recognized syntax for declaring privilege levels in languages with
> classes is my primary reason for adopting those already reserved keywords.
> The fact that I also think it would be a waste not to use them is just a
> personal bias I'm willing to disregard in the face of a good, sound,
> logical reason for not using them.
>
> On Fri, Aug 3, 2018 at 4:07 PM Jordan Harband  wrote:
>
>> A keyword being reserved is NOT the same as "being a part of ES".
>> `package` is reserved too, but there's zero concept of packages in the
>> language, and absolutely no obligation for there ever to be one.
>>
>> To reiterate, the existence of `private`, `public`, and `protected` as
>> reserved keywords in *no way* justifies including any, or all, of these
>> keywords in any language feature.
>>
>> On Fri, Aug 3, 2018 at 12:36 PM, Isiah Meadows 
>> wrote:
>>
>>> My "private symbols" proposal supports it, but that's about it.
>>>
>>> I think the main thing is that the use case isn't really that large,
>>> so nobody's really thought about it. (You can always "pretend" it
>>> exists by creating a single private key that's just an object
>>> dictionary.)
>>> -
>>>
>>> Isiah Meadows
>>> cont...@isiahmeadows.com
>>> www.isiahmeadows.com
>>>
>>>
>>> On Fri, Aug 3, 2018 at 8:34 AM, Michael Theriot
>>>  wrote:
>>> > If I understand the terminology, "private dynamic properties" are
>>> easily
>>> > polyfilled via weakmaps?
>>> >
>>> > I actually think it's odd there is no attempt to implement dynamic
>>> > properties in the other "private properties" proposals.
>>> >
>>> >
>>> > On Friday, August 3, 2018, Isiah Meadows 
>>> wrote:
>>> >>
>>> >> Okay, now that I look at that proposal, I see two issues right off:
>>> >>
>>> >> 1. It's *super incredibly boilerplatey* and verbose syntactically. I
>>> >> don't know very many people who'd be willing to downgrade very far
>>> >> from even what TypeScript has. (I'm specifically referring to the
>>> >> declarations here.)
>>> >> 2. `protected` on an object literal is next to useless. I've used that
>>> >> kind of feature almost never.
>>> >>
>>> >> I also find it odd you're supporting private dynamic properties. It
>>> >> does make polyfilling next to impossible, though.
>>> >>
>>> >> Just my 2 cents on it. (I glanced over this while very tired, so I
>>> >> probably missed several highlights. These are what stuck out to me.)
>>> >>
>>> >> -
>>> >>
>>> >> Isiah Meadows
>>> >> cont...@isiahmeadows.com
>>> >> www.isiahmeadows.com
>>> >>
>>> >>
>>> >> On Wed, Aug 1, 2018 at 11:54 PM, Ranando King 
>>> wrote:
>>> >> >
>>> https://github.com/rdking/proposal-object-members/blob/master/README.md
>>> >> >
>>> >> > On Wed, Aug 1, 2018 at 2:01 AM Isiah Meadows <
>>> isiahmead...@gmail.com>
>>> >> > wrote:
>>> >> >>
>>> >> >> Do you have a link to this proposal so I can take a look at it?
>>> It'd
>>> >> >> be much easier to critique it if I could see the proposal text.
>>> >> >> -
>>> >> >>
>>> >> >> Isiah Meadows
>>> >> >> cont...@isiahmeadows.com
>>> >> >> www.isiahmeadows.com
>>> >> >>
>>> >> >>
>>> >> >> On Wed, Aug 1, 2018 at 2:18 AM, Ranando King 
>>> wrote:
>>> >> >> >> If you go back a few months, what you're proposing is *very*
>>> >> >> >> similar,
>>> >> >> >> at
>>> >> >> >> least functionally, to my previous iteration of my proposal:
>>> >> >> >
>>> >> >> > That functional similarity is intentional. After pouring over
>>> years
>>> >> >> > worth of
>>> >> >> > posts, I figured out what the vast majority of the
>>> >> >> > proposal-class-fields
>>> >> >> > detractors actually wanted: an elegant, easily recognized syntax
>>> for
>>> >> >> > adding
>>> >> >> > private members to objects.
>>> >> >> >
>>> >> >> >> My main problem was that trying to limit private properties to
>>> >> >> >> objects
>>> >> >> >> created within a scope got complicated in a hurry once you
>>> >> >> >> considered
>>> >> >> >> all
>>> >> >> >> the small details, and it just didn't seem simple anymore.
>>> >> >> >
>>> >> >> > I noticed that about your proposal too. I'm also pretty sure that
>>> >> >> > Daniel
>>> >> >> > E.
>>> >> >> > and 

Re: !Re: proposal: Object Members

2018-08-03 Thread Ranando King
Good argument. However, the fact that the wide adoption `private` and
`public` in other languages constitutes an immediately understood,
well-recognized syntax for declaring privilege levels in languages with
classes is my primary reason for adopting those already reserved keywords.
The fact that I also think it would be a waste not to use them is just a
personal bias I'm willing to disregard in the face of a good, sound,
logical reason for not using them.

On Fri, Aug 3, 2018 at 4:07 PM Jordan Harband  wrote:

> A keyword being reserved is NOT the same as "being a part of ES".
> `package` is reserved too, but there's zero concept of packages in the
> language, and absolutely no obligation for there ever to be one.
>
> To reiterate, the existence of `private`, `public`, and `protected` as
> reserved keywords in *no way* justifies including any, or all, of these
> keywords in any language feature.
>
> On Fri, Aug 3, 2018 at 12:36 PM, Isiah Meadows 
> wrote:
>
>> My "private symbols" proposal supports it, but that's about it.
>>
>> I think the main thing is that the use case isn't really that large,
>> so nobody's really thought about it. (You can always "pretend" it
>> exists by creating a single private key that's just an object
>> dictionary.)
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Fri, Aug 3, 2018 at 8:34 AM, Michael Theriot
>>  wrote:
>> > If I understand the terminology, "private dynamic properties" are easily
>> > polyfilled via weakmaps?
>> >
>> > I actually think it's odd there is no attempt to implement dynamic
>> > properties in the other "private properties" proposals.
>> >
>> >
>> > On Friday, August 3, 2018, Isiah Meadows 
>> wrote:
>> >>
>> >> Okay, now that I look at that proposal, I see two issues right off:
>> >>
>> >> 1. It's *super incredibly boilerplatey* and verbose syntactically. I
>> >> don't know very many people who'd be willing to downgrade very far
>> >> from even what TypeScript has. (I'm specifically referring to the
>> >> declarations here.)
>> >> 2. `protected` on an object literal is next to useless. I've used that
>> >> kind of feature almost never.
>> >>
>> >> I also find it odd you're supporting private dynamic properties. It
>> >> does make polyfilling next to impossible, though.
>> >>
>> >> Just my 2 cents on it. (I glanced over this while very tired, so I
>> >> probably missed several highlights. These are what stuck out to me.)
>> >>
>> >> -
>> >>
>> >> Isiah Meadows
>> >> cont...@isiahmeadows.com
>> >> www.isiahmeadows.com
>> >>
>> >>
>> >> On Wed, Aug 1, 2018 at 11:54 PM, Ranando King 
>> wrote:
>> >> >
>> https://github.com/rdking/proposal-object-members/blob/master/README.md
>> >> >
>> >> > On Wed, Aug 1, 2018 at 2:01 AM Isiah Meadows > >
>> >> > wrote:
>> >> >>
>> >> >> Do you have a link to this proposal so I can take a look at it? It'd
>> >> >> be much easier to critique it if I could see the proposal text.
>> >> >> -
>> >> >>
>> >> >> Isiah Meadows
>> >> >> cont...@isiahmeadows.com
>> >> >> www.isiahmeadows.com
>> >> >>
>> >> >>
>> >> >> On Wed, Aug 1, 2018 at 2:18 AM, Ranando King 
>> wrote:
>> >> >> >> If you go back a few months, what you're proposing is *very*
>> >> >> >> similar,
>> >> >> >> at
>> >> >> >> least functionally, to my previous iteration of my proposal:
>> >> >> >
>> >> >> > That functional similarity is intentional. After pouring over
>> years
>> >> >> > worth of
>> >> >> > posts, I figured out what the vast majority of the
>> >> >> > proposal-class-fields
>> >> >> > detractors actually wanted: an elegant, easily recognized syntax
>> for
>> >> >> > adding
>> >> >> > private members to objects.
>> >> >> >
>> >> >> >> My main problem was that trying to limit private properties to
>> >> >> >> objects
>> >> >> >> created within a scope got complicated in a hurry once you
>> >> >> >> considered
>> >> >> >> all
>> >> >> >> the small details, and it just didn't seem simple anymore.
>> >> >> >
>> >> >> > I noticed that about your proposal too. I'm also pretty sure that
>> >> >> > Daniel
>> >> >> > E.
>> >> >> > and Kevin G. ran into the same issues back during the
>> >> >> > proposal-private-names
>> >> >> > days which is why the private names concept is just an
>> implementation
>> >> >> > detail
>> >> >> > in their current proposal. My proposal is made less complicated by
>> >> >> > breaking
>> >> >> > the problem down into the 3 pieces required to make it all work:
>> >> >> > 1. a record to store private data
>> >> >> > 2. an array to hold references to the schema records of accessible
>> >> >> > private
>> >> >> > data
>> >> >> > 3. a schema record for the sharable data.
>> >> >> >
>> >> >> > In this way private = encapsulated on a non-function, protected =
>> >> >> > private +
>> >> >> > shared, and static = encapsulated on a function. It should be
>> easy to
>> >> >> > sort
>> >> >> > out how the data would be stored given such simple definitions.
>> These
>> >> >> > simple
>> >> >> 

Re: !Re: proposal: Object Members

2018-08-03 Thread Jordan Harband
A keyword being reserved is NOT the same as "being a part of ES". `package`
is reserved too, but there's zero concept of packages in the language, and
absolutely no obligation for there ever to be one.

To reiterate, the existence of `private`, `public`, and `protected` as
reserved keywords in *no way* justifies including any, or all, of these
keywords in any language feature.

On Fri, Aug 3, 2018 at 12:36 PM, Isiah Meadows 
wrote:

> My "private symbols" proposal supports it, but that's about it.
>
> I think the main thing is that the use case isn't really that large,
> so nobody's really thought about it. (You can always "pretend" it
> exists by creating a single private key that's just an object
> dictionary.)
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Fri, Aug 3, 2018 at 8:34 AM, Michael Theriot
>  wrote:
> > If I understand the terminology, "private dynamic properties" are easily
> > polyfilled via weakmaps?
> >
> > I actually think it's odd there is no attempt to implement dynamic
> > properties in the other "private properties" proposals.
> >
> >
> > On Friday, August 3, 2018, Isiah Meadows  wrote:
> >>
> >> Okay, now that I look at that proposal, I see two issues right off:
> >>
> >> 1. It's *super incredibly boilerplatey* and verbose syntactically. I
> >> don't know very many people who'd be willing to downgrade very far
> >> from even what TypeScript has. (I'm specifically referring to the
> >> declarations here.)
> >> 2. `protected` on an object literal is next to useless. I've used that
> >> kind of feature almost never.
> >>
> >> I also find it odd you're supporting private dynamic properties. It
> >> does make polyfilling next to impossible, though.
> >>
> >> Just my 2 cents on it. (I glanced over this while very tired, so I
> >> probably missed several highlights. These are what stuck out to me.)
> >>
> >> -
> >>
> >> Isiah Meadows
> >> cont...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Wed, Aug 1, 2018 at 11:54 PM, Ranando King 
> wrote:
> >> > https://github.com/rdking/proposal-object-members/blob/
> master/README.md
> >> >
> >> > On Wed, Aug 1, 2018 at 2:01 AM Isiah Meadows 
> >> > wrote:
> >> >>
> >> >> Do you have a link to this proposal so I can take a look at it? It'd
> >> >> be much easier to critique it if I could see the proposal text.
> >> >> -
> >> >>
> >> >> Isiah Meadows
> >> >> cont...@isiahmeadows.com
> >> >> www.isiahmeadows.com
> >> >>
> >> >>
> >> >> On Wed, Aug 1, 2018 at 2:18 AM, Ranando King 
> wrote:
> >> >> >> If you go back a few months, what you're proposing is *very*
> >> >> >> similar,
> >> >> >> at
> >> >> >> least functionally, to my previous iteration of my proposal:
> >> >> >
> >> >> > That functional similarity is intentional. After pouring over years
> >> >> > worth of
> >> >> > posts, I figured out what the vast majority of the
> >> >> > proposal-class-fields
> >> >> > detractors actually wanted: an elegant, easily recognized syntax
> for
> >> >> > adding
> >> >> > private members to objects.
> >> >> >
> >> >> >> My main problem was that trying to limit private properties to
> >> >> >> objects
> >> >> >> created within a scope got complicated in a hurry once you
> >> >> >> considered
> >> >> >> all
> >> >> >> the small details, and it just didn't seem simple anymore.
> >> >> >
> >> >> > I noticed that about your proposal too. I'm also pretty sure that
> >> >> > Daniel
> >> >> > E.
> >> >> > and Kevin G. ran into the same issues back during the
> >> >> > proposal-private-names
> >> >> > days which is why the private names concept is just an
> implementation
> >> >> > detail
> >> >> > in their current proposal. My proposal is made less complicated by
> >> >> > breaking
> >> >> > the problem down into the 3 pieces required to make it all work:
> >> >> > 1. a record to store private data
> >> >> > 2. an array to hold references to the schema records of accessible
> >> >> > private
> >> >> > data
> >> >> > 3. a schema record for the sharable data.
> >> >> >
> >> >> > In this way private = encapsulated on a non-function, protected =
> >> >> > private +
> >> >> > shared, and static = encapsulated on a function. It should be easy
> to
> >> >> > sort
> >> >> > out how the data would be stored given such simple definitions.
> These
> >> >> > simple
> >> >> > definitions also mean that encapsulation is naturally confined to
> >> >> > definitions. Attempts to alter that state lead to strange logical
> >> >> > contradictions and potential leaks of encapsulated data. I have
> >> >> > thought
> >> >> > of
> >> >> > the possibility that private data could be added after definition,
> >> >> > but
> >> >> > every
> >> >> > attempt I make to consider such a thing has so far led to a risk of
> >> >> > leaking.
> >> >> >
> >> >> > I've been working on some code that can serve as a proof-of-concept
> >> >> > in
> >> >> > ES6.
> >> >> > It will implement all of my proposal that can reasonably be
> >> >> > impleme

Re: !Re: proposal: Object Members

2018-08-03 Thread Isiah Meadows
My "private symbols" proposal supports it, but that's about it.

I think the main thing is that the use case isn't really that large,
so nobody's really thought about it. (You can always "pretend" it
exists by creating a single private key that's just an object
dictionary.)
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Fri, Aug 3, 2018 at 8:34 AM, Michael Theriot
 wrote:
> If I understand the terminology, "private dynamic properties" are easily
> polyfilled via weakmaps?
>
> I actually think it's odd there is no attempt to implement dynamic
> properties in the other "private properties" proposals.
>
>
> On Friday, August 3, 2018, Isiah Meadows  wrote:
>>
>> Okay, now that I look at that proposal, I see two issues right off:
>>
>> 1. It's *super incredibly boilerplatey* and verbose syntactically. I
>> don't know very many people who'd be willing to downgrade very far
>> from even what TypeScript has. (I'm specifically referring to the
>> declarations here.)
>> 2. `protected` on an object literal is next to useless. I've used that
>> kind of feature almost never.
>>
>> I also find it odd you're supporting private dynamic properties. It
>> does make polyfilling next to impossible, though.
>>
>> Just my 2 cents on it. (I glanced over this while very tired, so I
>> probably missed several highlights. These are what stuck out to me.)
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Wed, Aug 1, 2018 at 11:54 PM, Ranando King  wrote:
>> > https://github.com/rdking/proposal-object-members/blob/master/README.md
>> >
>> > On Wed, Aug 1, 2018 at 2:01 AM Isiah Meadows 
>> > wrote:
>> >>
>> >> Do you have a link to this proposal so I can take a look at it? It'd
>> >> be much easier to critique it if I could see the proposal text.
>> >> -
>> >>
>> >> Isiah Meadows
>> >> cont...@isiahmeadows.com
>> >> www.isiahmeadows.com
>> >>
>> >>
>> >> On Wed, Aug 1, 2018 at 2:18 AM, Ranando King  wrote:
>> >> >> If you go back a few months, what you're proposing is *very*
>> >> >> similar,
>> >> >> at
>> >> >> least functionally, to my previous iteration of my proposal:
>> >> >
>> >> > That functional similarity is intentional. After pouring over years
>> >> > worth of
>> >> > posts, I figured out what the vast majority of the
>> >> > proposal-class-fields
>> >> > detractors actually wanted: an elegant, easily recognized syntax for
>> >> > adding
>> >> > private members to objects.
>> >> >
>> >> >> My main problem was that trying to limit private properties to
>> >> >> objects
>> >> >> created within a scope got complicated in a hurry once you
>> >> >> considered
>> >> >> all
>> >> >> the small details, and it just didn't seem simple anymore.
>> >> >
>> >> > I noticed that about your proposal too. I'm also pretty sure that
>> >> > Daniel
>> >> > E.
>> >> > and Kevin G. ran into the same issues back during the
>> >> > proposal-private-names
>> >> > days which is why the private names concept is just an implementation
>> >> > detail
>> >> > in their current proposal. My proposal is made less complicated by
>> >> > breaking
>> >> > the problem down into the 3 pieces required to make it all work:
>> >> > 1. a record to store private data
>> >> > 2. an array to hold references to the schema records of accessible
>> >> > private
>> >> > data
>> >> > 3. a schema record for the sharable data.
>> >> >
>> >> > In this way private = encapsulated on a non-function, protected =
>> >> > private +
>> >> > shared, and static = encapsulated on a function. It should be easy to
>> >> > sort
>> >> > out how the data would be stored given such simple definitions. These
>> >> > simple
>> >> > definitions also mean that encapsulation is naturally confined to
>> >> > definitions. Attempts to alter that state lead to strange logical
>> >> > contradictions and potential leaks of encapsulated data. I have
>> >> > thought
>> >> > of
>> >> > the possibility that private data could be added after definition,
>> >> > but
>> >> > every
>> >> > attempt I make to consider such a thing has so far led to a risk of
>> >> > leaking.
>> >> >
>> >> > I've been working on some code that can serve as a proof-of-concept
>> >> > in
>> >> > ES6.
>> >> > It will implement all of my proposal that can reasonably be
>> >> > implemented
>> >> > in
>> >> > ES6 using Proxy. It's already in the proposal repository under the
>> >> > POC
>> >> > branch, but it's still a WIP. For now, it already supports inheriting
>> >> > from
>> >> > native objects. I'm working on subclassing right now. By the time I
>> >> > get
>> >> > done
>> >> > (likely this coming Monday), it should support every feature in my
>> >> > proposal.
>> >> > I'm basically using it as a means to check the viability of my
>> >> > proposal.
>> >> >
>> >> > On Tue, Jul 31, 2018 at 4:35 PM Isiah Meadows
>> >> > 
>> >> > wrote:
>> >> >>
>> >> >> If you go back a few months, what you're proposing is *very*
>> >> >> similar,
>> >> >> at least functional

Re: !Re: proposal: Object Members

2018-08-03 Thread Ranando King
> 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  wrote:

> Inline
>
> On Fri, Aug 3, 2018, 11:12 Ranando King  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 ac

Re: !Re: proposal: Object Members

2018-08-03 Thread Ranando King
I'm glad someone other than myself can appreciate it. I trudged my way
through a lot of variations on the theme to find the implementation that
would make the most sense and still behave properly. It really is rather
simple. The POC will more or less show how it can be implemented. The only
issue I'm having at the moment is trying to capture access to `super`
properties. Apparently V8 doesn't redirect `super` through prototypes like
I was expecting, so I'm beginning to think that I won't be able to
implement calls to protected methods of the base in this POC.

On Fri, Aug 3, 2018 at 11:38 AM Michael Theriot <
michael.lee.ther...@gmail.com> wrote:

> I'd argue that is 1:1 with the way subclasses work today.
>
> Protected properties can be implemented by sharing the weakmap instance
> with the parent.
>
> Private properties can be implemented by using a unique weakmap instance
> for the subclass.
>
> I actually think it's pretty straightforward and simple.
>
> On Friday, August 3, 2018, Ranando King  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.
>>
>> > 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. It's even more necessary for people writing factory factories.
>> The only other way to achieve the same thing would be to force them to use
>> `Function()` or `eval` and build up the code as strings. I'd rather avoid
>> that.
>>
>> > 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?
>> The first 2 paragraphs in the implementation say that all private container
>> records are sealed, and all fields in info records are added read-only. If
>> it wasn't clear from that, I'm going to have to re-write that section.
>> However, the intent is that after the declaration process is complete, what
>> you have is all you can get. No additional private fields can be added
>> later. I considered dynamic private data, but that can get very messy very
>> quickly.
>>
>> > 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


Re: !Re: proposal: Object Members

2018-08-03 Thread Michael Theriot
I'd argue that is 1:1 with the way subclasses work today.

Protected properties can be implemented by sharing the weakmap instance
with the parent.

Private properties can be implemented by using a unique weakmap instance
for the subclass.

I actually think it's pretty straightforward and simple.

On Friday, August 3, 2018, Ranando King  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.
>
> > 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. It's even more necessary for people writing factory factories.
> The only other way to achieve the same thing would be to force them to use
> `Function()` or `eval` and build up the code as strings. I'd rather avoid
> that.
>
> > 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?
> The first 2 paragraphs in the implementation say that all private container
> records are sealed, and all fields in info records are added read-only. If
> it wasn't clear from that, I'm going to have to re-write that section.
> However, the intent is that after the declaration process is complete, what
> you have is all you can get. No additional private fields can be added
> later. I considered dynamic private data, but that can get very messy very
> quickly.
>
> > 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


Re: !Re: proposal: Object Members

2018-08-03 Thread Ranando King
> 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.

> 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. It's even more necessary for people writing factory factories.
The only other way to achieve the same thing would be to force them to use
`Function()` or `eval` and build up the code as strings. I'd rather avoid
that.

> 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?
The first 2 paragraphs in the implementation say that all private container
records are sealed, and all fields in info records are added read-only. If
it wasn't clear from that, I'm going to have to re-write that section.
However, the intent is that after the declaration process is complete, what
you have is all you can get. No additional private fields can be added
later. I considered dynamic private data, but that can get very messy very
quickly.

> 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


Re: !Re: proposal: Object Members

2018-08-03 Thread Michael Theriot
If I understand the terminology, "private dynamic properties" are easily
polyfilled via weakmaps?

I actually think it's odd there is no attempt to implement dynamic
properties in the other "private properties" proposals.

On Friday, August 3, 2018, Isiah Meadows  wrote:

> Okay, now that I look at that proposal, I see two issues right off:
>
> 1. It's *super incredibly boilerplatey* and verbose syntactically. I
> don't know very many people who'd be willing to downgrade very far
> from even what TypeScript has. (I'm specifically referring to the
> declarations here.)
> 2. `protected` on an object literal is next to useless. I've used that
> kind of feature almost never.
>
> I also find it odd you're supporting private dynamic properties. It
> does make polyfilling next to impossible, though.
>
> Just my 2 cents on it. (I glanced over this while very tired, so I
> probably missed several highlights. These are what stuck out to me.)
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Wed, Aug 1, 2018 at 11:54 PM, Ranando King  wrote:
> > https://github.com/rdking/proposal-object-members/blob/master/README.md
> >
> > On Wed, Aug 1, 2018 at 2:01 AM Isiah Meadows 
> wrote:
> >>
> >> Do you have a link to this proposal so I can take a look at it? It'd
> >> be much easier to critique it if I could see the proposal text.
> >> -
> >>
> >> Isiah Meadows
> >> cont...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Wed, Aug 1, 2018 at 2:18 AM, Ranando King  wrote:
> >> >> If you go back a few months, what you're proposing is *very* similar,
> >> >> at
> >> >> least functionally, to my previous iteration of my proposal:
> >> >
> >> > That functional similarity is intentional. After pouring over years
> >> > worth of
> >> > posts, I figured out what the vast majority of the
> proposal-class-fields
> >> > detractors actually wanted: an elegant, easily recognized syntax for
> >> > adding
> >> > private members to objects.
> >> >
> >> >> My main problem was that trying to limit private properties to
> objects
> >> >> created within a scope got complicated in a hurry once you considered
> >> >> all
> >> >> the small details, and it just didn't seem simple anymore.
> >> >
> >> > I noticed that about your proposal too. I'm also pretty sure that
> Daniel
> >> > E.
> >> > and Kevin G. ran into the same issues back during the
> >> > proposal-private-names
> >> > days which is why the private names concept is just an implementation
> >> > detail
> >> > in their current proposal. My proposal is made less complicated by
> >> > breaking
> >> > the problem down into the 3 pieces required to make it all work:
> >> > 1. a record to store private data
> >> > 2. an array to hold references to the schema records of accessible
> >> > private
> >> > data
> >> > 3. a schema record for the sharable data.
> >> >
> >> > In this way private = encapsulated on a non-function, protected =
> >> > private +
> >> > shared, and static = encapsulated on a function. It should be easy to
> >> > sort
> >> > out how the data would be stored given such simple definitions. These
> >> > simple
> >> > definitions also mean that encapsulation is naturally confined to
> >> > definitions. Attempts to alter that state lead to strange logical
> >> > contradictions and potential leaks of encapsulated data. I have
> thought
> >> > of
> >> > the possibility that private data could be added after definition, but
> >> > every
> >> > attempt I make to consider such a thing has so far led to a risk of
> >> > leaking.
> >> >
> >> > I've been working on some code that can serve as a proof-of-concept in
> >> > ES6.
> >> > It will implement all of my proposal that can reasonably be
> implemented
> >> > in
> >> > ES6 using Proxy. It's already in the proposal repository under the POC
> >> > branch, but it's still a WIP. For now, it already supports inheriting
> >> > from
> >> > native objects. I'm working on subclassing right now. By the time I
> get
> >> > done
> >> > (likely this coming Monday), it should support every feature in my
> >> > proposal.
> >> > I'm basically using it as a means to check the viability of my
> proposal.
> >> >
> >> > On Tue, Jul 31, 2018 at 4:35 PM Isiah Meadows  >
> >> > wrote:
> >> >>
> >> >> If you go back a few months, what you're proposing is *very* similar,
> >> >> at least functionally, to my previous iteration of my proposal:
> >> >>
> >> >>
> >> >> https://github.com/isiahmeadows/private-symbol-proposal/blob/
> c5c9781d9e76123c92d8fbc83681fdd3a9b0b319/README.md
> >> >>
> >> >> My main problem was that trying to limit private properties to
> objects
> >> >> created within a scope got complicated in a hurry once you considered
> >> >> all the small details, and it just didn't seem simple anymore. It
> only
> >> >> got more complicated when you started getting into the logistics of
> >> >> integrating with modules.
> >> >>
> >> >> So I've considered the issue and explored it pretty thoroughly

Re: !Re: proposal: Object Members

2018-08-03 Thread Isiah Meadows
Okay, now that I look at that proposal, I see two issues right off:

1. It's *super incredibly boilerplatey* and verbose syntactically. I
don't know very many people who'd be willing to downgrade very far
from even what TypeScript has. (I'm specifically referring to the
declarations here.)
2. `protected` on an object literal is next to useless. I've used that
kind of feature almost never.

I also find it odd you're supporting private dynamic properties. It
does make polyfilling next to impossible, though.

Just my 2 cents on it. (I glanced over this while very tired, so I
probably missed several highlights. These are what stuck out to me.)

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Wed, Aug 1, 2018 at 11:54 PM, Ranando King  wrote:
> https://github.com/rdking/proposal-object-members/blob/master/README.md
>
> On Wed, Aug 1, 2018 at 2:01 AM Isiah Meadows  wrote:
>>
>> Do you have a link to this proposal so I can take a look at it? It'd
>> be much easier to critique it if I could see the proposal text.
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Wed, Aug 1, 2018 at 2:18 AM, Ranando King  wrote:
>> >> If you go back a few months, what you're proposing is *very* similar,
>> >> at
>> >> least functionally, to my previous iteration of my proposal:
>> >
>> > That functional similarity is intentional. After pouring over years
>> > worth of
>> > posts, I figured out what the vast majority of the proposal-class-fields
>> > detractors actually wanted: an elegant, easily recognized syntax for
>> > adding
>> > private members to objects.
>> >
>> >> My main problem was that trying to limit private properties to objects
>> >> created within a scope got complicated in a hurry once you considered
>> >> all
>> >> the small details, and it just didn't seem simple anymore.
>> >
>> > I noticed that about your proposal too. I'm also pretty sure that Daniel
>> > E.
>> > and Kevin G. ran into the same issues back during the
>> > proposal-private-names
>> > days which is why the private names concept is just an implementation
>> > detail
>> > in their current proposal. My proposal is made less complicated by
>> > breaking
>> > the problem down into the 3 pieces required to make it all work:
>> > 1. a record to store private data
>> > 2. an array to hold references to the schema records of accessible
>> > private
>> > data
>> > 3. a schema record for the sharable data.
>> >
>> > In this way private = encapsulated on a non-function, protected =
>> > private +
>> > shared, and static = encapsulated on a function. It should be easy to
>> > sort
>> > out how the data would be stored given such simple definitions. These
>> > simple
>> > definitions also mean that encapsulation is naturally confined to
>> > definitions. Attempts to alter that state lead to strange logical
>> > contradictions and potential leaks of encapsulated data. I have thought
>> > of
>> > the possibility that private data could be added after definition, but
>> > every
>> > attempt I make to consider such a thing has so far led to a risk of
>> > leaking.
>> >
>> > I've been working on some code that can serve as a proof-of-concept in
>> > ES6.
>> > It will implement all of my proposal that can reasonably be implemented
>> > in
>> > ES6 using Proxy. It's already in the proposal repository under the POC
>> > branch, but it's still a WIP. For now, it already supports inheriting
>> > from
>> > native objects. I'm working on subclassing right now. By the time I get
>> > done
>> > (likely this coming Monday), it should support every feature in my
>> > proposal.
>> > I'm basically using it as a means to check the viability of my proposal.
>> >
>> > On Tue, Jul 31, 2018 at 4:35 PM Isiah Meadows 
>> > wrote:
>> >>
>> >> If you go back a few months, what you're proposing is *very* similar,
>> >> at least functionally, to my previous iteration of my proposal:
>> >>
>> >>
>> >> https://github.com/isiahmeadows/private-symbol-proposal/blob/c5c9781d9e76123c92d8fbc83681fdd3a9b0b319/README.md
>> >>
>> >> My main problem was that trying to limit private properties to objects
>> >> created within a scope got complicated in a hurry once you considered
>> >> all the small details, and it just didn't seem simple anymore. It only
>> >> got more complicated when you started getting into the logistics of
>> >> integrating with modules.
>> >>
>> >> So I've considered the issue and explored it pretty thoroughly - I
>> >> *really* don't want private data to be limited to classes (which I
>> >> dislike), but I did also previously have the concern of trying to
>> >> limit who could define properties where.
>> >>
>> >> I will point out that you can prevent arbitrary private extension by
>> >> simply doing `Object.preventExtensions(object)`. Because properties
>> >> defined using private symbols are otherwise just normal properties,
>> >> they still have to go through the same access checks normal properties
>> >> have t

Re: !Re: proposal: Object Members

2018-08-01 Thread Ranando King
https://github.com/rdking/proposal-object-members/blob/master/README.md

On Wed, Aug 1, 2018 at 2:01 AM Isiah Meadows  wrote:

> Do you have a link to this proposal so I can take a look at it? It'd
> be much easier to critique it if I could see the proposal text.
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Wed, Aug 1, 2018 at 2:18 AM, Ranando King  wrote:
> >> If you go back a few months, what you're proposing is *very* similar, at
> >> least functionally, to my previous iteration of my proposal:
> >
> > That functional similarity is intentional. After pouring over years
> worth of
> > posts, I figured out what the vast majority of the proposal-class-fields
> > detractors actually wanted: an elegant, easily recognized syntax for
> adding
> > private members to objects.
> >
> >> My main problem was that trying to limit private properties to objects
> >> created within a scope got complicated in a hurry once you considered
> all
> >> the small details, and it just didn't seem simple anymore.
> >
> > I noticed that about your proposal too. I'm also pretty sure that Daniel
> E.
> > and Kevin G. ran into the same issues back during the
> proposal-private-names
> > days which is why the private names concept is just an implementation
> detail
> > in their current proposal. My proposal is made less complicated by
> breaking
> > the problem down into the 3 pieces required to make it all work:
> > 1. a record to store private data
> > 2. an array to hold references to the schema records of accessible
> private
> > data
> > 3. a schema record for the sharable data.
> >
> > In this way private = encapsulated on a non-function, protected =
> private +
> > shared, and static = encapsulated on a function. It should be easy to
> sort
> > out how the data would be stored given such simple definitions. These
> simple
> > definitions also mean that encapsulation is naturally confined to
> > definitions. Attempts to alter that state lead to strange logical
> > contradictions and potential leaks of encapsulated data. I have thought
> of
> > the possibility that private data could be added after definition, but
> every
> > attempt I make to consider such a thing has so far led to a risk of
> leaking.
> >
> > I've been working on some code that can serve as a proof-of-concept in
> ES6.
> > It will implement all of my proposal that can reasonably be implemented
> in
> > ES6 using Proxy. It's already in the proposal repository under the POC
> > branch, but it's still a WIP. For now, it already supports inheriting
> from
> > native objects. I'm working on subclassing right now. By the time I get
> done
> > (likely this coming Monday), it should support every feature in my
> proposal.
> > I'm basically using it as a means to check the viability of my proposal.
> >
> > On Tue, Jul 31, 2018 at 4:35 PM Isiah Meadows 
> > wrote:
> >>
> >> If you go back a few months, what you're proposing is *very* similar,
> >> at least functionally, to my previous iteration of my proposal:
> >>
> >>
> https://github.com/isiahmeadows/private-symbol-proposal/blob/c5c9781d9e76123c92d8fbc83681fdd3a9b0b319/README.md
> >>
> >> My main problem was that trying to limit private properties to objects
> >> created within a scope got complicated in a hurry once you considered
> >> all the small details, and it just didn't seem simple anymore. It only
> >> got more complicated when you started getting into the logistics of
> >> integrating with modules.
> >>
> >> So I've considered the issue and explored it pretty thoroughly - I
> >> *really* don't want private data to be limited to classes (which I
> >> dislike), but I did also previously have the concern of trying to
> >> limit who could define properties where.
> >>
> >> I will point out that you can prevent arbitrary private extension by
> >> simply doing `Object.preventExtensions(object)`. Because properties
> >> defined using private symbols are otherwise just normal properties,
> >> they still have to go through the same access checks normal properties
> >> have to, like [[IsExtensible]]. The only other concrete difference is
> >> that proxy hooks don't fire when you do things with private symbols.
> >>
> >> -
> >>
> >> Isiah Meadows
> >> cont...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Tue, Jul 31, 2018 at 3:09 PM, Ranando King 
> wrote:
> >> >> What use case are you referring to here?
> >> >
> >> > In the case of SymbolTree, the objects in use are external.
> >> >
> >> >> I think there’s been a misunderstanding. Everybody agrees that
> that’s a
> >> >> bad pattern. It’s not what the point of private symbols would be.
> It’s
> >> >> not a
> >> >> target use case.
> >> >
> >> > That certainly puts my mind at ease.
> >> >
> >> >> As Isiah said, “all of the examples here I've presented are for
> >> >> scenarios
> >> >> where the state is related to the factory that created the objects.”
> >> >
> >> > If the factory that creates the objects is t

Re: !Re: proposal: Object Members

2018-08-01 Thread Isiah Meadows
Do you have a link to this proposal so I can take a look at it? It'd
be much easier to critique it if I could see the proposal text.
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Wed, Aug 1, 2018 at 2:18 AM, Ranando King  wrote:
>> If you go back a few months, what you're proposing is *very* similar, at
>> least functionally, to my previous iteration of my proposal:
>
> That functional similarity is intentional. After pouring over years worth of
> posts, I figured out what the vast majority of the proposal-class-fields
> detractors actually wanted: an elegant, easily recognized syntax for adding
> private members to objects.
>
>> My main problem was that trying to limit private properties to objects
>> created within a scope got complicated in a hurry once you considered all
>> the small details, and it just didn't seem simple anymore.
>
> I noticed that about your proposal too. I'm also pretty sure that Daniel E.
> and Kevin G. ran into the same issues back during the proposal-private-names
> days which is why the private names concept is just an implementation detail
> in their current proposal. My proposal is made less complicated by breaking
> the problem down into the 3 pieces required to make it all work:
> 1. a record to store private data
> 2. an array to hold references to the schema records of accessible private
> data
> 3. a schema record for the sharable data.
>
> In this way private = encapsulated on a non-function, protected = private +
> shared, and static = encapsulated on a function. It should be easy to sort
> out how the data would be stored given such simple definitions. These simple
> definitions also mean that encapsulation is naturally confined to
> definitions. Attempts to alter that state lead to strange logical
> contradictions and potential leaks of encapsulated data. I have thought of
> the possibility that private data could be added after definition, but every
> attempt I make to consider such a thing has so far led to a risk of leaking.
>
> I've been working on some code that can serve as a proof-of-concept in ES6.
> It will implement all of my proposal that can reasonably be implemented in
> ES6 using Proxy. It's already in the proposal repository under the POC
> branch, but it's still a WIP. For now, it already supports inheriting from
> native objects. I'm working on subclassing right now. By the time I get done
> (likely this coming Monday), it should support every feature in my proposal.
> I'm basically using it as a means to check the viability of my proposal.
>
> On Tue, Jul 31, 2018 at 4:35 PM Isiah Meadows 
> wrote:
>>
>> If you go back a few months, what you're proposing is *very* similar,
>> at least functionally, to my previous iteration of my proposal:
>>
>> https://github.com/isiahmeadows/private-symbol-proposal/blob/c5c9781d9e76123c92d8fbc83681fdd3a9b0b319/README.md
>>
>> My main problem was that trying to limit private properties to objects
>> created within a scope got complicated in a hurry once you considered
>> all the small details, and it just didn't seem simple anymore. It only
>> got more complicated when you started getting into the logistics of
>> integrating with modules.
>>
>> So I've considered the issue and explored it pretty thoroughly - I
>> *really* don't want private data to be limited to classes (which I
>> dislike), but I did also previously have the concern of trying to
>> limit who could define properties where.
>>
>> I will point out that you can prevent arbitrary private extension by
>> simply doing `Object.preventExtensions(object)`. Because properties
>> defined using private symbols are otherwise just normal properties,
>> they still have to go through the same access checks normal properties
>> have to, like [[IsExtensible]]. The only other concrete difference is
>> that proxy hooks don't fire when you do things with private symbols.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Tue, Jul 31, 2018 at 3:09 PM, Ranando King  wrote:
>> >> What use case are you referring to here?
>> >
>> > In the case of SymbolTree, the objects in use are external.
>> >
>> >> I think there’s been a misunderstanding. Everybody agrees that that’s a
>> >> bad pattern. It’s not what the point of private symbols would be. It’s
>> >> not a
>> >> target use case.
>> >
>> > That certainly puts my mind at ease.
>> >
>> >> As Isiah said, “all of the examples here I've presented are for
>> >> scenarios
>> >> where the state is related to the factory that created the objects.”
>> >
>> > If the factory that creates the objects is the also the only thing
>> > trying to
>> > store private information on those objects, then I understand you're
>> > only
>> > looking for per-instance module-private data, possibly with the ability
>> > to
>> > use common private names. If that's the case, then it really is just 2
>> > simple extensions of my proposal:
>> > * allow a Symbol when used as a private o

Re: !Re: proposal: Object Members

2018-07-31 Thread Ranando King
> If you go back a few months, what you're proposing is *very* similar, at
least functionally, to my previous iteration of my proposal:

That functional similarity is intentional. After pouring over years worth
of posts, I figured out what the vast majority of the proposal-class-fields
detractors actually wanted: an elegant, easily recognized syntax for adding
private members to objects.

> My main problem was that trying to limit private properties to objects created
within a scope got complicated in a hurry once you considered all the small
details, and it just didn't seem simple anymore.

I noticed that about your proposal too. I'm also pretty sure that Daniel E.
and Kevin G. ran into the same issues back during the
proposal-private-names days which is why the private names concept is just
an implementation detail in their current proposal. My proposal is made
less complicated by breaking the problem down into the 3 pieces required to
make it all work:
1. a record to store private data
2. an array to hold references to the schema records of accessible private
data
3. a schema record for the sharable data.

In this way private = encapsulated on a non-function, protected = private +
shared, and static = encapsulated on a function. It should be easy to sort
out how the data would be stored given such simple definitions. These
simple definitions also mean that encapsulation is naturally confined to
definitions. Attempts to alter that state lead to strange logical
contradictions and potential leaks of encapsulated data. I have thought of
the possibility that private data could be added after definition, but
every attempt I make to consider such a thing has so far led to a risk of
leaking.

I've been working on some code that can serve as a proof-of-concept in ES6.
It will implement all of my proposal that can reasonably be implemented in
ES6 using Proxy. It's already in the proposal repository under the POC
branch, but it's still a WIP. For now, it already supports inheriting from
native objects. I'm working on subclassing right now. By the time I get
done (likely this coming Monday), it should support every feature in my
proposal. I'm basically using it as a means to check the viability of my
proposal.

On Tue, Jul 31, 2018 at 4:35 PM Isiah Meadows 
wrote:

> If you go back a few months, what you're proposing is *very* similar,
> at least functionally, to my previous iteration of my proposal:
>
> https://github.com/isiahmeadows/private-symbol-proposal/blob/c5c9781d9e76123c92d8fbc83681fdd3a9b0b319/README.md
>
> My main problem was that trying to limit private properties to objects
> created within a scope got complicated in a hurry once you considered
> all the small details, and it just didn't seem simple anymore. It only
> got more complicated when you started getting into the logistics of
> integrating with modules.
>
> So I've considered the issue and explored it pretty thoroughly - I
> *really* don't want private data to be limited to classes (which I
> dislike), but I did also previously have the concern of trying to
> limit who could define properties where.
>
> I will point out that you can prevent arbitrary private extension by
> simply doing `Object.preventExtensions(object)`. Because properties
> defined using private symbols are otherwise just normal properties,
> they still have to go through the same access checks normal properties
> have to, like [[IsExtensible]]. The only other concrete difference is
> that proxy hooks don't fire when you do things with private symbols.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Tue, Jul 31, 2018 at 3:09 PM, Ranando King  wrote:
> >> What use case are you referring to here?
> >
> > In the case of SymbolTree, the objects in use are external.
> >
> >> I think there’s been a misunderstanding. Everybody agrees that that’s a
> >> bad pattern. It’s not what the point of private symbols would be. It’s
> not a
> >> target use case.
> >
> > That certainly puts my mind at ease.
> >
> >> As Isiah said, “all of the examples here I've presented are for
> scenarios
> >> where the state is related to the factory that created the objects.”
> >
> > If the factory that creates the objects is the also the only thing
> trying to
> > store private information on those objects, then I understand you're only
> > looking for per-instance module-private data, possibly with the ability
> to
> > use common private names. If that's the case, then it really is just 2
> > simple extensions of my proposal:
> > * allow a Symbol when used as a private or protected property name to
> > persist as the private Symbol name for the private instance field on each
> > object for which it is used.
> > * create an additional privilege level (internal) that places the new
> > field's name in the [[DeclarationInfo]] of the function containing the
> > declaration.
> >
> > The effect of using these 2 features together is that anything within the
> > same functi

Re: !Re: proposal: Object Members

2018-07-31 Thread Ranando King
Thanks for that information. I wasn't yet sure how to handle it. A parallel
question is this: Is there any particular reason that the private container
itself shouldn't be mutable? Or more directly, is there a good reason for
private fields to only be create-able at declaration time? So far, all the
logic I've created hinges on the reference to [[DeclarationInfo]] (which
keeps all the known private names). Since that container is created at
declaration time, it's not unfeasible for private properties to be appended
after the declaration. I'm not particularly fond of the idea, but I'm also
trying not to let my own biases commit me to a decision.

On Tue, Jul 31, 2018 at 4:41 PM Jordan Harband  wrote:

> Note that builtins with internal slots, like Map, Set, and Promise, are
> still mutable after being frozen - so if one is trying to model internal
> slots with some kind of property stored on the object, then freezing *must*
> have no effect on the ability to alter their contents.
>
> On Tue, Jul 31, 2018 at 2:34 PM, Isiah Meadows 
> wrote:
>
>> If you go back a few months, what you're proposing is *very* similar,
>> at least functionally, to my previous iteration of my proposal:
>>
>> https://github.com/isiahmeadows/private-symbol-proposal/blob/c5c9781d9e76123c92d8fbc83681fdd3a9b0b319/README.md
>>
>> My main problem was that trying to limit private properties to objects
>> created within a scope got complicated in a hurry once you considered
>> all the small details, and it just didn't seem simple anymore. It only
>> got more complicated when you started getting into the logistics of
>> integrating with modules.
>>
>> So I've considered the issue and explored it pretty thoroughly - I
>> *really* don't want private data to be limited to classes (which I
>> dislike), but I did also previously have the concern of trying to
>> limit who could define properties where.
>>
>> I will point out that you can prevent arbitrary private extension by
>> simply doing `Object.preventExtensions(object)`. Because properties
>> defined using private symbols are otherwise just normal properties,
>> they still have to go through the same access checks normal properties
>> have to, like [[IsExtensible]]. The only other concrete difference is
>> that proxy hooks don't fire when you do things with private symbols.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Tue, Jul 31, 2018 at 3:09 PM, Ranando King  wrote:
>> >> What use case are you referring to here?
>> >
>> > In the case of SymbolTree, the objects in use are external.
>> >
>> >> I think there’s been a misunderstanding. Everybody agrees that that’s a
>> >> bad pattern. It’s not what the point of private symbols would be. It’s
>> not a
>> >> target use case.
>> >
>> > That certainly puts my mind at ease.
>> >
>> >> As Isiah said, “all of the examples here I've presented are for
>> scenarios
>> >> where the state is related to the factory that created the objects.”
>> >
>> > If the factory that creates the objects is the also the only thing
>> trying to
>> > store private information on those objects, then I understand you're
>> only
>> > looking for per-instance module-private data, possibly with the ability
>> to
>> > use common private names. If that's the case, then it really is just 2
>> > simple extensions of my proposal:
>> > * allow a Symbol when used as a private or protected property name to
>> > persist as the private Symbol name for the private instance field on
>> each
>> > object for which it is used.
>> > * create an additional privilege level (internal) that places the new
>> > field's name in the [[DeclarationInfo]] of the function containing the
>> > declaration.
>> >
>> > The effect of using these 2 features together is that anything within
>> the
>> > same function as the declared Symbol will gain access to the internal
>> field
>> > of all objects using that Symbol as a field name.
>> >
>> > On Tue, Jul 31, 2018 at 1:36 PM Darien Valentine > >
>> > wrote:
>> >>
>> >> > I'd say you've identified the common pattern, but that pattern
>> itself is
>> >> > a bad use case, and the use of private symbols as you have defined
>> them
>> >> > doesn't do anything to correct the technical issue.
>> >>
>> >> I think there’s been a misunderstanding. Everybody agrees that that’s a
>> >> bad pattern. It’s not what the point of private symbols would be. It’s
>> not a
>> >> target use case.
>> >>
>> >> > Since you cannot stick new properties onto a non-extensible object,
>> even
>> >> > private symbols won't solve the problem with your use case.
>> >>
>> >> That appending private symbols to external objects which are frozen
>> >> wouldn’t work doesn’t matter precisely because it’s not a target use
>> case.
>> >> That it doesn’t work reliably might even be considered a positive,
>> since it
>> >> discourages something we all seem to agree is not good practice.
>> >>
>> >> It’s also not related to private symbols; this is alrea

Re: !Re: proposal: Object Members

2018-07-31 Thread Isiah Meadows
Yeah, I left it without saying that you could just model them as
having their state as a single private symbol field with all the
relevant data for it. I assumed it would be obvious enough for those
who really pay attention to the spec, so I just left it implied.
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Tue, Jul 31, 2018 at 5:40 PM, Jordan Harband  wrote:
> Note that builtins with internal slots, like Map, Set, and Promise, are
> still mutable after being frozen - so if one is trying to model internal
> slots with some kind of property stored on the object, then freezing *must*
> have no effect on the ability to alter their contents.
>
> On Tue, Jul 31, 2018 at 2:34 PM, Isiah Meadows 
> wrote:
>>
>> If you go back a few months, what you're proposing is *very* similar,
>> at least functionally, to my previous iteration of my proposal:
>>
>> https://github.com/isiahmeadows/private-symbol-proposal/blob/c5c9781d9e76123c92d8fbc83681fdd3a9b0b319/README.md
>>
>> My main problem was that trying to limit private properties to objects
>> created within a scope got complicated in a hurry once you considered
>> all the small details, and it just didn't seem simple anymore. It only
>> got more complicated when you started getting into the logistics of
>> integrating with modules.
>>
>> So I've considered the issue and explored it pretty thoroughly - I
>> *really* don't want private data to be limited to classes (which I
>> dislike), but I did also previously have the concern of trying to
>> limit who could define properties where.
>>
>> I will point out that you can prevent arbitrary private extension by
>> simply doing `Object.preventExtensions(object)`. Because properties
>> defined using private symbols are otherwise just normal properties,
>> they still have to go through the same access checks normal properties
>> have to, like [[IsExtensible]]. The only other concrete difference is
>> that proxy hooks don't fire when you do things with private symbols.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Tue, Jul 31, 2018 at 3:09 PM, Ranando King  wrote:
>> >> What use case are you referring to here?
>> >
>> > In the case of SymbolTree, the objects in use are external.
>> >
>> >> I think there’s been a misunderstanding. Everybody agrees that that’s a
>> >> bad pattern. It’s not what the point of private symbols would be. It’s
>> >> not a
>> >> target use case.
>> >
>> > That certainly puts my mind at ease.
>> >
>> >> As Isiah said, “all of the examples here I've presented are for
>> >> scenarios
>> >> where the state is related to the factory that created the objects.”
>> >
>> > If the factory that creates the objects is the also the only thing
>> > trying to
>> > store private information on those objects, then I understand you're
>> > only
>> > looking for per-instance module-private data, possibly with the ability
>> > to
>> > use common private names. If that's the case, then it really is just 2
>> > simple extensions of my proposal:
>> > * allow a Symbol when used as a private or protected property name to
>> > persist as the private Symbol name for the private instance field on
>> > each
>> > object for which it is used.
>> > * create an additional privilege level (internal) that places the new
>> > field's name in the [[DeclarationInfo]] of the function containing the
>> > declaration.
>> >
>> > The effect of using these 2 features together is that anything within
>> > the
>> > same function as the declared Symbol will gain access to the internal
>> > field
>> > of all objects using that Symbol as a field name.
>> >
>> > On Tue, Jul 31, 2018 at 1:36 PM Darien Valentine 
>> > wrote:
>> >>
>> >> > I'd say you've identified the common pattern, but that pattern itself
>> >> > is
>> >> > a bad use case, and the use of private symbols as you have defined
>> >> > them
>> >> > doesn't do anything to correct the technical issue.
>> >>
>> >> I think there’s been a misunderstanding. Everybody agrees that that’s a
>> >> bad pattern. It’s not what the point of private symbols would be. It’s
>> >> not a
>> >> target use case.
>> >>
>> >> > Since you cannot stick new properties onto a non-extensible object,
>> >> > even
>> >> > private symbols won't solve the problem with your use case.
>> >>
>> >> That appending private symbols to external objects which are frozen
>> >> wouldn’t work doesn’t matter precisely because it’s not a target use
>> >> case.
>> >> That it doesn’t work reliably might even be considered a positive,
>> >> since it
>> >> discourages something we all seem to agree is not good practice.
>> >>
>> >> It’s also not related to private symbols; this is already how
>> >> properties
>> >> work, regardless of what kind of key they have.
>> >>
>> >> > The difference here is that in your use cases, library A is
>> >> > "sneakily"
>> >> > storing information on object B.
>> >>
>> >> What use case are you referring to here? I can’t find any

Re: !Re: proposal: Object Members

2018-07-31 Thread Isiah Meadows
> The argument I raised with Isiah was just 1 example of a bad pattern that
> being too generic can open up.

BTW, the risk for bad patterns doesn't necessarily justify exclusion
of a feature. As I've brought up here before, iterators can be
seriously abused similarly [1], thanks to the availability of `throw`
+ `return`, and you can always make a deferred out of a promise by
simply pulling the `resolve`/`reject` out of the promise callback's
scope. As long as it looks strange and weird enough and we have more
semantically appropriate alternatives, I don't think we have an issue
with potential abuse, and I feel private symbols as I have them meet
this threshold.

[1]: https://github.com/tc39/proposal-async-iteration/issues/68

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Tue, Jul 31, 2018 at 5:10 PM, Ranando King  wrote:
> I get where you're coming from. The main reasons I've written my proposal
> this way are:
>
> * Prior art:
>   - Many ES developers come from other, class-based, object-oriented
> languages where keywords are the primary way of controlling data
> accessibility. This means using the well known keywords will lower the
> learning curve and increase adoption.
> * Future expansion:
>   - Careful and narrow definition of the keywords and their corresponding
> actions allows undesirable patterns to be avoided while leaving room for
> future extensibility.
>
> The argument I raised with Isiah was just 1 example of a bad pattern that
> being too generic can open up. These are also part of the reasons why I am
> against proposal-class-fields. It seems so simple on the surface, but
> effectively makes an already limited keyword even more limited than is
> should be. Plus it adds difficulty to creating new features around those
> concepts in a way that will be easily understood by developers migrating
> from other languages.
>
>
> On Tue, Jul 31, 2018 at 3:43 PM Darien Valentine 
> wrote:
>>
>> You’re right, sorry — the SymbolTree example does operate on objects not
>> created in the module itself, so my statement wasn’t accurate.
>>
>> More carefully I ought to have said that the use cases concern object
>> creation. Decorators and mixin functionality can fall in this bucket, where
>> the object is likely not literally “birthed” by the library that is doing
>> the decorating, yet the functionality is intended to be attached during that
>> process by a consumer of the library.
>>
>> In my own experience to date, all cases where I have run into the
>> class-declaration scope limitation did concern locally created objects
>> (class instances specifically), so yes, the adjustments you are talking
>> about wrt the object members proposal probably would be able to cover them,
>> though I would still tend to favor a more generic and simple solution.
>>
>> On Tue, Jul 31, 2018 at 3:09 PM Ranando King  wrote:
>>>
>>> > What use case are you referring to here?
>>>
>>> In the case of SymbolTree, the objects in use are external.
>>>
>>> > I think there’s been a misunderstanding. Everybody agrees that that’s a
>>> > bad pattern. It’s not what the point of private symbols would be. It’s 
>>> > not a
>>> > target use case.
>>>
>>> That certainly puts my mind at ease.
>>>
>>> > As Isiah said, “all of the examples here I've presented are for
>>> > scenarios where the state is related to the factory that created the
>>> > objects.”
>>>
>>> If the factory that creates the objects is the also the only thing trying
>>> to store private information on those objects, then I understand you're only
>>> looking for per-instance module-private data, possibly with the ability to
>>> use common private names. If that's the case, then it really is just 2
>>> simple extensions of my proposal:
>>> * allow a Symbol when used as a private or protected property name to
>>> persist as the private Symbol name for the private instance field on each
>>> object for which it is used.
>>> * create an additional privilege level (internal) that places the new
>>> field's name in the [[DeclarationInfo]] of the function containing the
>>> declaration.
>>>
>>> The effect of using these 2 features together is that anything within the
>>> same function as the declared Symbol will gain access to the internal field
>>> of all objects using that Symbol as a field name.
>>>
>>> On Tue, Jul 31, 2018 at 1:36 PM Darien Valentine 
>>> wrote:

 > I'd say you've identified the common pattern, but that pattern itself
 > is a bad use case, and the use of private symbols as you have defined 
 > them
 > doesn't do anything to correct the technical issue.

 I think there’s been a misunderstanding. Everybody agrees that that’s a
 bad pattern. It’s not what the point of private symbols would be. It’s not 
 a
 target use case.

 > Since you cannot stick new properties onto a non-extensible object,
 > even private symbols won't solve the problem with your use case.

 That appendi

Re: !Re: proposal: Object Members

2018-07-31 Thread Jordan Harband
Note that builtins with internal slots, like Map, Set, and Promise, are
still mutable after being frozen - so if one is trying to model internal
slots with some kind of property stored on the object, then freezing *must*
have no effect on the ability to alter their contents.

On Tue, Jul 31, 2018 at 2:34 PM, Isiah Meadows 
wrote:

> If you go back a few months, what you're proposing is *very* similar,
> at least functionally, to my previous iteration of my proposal:
> https://github.com/isiahmeadows/private-symbol-proposal/blob/
> c5c9781d9e76123c92d8fbc83681fdd3a9b0b319/README.md
>
> My main problem was that trying to limit private properties to objects
> created within a scope got complicated in a hurry once you considered
> all the small details, and it just didn't seem simple anymore. It only
> got more complicated when you started getting into the logistics of
> integrating with modules.
>
> So I've considered the issue and explored it pretty thoroughly - I
> *really* don't want private data to be limited to classes (which I
> dislike), but I did also previously have the concern of trying to
> limit who could define properties where.
>
> I will point out that you can prevent arbitrary private extension by
> simply doing `Object.preventExtensions(object)`. Because properties
> defined using private symbols are otherwise just normal properties,
> they still have to go through the same access checks normal properties
> have to, like [[IsExtensible]]. The only other concrete difference is
> that proxy hooks don't fire when you do things with private symbols.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Tue, Jul 31, 2018 at 3:09 PM, Ranando King  wrote:
> >> What use case are you referring to here?
> >
> > In the case of SymbolTree, the objects in use are external.
> >
> >> I think there’s been a misunderstanding. Everybody agrees that that’s a
> >> bad pattern. It’s not what the point of private symbols would be. It’s
> not a
> >> target use case.
> >
> > That certainly puts my mind at ease.
> >
> >> As Isiah said, “all of the examples here I've presented are for
> scenarios
> >> where the state is related to the factory that created the objects.”
> >
> > If the factory that creates the objects is the also the only thing
> trying to
> > store private information on those objects, then I understand you're only
> > looking for per-instance module-private data, possibly with the ability
> to
> > use common private names. If that's the case, then it really is just 2
> > simple extensions of my proposal:
> > * allow a Symbol when used as a private or protected property name to
> > persist as the private Symbol name for the private instance field on each
> > object for which it is used.
> > * create an additional privilege level (internal) that places the new
> > field's name in the [[DeclarationInfo]] of the function containing the
> > declaration.
> >
> > The effect of using these 2 features together is that anything within the
> > same function as the declared Symbol will gain access to the internal
> field
> > of all objects using that Symbol as a field name.
> >
> > On Tue, Jul 31, 2018 at 1:36 PM Darien Valentine 
> > wrote:
> >>
> >> > I'd say you've identified the common pattern, but that pattern itself
> is
> >> > a bad use case, and the use of private symbols as you have defined
> them
> >> > doesn't do anything to correct the technical issue.
> >>
> >> I think there’s been a misunderstanding. Everybody agrees that that’s a
> >> bad pattern. It’s not what the point of private symbols would be. It’s
> not a
> >> target use case.
> >>
> >> > Since you cannot stick new properties onto a non-extensible object,
> even
> >> > private symbols won't solve the problem with your use case.
> >>
> >> That appending private symbols to external objects which are frozen
> >> wouldn’t work doesn’t matter precisely because it’s not a target use
> case.
> >> That it doesn’t work reliably might even be considered a positive,
> since it
> >> discourages something we all seem to agree is not good practice.
> >>
> >> It’s also not related to private symbols; this is already how properties
> >> work, regardless of what kind of key they have.
> >>
> >> > The difference here is that in your use cases, library A is "sneakily"
> >> > storing information on object B.
> >>
> >> What use case are you referring to here? I can’t find any example in the
> >> previous posts that matches these descriptions. As Isiah said, “all of
> the
> >> examples here I've presented are for scenarios where the state is
> related to
> >> the factory that created the objects.” The same is true of my examples.
> >> Everybody’s on the same page regarding not wanting to add properties to
> >> objects their own libraries do not create.
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___

Re: !Re: proposal: Object Members

2018-07-31 Thread Isiah Meadows
If you go back a few months, what you're proposing is *very* similar,
at least functionally, to my previous iteration of my proposal:
https://github.com/isiahmeadows/private-symbol-proposal/blob/c5c9781d9e76123c92d8fbc83681fdd3a9b0b319/README.md

My main problem was that trying to limit private properties to objects
created within a scope got complicated in a hurry once you considered
all the small details, and it just didn't seem simple anymore. It only
got more complicated when you started getting into the logistics of
integrating with modules.

So I've considered the issue and explored it pretty thoroughly - I
*really* don't want private data to be limited to classes (which I
dislike), but I did also previously have the concern of trying to
limit who could define properties where.

I will point out that you can prevent arbitrary private extension by
simply doing `Object.preventExtensions(object)`. Because properties
defined using private symbols are otherwise just normal properties,
they still have to go through the same access checks normal properties
have to, like [[IsExtensible]]. The only other concrete difference is
that proxy hooks don't fire when you do things with private symbols.

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Tue, Jul 31, 2018 at 3:09 PM, Ranando King  wrote:
>> What use case are you referring to here?
>
> In the case of SymbolTree, the objects in use are external.
>
>> I think there’s been a misunderstanding. Everybody agrees that that’s a
>> bad pattern. It’s not what the point of private symbols would be. It’s not a
>> target use case.
>
> That certainly puts my mind at ease.
>
>> As Isiah said, “all of the examples here I've presented are for scenarios
>> where the state is related to the factory that created the objects.”
>
> If the factory that creates the objects is the also the only thing trying to
> store private information on those objects, then I understand you're only
> looking for per-instance module-private data, possibly with the ability to
> use common private names. If that's the case, then it really is just 2
> simple extensions of my proposal:
> * allow a Symbol when used as a private or protected property name to
> persist as the private Symbol name for the private instance field on each
> object for which it is used.
> * create an additional privilege level (internal) that places the new
> field's name in the [[DeclarationInfo]] of the function containing the
> declaration.
>
> The effect of using these 2 features together is that anything within the
> same function as the declared Symbol will gain access to the internal field
> of all objects using that Symbol as a field name.
>
> On Tue, Jul 31, 2018 at 1:36 PM Darien Valentine 
> wrote:
>>
>> > I'd say you've identified the common pattern, but that pattern itself is
>> > a bad use case, and the use of private symbols as you have defined them
>> > doesn't do anything to correct the technical issue.
>>
>> I think there’s been a misunderstanding. Everybody agrees that that’s a
>> bad pattern. It’s not what the point of private symbols would be. It’s not a
>> target use case.
>>
>> > Since you cannot stick new properties onto a non-extensible object, even
>> > private symbols won't solve the problem with your use case.
>>
>> That appending private symbols to external objects which are frozen
>> wouldn’t work doesn’t matter precisely because it’s not a target use case.
>> That it doesn’t work reliably might even be considered a positive, since it
>> discourages something we all seem to agree is not good practice.
>>
>> It’s also not related to private symbols; this is already how properties
>> work, regardless of what kind of key they have.
>>
>> > The difference here is that in your use cases, library A is "sneakily"
>> > storing information on object B.
>>
>> What use case are you referring to here? I can’t find any example in the
>> previous posts that matches these descriptions. As Isiah said, “all of the
>> examples here I've presented are for scenarios where the state is related to
>> the factory that created the objects.” The same is true of my examples.
>> Everybody’s on the same page regarding not wanting to add properties to
>> objects their own libraries do not create.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-07-31 Thread Isiah Meadows
If you look at my proposal, it would be a "no" for the same reasons
you can't add normal properties to them.
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Tue, Jul 31, 2018 at 1:17 PM, Michael Theriot
 wrote:
> Should a sealed/frozen object be privately extensible? I don't actually
> know, but interesting point.
>
>
> On Tuesday, July 31, 2018, Ranando King  wrote:
>>
>> > Consider what people often use public symbols for now.
>>
>> I know that I use them as fixed-value unique keys (module globals) for
>> properties on objects that I export and don't want others to be aware of or
>> able to touch.
>>
>> > For example, consider this library [1]. In this case, they use a public
>> > symbol for their stuff in this file [2].
>>
>> And as I said before, if someone passes a non-extensible object to this
>> library, it breaks. Since any library can request any object be sealed or
>> frozen, the implementation of this library is too fragile.
>>
>> > Because here, it's not a cache, but it's literally extra associated data
>> > in the object. And also, in that case, you *want* the engine to see it as a
>> > property, since it can employ relevant IC caching for it.
>>
>> Here's a parallel for you. Right now, Google has a database with
>> information about me on it. I don't have access to that information (module
>> privacy) and that information isn't stored anywhere on me or my devices
>> (module locality). This is a proper conceptual model. The information Google
>> is keeping about me is information they generated. Why should I have to pay
>> to store their information? Thankfully I don't. However, this is precisely
>> what you're claiming to be a good use case. You want module privacy without
>> module locality. If I were to play at a Kevin Gibbons-like response, I'd say
>> you've identified the common pattern, but that pattern itself is a bad use
>> case, and the use of private symbols as you have defined them doesn't do
>> anything to correct the technical issue. Since you cannot stick new
>> properties onto a non-extensible object, even private symbols won't solve
>> the problem with your use case.
>>
>> > No, I'm not. I'm drawing a distinction between a pure many-to-one
>> > association (weak maps) and a "has a" relationship (private symbol
>> > properties).
>>
>> First, for any given property bag, the keys will need to be unique, but
>> that doesn't force uniqueness onto the values. As such, even properties on
>> an object provided by your "private Symbol" would still be many-1. When a
>> 3rd party library wants to keep information associated with an arbitrary
>> object, there are only 3 choices:
>> * try to store that information on the object
>>   * this is what you're advocating, but it's not a good pattern. It's too
>> fragile, being subject to break if the incoming object is not extensible.
>> * store the information as being associated to the object (WeakMap)
>>   * this is the pattern that works in all cases (but the syntax is
>> cumbersome and the implementation somewhat slow)
>> * return a wrapper containing the original object and the new information
>> (Proxy or custom wrapper)
>>   * this is another possibility, but requires that any users accept and
>> use the new Proxy or wrapper object in lieu of the original.
>>
>> > Another scenario is for JSDOM's `Window` implementation, where they have
>> > a few underscore-private variables like this [3]. That particular variable
>> > is used in several disparate parts throughout the code base [4], but is
>> > still conceptually a property. This is a case where a private symbol
>> > property is appropriate.
>>
>> It's not just "conceptually" a property. It's logically a property. Why?
>> Because all the objects that it exists on were constructed somewhere within
>> the JSDOM library. That's me putting _my_ keys in _my_ pocket. There's
>> absolutely nothing wrong with that.
>>
>> > Conversely in this JSDOM file [5], it's just associating data with an
>> > arbitrary object it happens to have, and so using the weak map makes 
>> > perfect
>> > sense.
>>
>> Conceptually speaking, this is the same scenario as SymbolTree. In both
>> cases, the library is generating information associated with an object it
>> doesn't own and didn't create.
>>
>> > BTW, you could make a similar argument against superclass private fields
>> > - it's like hiding valuable info in your wallet before you receive it for
>> > the first time, but even after dismantling it, you can't find any evidence
>> > of that valuable info.
>>
>> That dog don't hunt. The difference here is that in your use cases,
>> library A is "sneakily" storing information on object B. In the case of
>> superclass private fields, subclass B has "volunteered" to take on the
>> information and functionality of class A. You've essentially compared apples
>> and asteroids just because they both begin with "a".
>>
>> On Tue, Jul 31, 2018 at 2:15 AM Isiah Meadows 
>> wrote:
>>>
>>> > Isn't this 

Re: !Re: proposal: Object Members

2018-07-31 Thread Ranando King
I get where you're coming from. The main reasons I've written my proposal
this way are:

* Prior art:
  - Many ES developers come from other, class-based, object-oriented
languages where keywords are the primary way of controlling data
accessibility. This means using the well known keywords will lower the
learning curve and increase adoption.
* Future expansion:
  - Careful and narrow definition of the keywords and their corresponding
actions allows undesirable patterns to be avoided while leaving room for
future extensibility.

The argument I raised with Isiah was just 1 example of a bad pattern that
being too generic can open up. These are also part of the reasons why I am
against proposal-class-fields. It seems so simple on the surface, but
effectively makes an already limited keyword even more limited than is
should be. Plus it adds difficulty to creating new features around those
concepts in a way that will be easily understood by developers migrating
from other languages.


On Tue, Jul 31, 2018 at 3:43 PM Darien Valentine 
wrote:

> You’re right, sorry — the SymbolTree example does operate on objects not
> created in the module itself, so my statement wasn’t accurate.
>
> More carefully I ought to have said that the use cases concern object
> creation. Decorators and mixin functionality can fall in this bucket, where
> the object is likely not literally “birthed” by the library that is doing
> the decorating, yet the functionality is intended to be attached during
> that process by a consumer of the library.
>
> In my own experience to date, all cases where I have run into the
> class-declaration scope limitation did concern locally created objects
> (class instances specifically), so yes, the adjustments you are talking
> about wrt the object members proposal probably would be able to cover them,
> though I would still tend to favor a more generic and simple solution.
>
> On Tue, Jul 31, 2018 at 3:09 PM Ranando King  wrote:
>
>> > What use case are you referring to here?
>>
>> In the case of SymbolTree, the objects in use are external.
>>
>> > I think there’s been a misunderstanding. Everybody agrees that that’s
>> a bad pattern. It’s not what the point of private symbols would be. It’s
>> not a target use case.
>>
>> That certainly puts my mind at ease.
>>
>> > As Isiah said, “all of the examples here I've presented are for
>> scenarios where the state is related to the factory that created the
>> objects.”
>>
>> If the factory that creates the objects is the also the only thing trying
>> to store private information on those objects, then I understand you're
>> only looking for per-instance module-private data, possibly with the
>> ability to use common private names. If that's the case, then it really is
>> just 2 simple extensions of my proposal:
>> * allow a Symbol when used as a private or protected property name to
>> persist as the private Symbol name for the private instance field on each
>> object for which it is used.
>> * create an additional privilege level (internal) that places the new
>> field's name in the [[DeclarationInfo]] of the function containing the
>> declaration.
>>
>> The effect of using these 2 features together is that anything within the
>> same function as the declared Symbol will gain access to the internal field
>> of all objects using that Symbol as a field name.
>>
>> On Tue, Jul 31, 2018 at 1:36 PM Darien Valentine 
>> wrote:
>>
>>> > I'd say you've identified the common pattern, but that pattern itself
>>> is a bad use case, and the use of private symbols as you have defined them
>>> doesn't do anything to correct the technical issue.
>>>
>>> I think there’s been a misunderstanding. Everybody agrees that that’s a
>>> bad pattern. It’s not what the point of private symbols would be. It’s not
>>> a target use case.
>>>
>>> > Since you cannot stick new properties onto a non-extensible object,
>>> even private symbols won't solve the problem with your use case.
>>>
>>> That appending private symbols to external objects which are frozen
>>> wouldn’t work doesn’t matter precisely because it’s not a target use case.
>>> That it doesn’t work reliably might even be considered a positive, since it
>>> discourages something we all seem to agree is not good practice.
>>>
>>> It’s also not related to private symbols; this is already how properties
>>> work, regardless of what kind of key they have.
>>>
>>> > The difference here is that in your use cases, library A is "sneakily"
>>> storing information on object B.
>>>
>>> What use case are you referring to here? I can’t find any example in the
>>> previous posts that matches these descriptions. As Isiah said, “all of the
>>> examples here I've presented are for scenarios where the state is related
>>> to the factory that created the objects.” The same is true of my examples.
>>> Everybody’s on the same page regarding not wanting to add properties to
>>> objects their own libraries do not create.
>>>
>>
___

Re: !Re: proposal: Object Members

2018-07-31 Thread Darien Valentine
You’re right, sorry — the SymbolTree example does operate on objects not
created in the module itself, so my statement wasn’t accurate.

More carefully I ought to have said that the use cases concern object
creation. Decorators and mixin functionality can fall in this bucket, where
the object is likely not literally “birthed” by the library that is doing
the decorating, yet the functionality is intended to be attached during
that process by a consumer of the library.

In my own experience to date, all cases where I have run into the
class-declaration scope limitation did concern locally created objects
(class instances specifically), so yes, the adjustments you are talking
about wrt the object members proposal probably would be able to cover them,
though I would still tend to favor a more generic and simple solution.

On Tue, Jul 31, 2018 at 3:09 PM Ranando King  wrote:

> > What use case are you referring to here?
>
> In the case of SymbolTree, the objects in use are external.
>
> > I think there’s been a misunderstanding. Everybody agrees that that’s a
> bad pattern. It’s not what the point of private symbols would be. It’s not
> a target use case.
>
> That certainly puts my mind at ease.
>
> > As Isiah said, “all of the examples here I've presented are for
> scenarios where the state is related to the factory that created the
> objects.”
>
> If the factory that creates the objects is the also the only thing trying
> to store private information on those objects, then I understand you're
> only looking for per-instance module-private data, possibly with the
> ability to use common private names. If that's the case, then it really is
> just 2 simple extensions of my proposal:
> * allow a Symbol when used as a private or protected property name to
> persist as the private Symbol name for the private instance field on each
> object for which it is used.
> * create an additional privilege level (internal) that places the new
> field's name in the [[DeclarationInfo]] of the function containing the
> declaration.
>
> The effect of using these 2 features together is that anything within the
> same function as the declared Symbol will gain access to the internal field
> of all objects using that Symbol as a field name.
>
> On Tue, Jul 31, 2018 at 1:36 PM Darien Valentine 
> wrote:
>
>> > I'd say you've identified the common pattern, but that pattern itself
>> is a bad use case, and the use of private symbols as you have defined them
>> doesn't do anything to correct the technical issue.
>>
>> I think there’s been a misunderstanding. Everybody agrees that that’s a
>> bad pattern. It’s not what the point of private symbols would be. It’s not
>> a target use case.
>>
>> > Since you cannot stick new properties onto a non-extensible object,
>> even private symbols won't solve the problem with your use case.
>>
>> That appending private symbols to external objects which are frozen
>> wouldn’t work doesn’t matter precisely because it’s not a target use case.
>> That it doesn’t work reliably might even be considered a positive, since it
>> discourages something we all seem to agree is not good practice.
>>
>> It’s also not related to private symbols; this is already how properties
>> work, regardless of what kind of key they have.
>>
>> > The difference here is that in your use cases, library A is "sneakily"
>> storing information on object B.
>>
>> What use case are you referring to here? I can’t find any example in the
>> previous posts that matches these descriptions. As Isiah said, “all of the
>> examples here I've presented are for scenarios where the state is related
>> to the factory that created the objects.” The same is true of my examples.
>> Everybody’s on the same page regarding not wanting to add properties to
>> objects their own libraries do not create.
>>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-07-31 Thread Ranando King
> What use case are you referring to here?

In the case of SymbolTree, the objects in use are external.

> I think there’s been a misunderstanding. Everybody agrees that that’s a
bad pattern. It’s not what the point of private symbols would be. It’s not
a target use case.

That certainly puts my mind at ease.

> As Isiah said, “all of the examples here I've presented are for scenarios
where the state is related to the factory that created the objects.”

If the factory that creates the objects is the also the only thing trying
to store private information on those objects, then I understand you're
only looking for per-instance module-private data, possibly with the
ability to use common private names. If that's the case, then it really is
just 2 simple extensions of my proposal:
* allow a Symbol when used as a private or protected property name to
persist as the private Symbol name for the private instance field on each
object for which it is used.
* create an additional privilege level (internal) that places the new
field's name in the [[DeclarationInfo]] of the function containing the
declaration.

The effect of using these 2 features together is that anything within the
same function as the declared Symbol will gain access to the internal field
of all objects using that Symbol as a field name.

On Tue, Jul 31, 2018 at 1:36 PM Darien Valentine 
wrote:

> > I'd say you've identified the common pattern, but that pattern itself is
> a bad use case, and the use of private symbols as you have defined them
> doesn't do anything to correct the technical issue.
>
> I think there’s been a misunderstanding. Everybody agrees that that’s a
> bad pattern. It’s not what the point of private symbols would be. It’s not
> a target use case.
>
> > Since you cannot stick new properties onto a non-extensible object, even
> private symbols won't solve the problem with your use case.
>
> That appending private symbols to external objects which are frozen
> wouldn’t work doesn’t matter precisely because it’s not a target use case.
> That it doesn’t work reliably might even be considered a positive, since it
> discourages something we all seem to agree is not good practice.
>
> It’s also not related to private symbols; this is already how properties
> work, regardless of what kind of key they have.
>
> > The difference here is that in your use cases, library A is "sneakily"
> storing information on object B.
>
> What use case are you referring to here? I can’t find any example in the
> previous posts that matches these descriptions. As Isiah said, “all of the
> examples here I've presented are for scenarios where the state is related
> to the factory that created the objects.” The same is true of my examples.
> Everybody’s on the same page regarding not wanting to add properties to
> objects their own libraries do not create.
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-07-31 Thread Darien Valentine
> I'd say you've identified the common pattern, but that pattern itself is
a bad use case, and the use of private symbols as you have defined them
doesn't do anything to correct the technical issue.

I think there’s been a misunderstanding. Everybody agrees that that’s a bad
pattern. It’s not what the point of private symbols would be. It’s not a
target use case.

> Since you cannot stick new properties onto a non-extensible object, even
private symbols won't solve the problem with your use case.

That appending private symbols to external objects which are frozen
wouldn’t work doesn’t matter precisely because it’s not a target use case.
That it doesn’t work reliably might even be considered a positive, since it
discourages something we all seem to agree is not good practice.

It’s also not related to private symbols; this is already how properties
work, regardless of what kind of key they have.

> The difference here is that in your use cases, library A is "sneakily"
storing information on object B.

What use case are you referring to here? I can’t find any example in the
previous posts that matches these descriptions. As Isiah said, “all of the
examples here I've presented are for scenarios where the state is related
to the factory that created the objects.” The same is true of my examples.
Everybody’s on the same page regarding not wanting to add properties to
objects their own libraries do not create.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-07-31 Thread Michael Theriot
Should a sealed/frozen object be privately extensible? I don't actually
know, but interesting point.

On Tuesday, July 31, 2018, Ranando King  wrote:

> > Consider what people often use public symbols for now.
>
> I know that I use them as fixed-value unique keys (module globals) for
> properties on objects that I export and don't want others to be aware of or
> able to touch.
>
> > For example, consider this library [1]. In this case, they use a public
> symbol for their stuff in this file [2].
>
> And as I said before, if someone passes a non-extensible object to this
> library, it breaks. Since any library can request any object be sealed or
> frozen, the implementation of this library is too fragile.
>
> > Because here, it's not a cache, but it's literally extra associated
> data in the object. And also, in that case, you *want* the engine to see
> it as a property, since it can employ relevant IC caching for it.
>
> Here's a parallel for you. Right now, Google has a database with
> information about me on it. I don't have access to that information (module
> privacy) and that information isn't stored anywhere on me or my devices
> (module locality). This is a proper conceptual model. The information
> Google is keeping about me is information they generated. Why should I have
> to pay to store their information? Thankfully I don't. However, this is
> precisely what you're claiming to be a good use case. You want module
> privacy without module locality. If I were to play at a Kevin Gibbons-like
> response, I'd say you've identified the common pattern, but that pattern
> itself is a bad use case, and the use of private symbols as you have
> defined them doesn't do anything to correct the technical issue. Since you
> cannot stick new properties onto a non-extensible object, even private
> symbols won't solve the problem with your use case.
>
> > No, I'm not. I'm drawing a distinction between a pure many-to-one 
> > association
> (weak maps) and a "has a" relationship (private symbol properties).
>
> First, for any given property bag, the keys will need to be unique, but
> that doesn't force uniqueness onto the values. As such, even properties on
> an object provided by your "private Symbol" would still be many-1. When a
> 3rd party library wants to keep information associated with an arbitrary
> object, there are only 3 choices:
> * try to store that information on the object
>   * this is what you're advocating, but it's not a good pattern. It's too
> fragile, being subject to break if the incoming object is not extensible.
> * store the information as being associated to the object (WeakMap)
>   * this is the pattern that works in all cases (but the syntax is
> cumbersome and the implementation somewhat slow)
> * return a wrapper containing the original object and the new information
> (Proxy or custom wrapper)
>   * this is another possibility, but requires that any users accept and
> use the new Proxy or wrapper object in lieu of the original.
>
> > Another scenario is for JSDOM's `Window` implementation, where they have
> a few underscore-private variables like this [3]. That particular variable
> is used in several disparate parts throughout the code base [4], but is
> still conceptually a property. This is a case where a private symbol
> property is appropriate.
>
> It's not just "conceptually" a property. It's logically a property. Why?
> Because all the objects that it exists on were constructed somewhere within
> the JSDOM library. That's me putting _my_ keys in _my_ pocket. There's
> absolutely nothing wrong with that.
>
> > Conversely in this JSDOM file [5], it's just associating data with an 
> > arbitrary
> object it happens to have, and so using the weak map makes perfect sense.
>
> Conceptually speaking, this is the same scenario as SymbolTree. In both
> cases, the library is generating information associated with an object it
> doesn't own and didn't create.
>
> > BTW, you could make a similar argument against superclass private fields
> - it's like hiding valuable info in your wallet before you receive it for
> the first time, but even after dismantling it, you can't find any
> evidence of that valuable info.
>
> That dog don't hunt. The difference here is that in your use cases,
> library A is "sneakily" storing information on object B. In the case of
> superclass private fields, subclass B has "volunteered" to take on the
> information and functionality of class A. You've essentially compared
> apples and asteroids just because they both begin with "a".
>
> On Tue, Jul 31, 2018 at 2:15 AM Isiah Meadows 
> wrote:
>
>> > Isn't this precisely what WeakMaps are for? If the data is
>> > "module-internal", then the module needs to be the owner of the data
>> store.
>> > If the data is about "arbitrary objects" (object from outside the
>> module?)
>> > then those objects are the keys to the data store. If any object is
>> thrown
>> > away, the associated data is no longer needed. If this do

Re: !Re: proposal: Object Members

2018-07-31 Thread Ranando King
> Consider what people often use public symbols for now.

I know that I use them as fixed-value unique keys (module globals) for
properties on objects that I export and don't want others to be aware of or
able to touch.

> For example, consider this library [1]. In this case, they use a public
symbol for their stuff in this file [2].

And as I said before, if someone passes a non-extensible object to this
library, it breaks. Since any library can request any object be sealed or
frozen, the implementation of this library is too fragile.

> Because here, it's not a cache, but it's literally extra associated data
in the object. And also, in that case, you *want* the engine to see it as a
property, since it can employ relevant IC caching for it.

Here's a parallel for you. Right now, Google has a database with
information about me on it. I don't have access to that information (module
privacy) and that information isn't stored anywhere on me or my devices
(module locality). This is a proper conceptual model. The information
Google is keeping about me is information they generated. Why should I have
to pay to store their information? Thankfully I don't. However, this is
precisely what you're claiming to be a good use case. You want module
privacy without module locality. If I were to play at a Kevin Gibbons-like
response, I'd say you've identified the common pattern, but that pattern
itself is a bad use case, and the use of private symbols as you have
defined them doesn't do anything to correct the technical issue. Since you
cannot stick new properties onto a non-extensible object, even private
symbols won't solve the problem with your use case.

> No, I'm not. I'm drawing a distinction between a pure many-to-one association
(weak maps) and a "has a" relationship (private symbol properties).

First, for any given property bag, the keys will need to be unique, but
that doesn't force uniqueness onto the values. As such, even properties on
an object provided by your "private Symbol" would still be many-1. When a
3rd party library wants to keep information associated with an arbitrary
object, there are only 3 choices:
* try to store that information on the object
  * this is what you're advocating, but it's not a good pattern. It's too
fragile, being subject to break if the incoming object is not extensible.
* store the information as being associated to the object (WeakMap)
  * this is the pattern that works in all cases (but the syntax is
cumbersome and the implementation somewhat slow)
* return a wrapper containing the original object and the new information
(Proxy or custom wrapper)
  * this is another possibility, but requires that any users accept and use
the new Proxy or wrapper object in lieu of the original.

> Another scenario is for JSDOM's `Window` implementation, where they have
a few underscore-private variables like this [3]. That particular variable
is used in several disparate parts throughout the code base [4], but is
still conceptually a property. This is a case where a private symbol
property is appropriate.

It's not just "conceptually" a property. It's logically a property. Why?
Because all the objects that it exists on were constructed somewhere within
the JSDOM library. That's me putting _my_ keys in _my_ pocket. There's
absolutely nothing wrong with that.

> Conversely in this JSDOM file [5], it's just associating data with an 
> arbitrary
object it happens to have, and so using the weak map makes perfect sense.

Conceptually speaking, this is the same scenario as SymbolTree. In both
cases, the library is generating information associated with an object it
doesn't own and didn't create.

> BTW, you could make a similar argument against superclass private fields
- it's like hiding valuable info in your wallet before you receive it for
the first time, but even after dismantling it, you can't find any evidence
of that valuable info.

That dog don't hunt. The difference here is that in your use cases, library
A is "sneakily" storing information on object B. In the case of superclass
private fields, subclass B has "volunteered" to take on the information and
functionality of class A. You've essentially compared apples and asteroids
just because they both begin with "a".

On Tue, Jul 31, 2018 at 2:15 AM Isiah Meadows 
wrote:

> > Isn't this precisely what WeakMaps are for? If the data is
> > "module-internal", then the module needs to be the owner of the data
> store.
> > If the data is about "arbitrary objects" (object from outside the
> module?)
> > then those objects are the keys to the data store. If any object is
> thrown
> > away, the associated data is no longer needed. If this doesn't fit the
> > functionality of a WeakMap, I don't know what will.
>
> Consider what people often use public symbols for now. For example,
> consider this library [1]. In this case, they use a public symbol for
> their stuff in this file [2].
>
> But here's the thing: that doesn't really need discoverable, and 

Re: !Re: proposal: Object Members

2018-07-31 Thread Isiah Meadows
> Isn't this precisely what WeakMaps are for? If the data is
> "module-internal", then the module needs to be the owner of the data store.
> If the data is about "arbitrary objects" (object from outside the module?)
> then those objects are the keys to the data store. If any object is thrown
> away, the associated data is no longer needed. If this doesn't fit the
> functionality of a WeakMap, I don't know what will.

Consider what people often use public symbols for now. For example,
consider this library [1]. In this case, they use a public symbol for
their stuff in this file [2].

But here's the thing: that doesn't really need discoverable, and is a
pure implementation detail. Wouldn't it make more sense for them to
just use a private symbol instead? Because here, it's not a cache, but
it's literally extra associated data in the object. And also, in that
case, you *want* the engine to see it as a property, since it can
employ relevant IC caching for it.

> Isn't that precisely what your question calls for? You're caching
> module-internal data about external objects.

No, I'm not. I'm drawing a distinction between a pure many-to-one
association (weak maps) and a "has a" relationship (private symbol
properties). You *could* implement one in terms of the other, but
these two types of relationships are *completely* different at a
conceptual level and how you model them.

For js-symbol-tree, it's not simply associating a node to a value, but
setting up the object so it *has* the data required for a doubly
linked list tree node. Because this symbol is repeatedly accessed,
it's not caching so much as it's adding data the object needs for it
to do what it needs to do.

Another scenario is for JSDOM's `Window` implementation, where they
have a few underscore-private variables like this [3]. That particular
variable is used in several disparate parts throughout the code base
[4], but is still conceptually a property. This is a case where a
private symbol property is appropriate.

Conversely in this JSDOM file [5], it's just associating data with an
arbitrary object it happens to have, and so using the weak map makes
perfect sense.

> Likewise, I'm specifically against the abuse of objects to store state
> unrelated to the factory that created it. To me, that's as if I came to
> visit you and somehow you managed to hide some valuable info in my wallet
> without me noticing, and even if I completely dismantle my wallet, I
> wouldn't be able to find it. But somehow you can easily retrieve it the next
> time I come around. That's just conceptually weird.

All of the examples here I've presented are for scenarios where the
state *is* related to the factory that created the objects. It's not
*directly* related (and thus encapsulation is warranted), but it's
still *related*, enough so that you usually see the state initialized
within the creator's constructor call. It's about as related as the
superclass is to a subclass of it.

BTW, you could make a similar argument against superclass private
fields - it's like hiding valuable info in your wallet before you
receive it for the first time, but even after dismantling it, you
can't find any evidence of that valuable info.

[1]: https://github.com/jsdom/js-symbol-tree
[2]: https://github.com/jsdom/js-symbol-tree/blob/master/lib/SymbolTree.js#L28
[3]: 
https://github.com/jsdom/jsdom/blob/23d67ebec901b3471b84e63f58a96b51a36f3671/lib/jsdom/browser/Window.js#L80
[4]: https://github.com/jsdom/jsdom/search?q=_globalProxy
[5]: 
https://github.com/jsdom/jsdom/blob/ad0e551b1b633e07d11f98d7a30287491958def3/lib/jsdom/living/websockets/WebSocket-impl.js#L49

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Tue, Jul 31, 2018 at 1:55 AM, Ranando King  wrote:
>> One last thing: how would you hope to deal with module-internal data
>> stored on arbitrary objects, using any means other than private symbols or
>> something similar?
>
> Isn't this precisely what WeakMaps are for? If the data is
> "module-internal", then the module needs to be the owner of the data store.
> If the data is about "arbitrary objects" (object from outside the module?)
> then those objects are the keys to the data store. If any object is thrown
> away, the associated data is no longer needed. If this doesn't fit the
> functionality of a WeakMap, I don't know what will.
>
>> Weak maps make sense when the weak map is the dictionary conceptually
>> (think: caching).
>
> Isn't that precisely what your question calls for? You're caching
> module-internal data about external objects.
>
>> Keep in mind, I'm specifically *against* the abuse of weak maps for
>> private state that's conceptually (in an abstract sense, not runtime) part
>> of an object.
>
> Likewise, I'm specifically against the abuse of objects to store state
> unrelated to the factory that created it. To me, that's as if I came to
> visit you and somehow you managed to hide some valuable info in my wallet
> without me noticing, and eve

Re: !Re: proposal: Object Members

2018-07-30 Thread Ranando King
> One last thing: how would you hope to deal with module-internal data stored
on arbitrary objects, using any means other than private symbols or
something similar?

Isn't this precisely what WeakMaps are for? If the data is
"module-internal", then the module needs to be the owner of the data store.
If the data is about "arbitrary objects" (object from outside the module?)
then those objects are the keys to the data store. If any object is thrown
away, the associated data is no longer needed. If this doesn't fit the
functionality of a WeakMap, I don't know what will.

> Weak maps make sense when the weak map is the dictionary conceptually
(think: caching).

Isn't that precisely what your question calls for? You're caching
module-internal data about external objects.

> Keep in mind, I'm specifically *against* the abuse of weak maps for private
state that's conceptually (in an abstract sense, not runtime) part of an
object.

Likewise, I'm specifically against the abuse of objects to store state
unrelated to the factory that created it. To me, that's as if I came to
visit you and somehow you managed to hide some valuable info in my wallet
without me noticing, and even if I completely dismantle my wallet, I
wouldn't be able to find it. But somehow you can easily retrieve it the
next time I come around. That's just conceptually weird.

On Mon, Jul 30, 2018 at 9:42 PM Isiah Meadows 
wrote:

> The reason private symbols are appropriate for Node's use case is
> because it's conceptually a mixin, not a simple key/value map with
> various utility functions (and weak map lookup is slower than property
> access). JSDOM uses a similar utility [1] as a sort of mixin.
>
> Keep in mind, I'm specifically *against* the abuse of weak maps for
> private state that's conceptually (in an abstract sense, not runtime)
> part of an object. Weak maps make sense when the weak map is the
> dictionary conceptually (think: caching). But if conceptually, the
> object is the dictionary, putting it in a weak map is giving the
> engine the wrong info - properties have inline caches and heavy
> optimization, but you can't do the same for weak maps in the other
> direction without literally implementing them as properties. (I would
> *love* to be proven wrong here, BTW.)
>
> Let me draw a quick comparison: When do you use a map/set with string
> keys, and when do you use an object instead?
>
> - Both are functionally equivalent, but engines use *very* different
> algorithms for each one.
> - I can almost guarantee you don't use maps when object properties work.
>
> One last thing: how would you hope to deal with module-internal data
> stored on arbitrary objects, using any means other than private
> symbols or something similar? To clarify, I'm talking of opaque object
> structs [2], not simply classes. (BTW, that one is easier to manage as
> a struct rather than a class, because of how many "methods" there are
> operating on the state.)
>
> [1]: https://github.com/jsdom/js-symbol-tree
> [2]: https://github.com/isiahmeadows/enigma/blob/master/src/parser.ts
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Mon, Jul 30, 2018 at 9:00 PM, Ranando King  wrote:
> > I meant to say if the object passed to the 3rd party function.
> >
> >
> > On Mon, Jul 30, 2018 at 7:59 PM Ranando King  wrote:
> >>
> >> Just that use case alone is problematic. If the 3rd party function is
> not
> >> extensible, then the new private data should not be allowed. If the
> library
> >> cannot function without storing that data, then the function will have
> no
> >> choice but to fall back to WeakMaps which don't care if the key is not
> >> extensible. So why not just stick with WeakMaps for that case? And if
> that's
> >> the case, then there would be little need for so open a means of
> defining
> >> private field names. The proposal I'm offering offers the room to
> extend it
> >> in the future to support everything else you might look for from your
> >> private symbols idea unless you think I missed something.
> >>
> >> On Mon, Jul 30, 2018 at 7:26 PM Isiah Meadows 
> >> wrote:
> >>>
> >>> That is one supported use case, yes. But that isn't the only use case
> >>> this supports. It can still extend to traditional private class data,
> >>> too.
> >>>
> >>> -
> >>>
> >>> Isiah Meadows
> >>> cont...@isiahmeadows.com
> >>> www.isiahmeadows.com
> >>>
> >>>
> >>> On Mon, Jul 30, 2018 at 8:04 PM, Ranando King 
> wrote:
> >>> > So you're wanting the ability for a 3rd-party function to be able to
> >>> > store
> >>> > data private to that library on an object it didn't create, and that
> >>> > only
> >>> > that library can access?
> >>> >
> >>> > On Mon, Jul 30, 2018 at 6:36 PM Isiah Meadows <
> isiahmead...@gmail.com>
> >>> > wrote:
> >>> >>
> >>> >> First, my private symbols are properly *private*. The only
> >>> >> "unexpected" thing that could happen is making an object larger
> >>> >> memory-wise, which engines already have

Re: !Re: proposal: Object Members

2018-07-30 Thread Isiah Meadows
The reason private symbols are appropriate for Node's use case is
because it's conceptually a mixin, not a simple key/value map with
various utility functions (and weak map lookup is slower than property
access). JSDOM uses a similar utility [1] as a sort of mixin.

Keep in mind, I'm specifically *against* the abuse of weak maps for
private state that's conceptually (in an abstract sense, not runtime)
part of an object. Weak maps make sense when the weak map is the
dictionary conceptually (think: caching). But if conceptually, the
object is the dictionary, putting it in a weak map is giving the
engine the wrong info - properties have inline caches and heavy
optimization, but you can't do the same for weak maps in the other
direction without literally implementing them as properties. (I would
*love* to be proven wrong here, BTW.)

Let me draw a quick comparison: When do you use a map/set with string
keys, and when do you use an object instead?

- Both are functionally equivalent, but engines use *very* different
algorithms for each one.
- I can almost guarantee you don't use maps when object properties work.

One last thing: how would you hope to deal with module-internal data
stored on arbitrary objects, using any means other than private
symbols or something similar? To clarify, I'm talking of opaque object
structs [2], not simply classes. (BTW, that one is easier to manage as
a struct rather than a class, because of how many "methods" there are
operating on the state.)

[1]: https://github.com/jsdom/js-symbol-tree
[2]: https://github.com/isiahmeadows/enigma/blob/master/src/parser.ts

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Mon, Jul 30, 2018 at 9:00 PM, Ranando King  wrote:
> I meant to say if the object passed to the 3rd party function.
>
>
> On Mon, Jul 30, 2018 at 7:59 PM Ranando King  wrote:
>>
>> Just that use case alone is problematic. If the 3rd party function is not
>> extensible, then the new private data should not be allowed. If the library
>> cannot function without storing that data, then the function will have no
>> choice but to fall back to WeakMaps which don't care if the key is not
>> extensible. So why not just stick with WeakMaps for that case? And if that's
>> the case, then there would be little need for so open a means of defining
>> private field names. The proposal I'm offering offers the room to extend it
>> in the future to support everything else you might look for from your
>> private symbols idea unless you think I missed something.
>>
>> On Mon, Jul 30, 2018 at 7:26 PM Isiah Meadows 
>> wrote:
>>>
>>> That is one supported use case, yes. But that isn't the only use case
>>> this supports. It can still extend to traditional private class data,
>>> too.
>>>
>>> -
>>>
>>> Isiah Meadows
>>> cont...@isiahmeadows.com
>>> www.isiahmeadows.com
>>>
>>>
>>> On Mon, Jul 30, 2018 at 8:04 PM, Ranando King  wrote:
>>> > So you're wanting the ability for a 3rd-party function to be able to
>>> > store
>>> > data private to that library on an object it didn't create, and that
>>> > only
>>> > that library can access?
>>> >
>>> > On Mon, Jul 30, 2018 at 6:36 PM Isiah Meadows 
>>> > wrote:
>>> >>
>>> >> First, my private symbols are properly *private*. The only
>>> >> "unexpected" thing that could happen is making an object larger
>>> >> memory-wise, which engines already have to be equipped to handle now
>>> >> (libraries aren't always well-behaved, and like to occasionally add
>>> >> expando properties to builtins and DOM elements). About the only thing
>>> >> most people would care about is in the debugger.
>>> >>
>>> >> Second, I had things like this in mind with supporting expando
>>> >> properties:
>>> >>
>>> >> https://github.com/nodejs/node/blob/ae4fde8bc883686def5badfb324236320669e8f4/lib/internal/linkedlist.js
>>> >>
>>> >> In that case, the Node.js people made it a pseudo-mixin rather than an
>>> >> actual type for performance reasons - there's fewer object allocations
>>> >> and they needed that.
>>> >>
>>> >> So I've considered the expando problem, and I disagree about it being
>>> >> a problem at all.
>>> >>
>>> >> -
>>> >>
>>> >> Isiah Meadows
>>> >> cont...@isiahmeadows.com
>>> >> www.isiahmeadows.com
>>> >>
>>> >>
>>> >> On Mon, Jul 30, 2018 at 6:35 PM, Waldemar Horwat 
>>> >> wrote:
>>> >> > On 07/29/2018 04:37 PM, Isiah Meadows wrote:
>>> >> >>
>>> >> >> BTW, I came up with an alternate proposal for privacy altogether:
>>> >> >> https://github.com/tc39/proposal-class-fields/issues/115
>>> >> >>
>>> >> >> TL;DR: private symbols that proxies can't see and that can't be
>>> >> >> enumerated.
>>> >> >
>>> >> >
>>> >> > Aside from syntax, the main semantic difference I see between this
>>> >> > alternative and the main one is that this alternative defines
>>> >> > private
>>> >> > fields
>>> >> > as expandos, creating opportunities for mischief by attaching them
>>> >> > to
>>> >> > unexpected objects.  Aside from privacy, one of th

Re: !Re: proposal: Object Members

2018-07-30 Thread Ranando King
I meant to say if the object passed to the 3rd party function.


On Mon, Jul 30, 2018 at 7:59 PM Ranando King  wrote:

> Just that use case alone is problematic. If the 3rd party function is not
> extensible, then the new private data should not be allowed. If the library
> cannot function without storing that data, then the function will have no
> choice but to fall back to WeakMaps which don't care if the key is not
> extensible. So why not just stick with WeakMaps for that case? And if
> that's the case, then there would be little need for so open a means of
> defining private field names. The proposal I'm offering offers the room to
> extend it in the future to support everything else you might look for from
> your private symbols idea unless you think I missed something.
>
> On Mon, Jul 30, 2018 at 7:26 PM Isiah Meadows 
> wrote:
>
>> That is one supported use case, yes. But that isn't the only use case
>> this supports. It can still extend to traditional private class data,
>> too.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Mon, Jul 30, 2018 at 8:04 PM, Ranando King  wrote:
>> > So you're wanting the ability for a 3rd-party function to be able to
>> store
>> > data private to that library on an object it didn't create, and that
>> only
>> > that library can access?
>> >
>> > On Mon, Jul 30, 2018 at 6:36 PM Isiah Meadows 
>> > wrote:
>> >>
>> >> First, my private symbols are properly *private*. The only
>> >> "unexpected" thing that could happen is making an object larger
>> >> memory-wise, which engines already have to be equipped to handle now
>> >> (libraries aren't always well-behaved, and like to occasionally add
>> >> expando properties to builtins and DOM elements). About the only thing
>> >> most people would care about is in the debugger.
>> >>
>> >> Second, I had things like this in mind with supporting expando
>> >> properties:
>> >>
>> https://github.com/nodejs/node/blob/ae4fde8bc883686def5badfb324236320669e8f4/lib/internal/linkedlist.js
>> >>
>> >> In that case, the Node.js people made it a pseudo-mixin rather than an
>> >> actual type for performance reasons - there's fewer object allocations
>> >> and they needed that.
>> >>
>> >> So I've considered the expando problem, and I disagree about it being
>> >> a problem at all.
>> >>
>> >> -
>> >>
>> >> Isiah Meadows
>> >> cont...@isiahmeadows.com
>> >> www.isiahmeadows.com
>> >>
>> >>
>> >> On Mon, Jul 30, 2018 at 6:35 PM, Waldemar Horwat 
>> >> wrote:
>> >> > On 07/29/2018 04:37 PM, Isiah Meadows wrote:
>> >> >>
>> >> >> BTW, I came up with an alternate proposal for privacy altogether:
>> >> >> https://github.com/tc39/proposal-class-fields/issues/115
>> >> >>
>> >> >> TL;DR: private symbols that proxies can't see and that can't be
>> >> >> enumerated.
>> >> >
>> >> >
>> >> > Aside from syntax, the main semantic difference I see between this
>> >> > alternative and the main one is that this alternative defines private
>> >> > fields
>> >> > as expandos, creating opportunities for mischief by attaching them to
>> >> > unexpected objects.  Aside from privacy, one of the things the
>> private
>> >> > fields proposal gives you is consistency among multiple private
>> fields
>> >> > on
>> >> > the same object.  In the rare cases where you don't want that, you
>> could
>> >> > use
>> >> > weak maps.
>> >> >
>> >> > Waldemar
>> >> ___
>> >> 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


Re: !Re: proposal: Object Members

2018-07-30 Thread Ranando King
Just that use case alone is problematic. If the 3rd party function is not
extensible, then the new private data should not be allowed. If the library
cannot function without storing that data, then the function will have no
choice but to fall back to WeakMaps which don't care if the key is not
extensible. So why not just stick with WeakMaps for that case? And if
that's the case, then there would be little need for so open a means of
defining private field names. The proposal I'm offering offers the room to
extend it in the future to support everything else you might look for from
your private symbols idea unless you think I missed something.

On Mon, Jul 30, 2018 at 7:26 PM Isiah Meadows 
wrote:

> That is one supported use case, yes. But that isn't the only use case
> this supports. It can still extend to traditional private class data,
> too.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Mon, Jul 30, 2018 at 8:04 PM, Ranando King  wrote:
> > So you're wanting the ability for a 3rd-party function to be able to
> store
> > data private to that library on an object it didn't create, and that only
> > that library can access?
> >
> > On Mon, Jul 30, 2018 at 6:36 PM Isiah Meadows 
> > wrote:
> >>
> >> First, my private symbols are properly *private*. The only
> >> "unexpected" thing that could happen is making an object larger
> >> memory-wise, which engines already have to be equipped to handle now
> >> (libraries aren't always well-behaved, and like to occasionally add
> >> expando properties to builtins and DOM elements). About the only thing
> >> most people would care about is in the debugger.
> >>
> >> Second, I had things like this in mind with supporting expando
> >> properties:
> >>
> https://github.com/nodejs/node/blob/ae4fde8bc883686def5badfb324236320669e8f4/lib/internal/linkedlist.js
> >>
> >> In that case, the Node.js people made it a pseudo-mixin rather than an
> >> actual type for performance reasons - there's fewer object allocations
> >> and they needed that.
> >>
> >> So I've considered the expando problem, and I disagree about it being
> >> a problem at all.
> >>
> >> -
> >>
> >> Isiah Meadows
> >> cont...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Mon, Jul 30, 2018 at 6:35 PM, Waldemar Horwat 
> >> wrote:
> >> > On 07/29/2018 04:37 PM, Isiah Meadows wrote:
> >> >>
> >> >> BTW, I came up with an alternate proposal for privacy altogether:
> >> >> https://github.com/tc39/proposal-class-fields/issues/115
> >> >>
> >> >> TL;DR: private symbols that proxies can't see and that can't be
> >> >> enumerated.
> >> >
> >> >
> >> > Aside from syntax, the main semantic difference I see between this
> >> > alternative and the main one is that this alternative defines private
> >> > fields
> >> > as expandos, creating opportunities for mischief by attaching them to
> >> > unexpected objects.  Aside from privacy, one of the things the private
> >> > fields proposal gives you is consistency among multiple private fields
> >> > on
> >> > the same object.  In the rare cases where you don't want that, you
> could
> >> > use
> >> > weak maps.
> >> >
> >> > Waldemar
> >> ___
> >> 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


Re: !Re: proposal: Object Members

2018-07-30 Thread Isiah Meadows
That is one supported use case, yes. But that isn't the only use case
this supports. It can still extend to traditional private class data,
too.

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Mon, Jul 30, 2018 at 8:04 PM, Ranando King  wrote:
> So you're wanting the ability for a 3rd-party function to be able to store
> data private to that library on an object it didn't create, and that only
> that library can access?
>
> On Mon, Jul 30, 2018 at 6:36 PM Isiah Meadows 
> wrote:
>>
>> First, my private symbols are properly *private*. The only
>> "unexpected" thing that could happen is making an object larger
>> memory-wise, which engines already have to be equipped to handle now
>> (libraries aren't always well-behaved, and like to occasionally add
>> expando properties to builtins and DOM elements). About the only thing
>> most people would care about is in the debugger.
>>
>> Second, I had things like this in mind with supporting expando
>> properties:
>> https://github.com/nodejs/node/blob/ae4fde8bc883686def5badfb324236320669e8f4/lib/internal/linkedlist.js
>>
>> In that case, the Node.js people made it a pseudo-mixin rather than an
>> actual type for performance reasons - there's fewer object allocations
>> and they needed that.
>>
>> So I've considered the expando problem, and I disagree about it being
>> a problem at all.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Mon, Jul 30, 2018 at 6:35 PM, Waldemar Horwat 
>> wrote:
>> > On 07/29/2018 04:37 PM, Isiah Meadows wrote:
>> >>
>> >> BTW, I came up with an alternate proposal for privacy altogether:
>> >> https://github.com/tc39/proposal-class-fields/issues/115
>> >>
>> >> TL;DR: private symbols that proxies can't see and that can't be
>> >> enumerated.
>> >
>> >
>> > Aside from syntax, the main semantic difference I see between this
>> > alternative and the main one is that this alternative defines private
>> > fields
>> > as expandos, creating opportunities for mischief by attaching them to
>> > unexpected objects.  Aside from privacy, one of the things the private
>> > fields proposal gives you is consistency among multiple private fields
>> > on
>> > the same object.  In the rare cases where you don't want that, you could
>> > use
>> > weak maps.
>> >
>> > Waldemar
>> ___
>> 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


Re: !Re: proposal: Object Members

2018-07-30 Thread Ranando King
So you're wanting the ability for a 3rd-party function to be able to store
data private to that library on an object it didn't create, and that only
that library can access?

On Mon, Jul 30, 2018 at 6:36 PM Isiah Meadows 
wrote:

> First, my private symbols are properly *private*. The only
> "unexpected" thing that could happen is making an object larger
> memory-wise, which engines already have to be equipped to handle now
> (libraries aren't always well-behaved, and like to occasionally add
> expando properties to builtins and DOM elements). About the only thing
> most people would care about is in the debugger.
>
> Second, I had things like this in mind with supporting expando
> properties:
> https://github.com/nodejs/node/blob/ae4fde8bc883686def5badfb324236320669e8f4/lib/internal/linkedlist.js
>
> In that case, the Node.js people made it a pseudo-mixin rather than an
> actual type for performance reasons - there's fewer object allocations
> and they needed that.
>
> So I've considered the expando problem, and I disagree about it being
> a problem at all.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Mon, Jul 30, 2018 at 6:35 PM, Waldemar Horwat 
> wrote:
> > On 07/29/2018 04:37 PM, Isiah Meadows wrote:
> >>
> >> BTW, I came up with an alternate proposal for privacy altogether:
> >> https://github.com/tc39/proposal-class-fields/issues/115
> >>
> >> TL;DR: private symbols that proxies can't see and that can't be
> >> enumerated.
> >
> >
> > Aside from syntax, the main semantic difference I see between this
> > alternative and the main one is that this alternative defines private
> fields
> > as expandos, creating opportunities for mischief by attaching them to
> > unexpected objects.  Aside from privacy, one of the things the private
> > fields proposal gives you is consistency among multiple private fields on
> > the same object.  In the rare cases where you don't want that, you could
> use
> > weak maps.
> >
> > Waldemar
> ___
> 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


Re: !Re: proposal: Object Members

2018-07-30 Thread Isiah Meadows
First, my private symbols are properly *private*. The only
"unexpected" thing that could happen is making an object larger
memory-wise, which engines already have to be equipped to handle now
(libraries aren't always well-behaved, and like to occasionally add
expando properties to builtins and DOM elements). About the only thing
most people would care about is in the debugger.

Second, I had things like this in mind with supporting expando
properties: 
https://github.com/nodejs/node/blob/ae4fde8bc883686def5badfb324236320669e8f4/lib/internal/linkedlist.js

In that case, the Node.js people made it a pseudo-mixin rather than an
actual type for performance reasons - there's fewer object allocations
and they needed that.

So I've considered the expando problem, and I disagree about it being
a problem at all.

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com


On Mon, Jul 30, 2018 at 6:35 PM, Waldemar Horwat  wrote:
> On 07/29/2018 04:37 PM, Isiah Meadows wrote:
>>
>> BTW, I came up with an alternate proposal for privacy altogether:
>> https://github.com/tc39/proposal-class-fields/issues/115
>>
>> TL;DR: private symbols that proxies can't see and that can't be
>> enumerated.
>
>
> Aside from syntax, the main semantic difference I see between this
> alternative and the main one is that this alternative defines private fields
> as expandos, creating opportunities for mischief by attaching them to
> unexpected objects.  Aside from privacy, one of the things the private
> fields proposal gives you is consistency among multiple private fields on
> the same object.  In the rare cases where you don't want that, you could use
> weak maps.
>
> Waldemar
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-07-30 Thread Waldemar Horwat

On 07/29/2018 04:37 PM, Isiah Meadows wrote:

BTW, I came up with an alternate proposal for privacy altogether:
https://github.com/tc39/proposal-class-fields/issues/115

TL;DR: private symbols that proxies can't see and that can't be enumerated.


Aside from syntax, the main semantic difference I see between this alternative 
and the main one is that this alternative defines private fields as expandos, 
creating opportunities for mischief by attaching them to unexpected objects.  
Aside from privacy, one of the things the private fields proposal gives you is 
consistency among multiple private fields on the same object.  In the rare 
cases where you don't want that, you could use weak maps.

Waldemar
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-07-30 Thread Ranando King
Isn't this just a different version of the private names idea that Kevin &
Daniel were pushing before settling into "proposal-class-fields"? If not,
then what's the difference?

On Mon, Jul 30, 2018 at 6:01 AM Michael Theriot <
michael.lee.ther...@gmail.com> wrote:

> I'll just say it feels inconsistent with how every other property is
> configured. That the key itself holds magic behavior-changing information.
> It's not a use case or overhead concern.
>
> On Monday, July 30, 2018, Isiah Meadows  wrote:
>
>> Um, no. The use case is *extremely* limited, and that ruins a few
>> optimizations you could otherwise make with private symbols (like
>> caching proxy forwarding without having to bail out).
>>
>> Besides, whether a symbol is private requires exactly one bit to
>> store, so there's no real overhead with storing it on the object.
>> Heck, if you want to optimize it better, you might choose to store
>> that same bit on both the symbol and the object descriptor itself, and
>> I'd expect engines to do just that - it saves a pointer dereference.
>> -
>>
>> Isiah Meadows
>> m...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Mon, Jul 30, 2018 at 1:25 AM, Michael Theriot
>>  wrote:
>> > Also throwing this out there, symbols would now carry additional
>> > information: private or normal. Would it be better to configure this on
>> > objects instead?
>> >
>> > E.g. `Object.setPropertySymbolVisibility(object, symbol, true / false)`
>> >
>> > (and then ideally sugar for this)
>> >
>> > That way a symbol's visibility on an object is information held on the
>> > object rather than the primitive. A little more work involved, but
>> lines up
>> > with Object.defineProperty and symbols remain purely unique identifiers.
>> >
>> > On Monday, July 30, 2018, Isiah Meadows  wrote:
>> >>
>> >> I'm aware it's possible to misuse, but if concerns of misuse were a
>> >> serious issue, we wouldn't have iterators, for example [1] [2]. But
>> >> IMHO freeing weak maps from a role they weren't designed for
>> >> substantially outweighs the risks of abusing them further (and the
>> >> abuses are incredibly frequent).
>> >>
>> >> [1]:
>> >>
>> https://esdiscuss.org/topic/iterators-generators-finally-and-scarce-resources-was-april-10-2014-meeting-notes
>> >> [2]: https://esdiscuss.org/topic/resource-management
>> >>
>> >> -
>> >>
>> >> Isiah Meadows
>> >> m...@isiahmeadows.com
>> >> www.isiahmeadows.com
>> >>
>> >>
>> >> On Sun, Jul 29, 2018 at 10:55 PM, Michael Theriot
>> >>  wrote:
>> >> > Right, I wouldn't, but I'm concerned others would misuse it. I don't
>> >> > think
>> >> > it's a blocker though, and actually frees weakmaps from trying to
>> fill
>> >> > this
>> >> > role.
>> >> >
>> >> >
>> >> > On Sunday, July 29, 2018, Isiah Meadows 
>> wrote:
>> >> >>
>> >> >> It will, but weak maps will still remain useful for cases when
>> you're
>> >> >> semantically dealing with a key/value map. In theory, you could
>> >> >> implement a weak map on top of this [1], but in practice, it doesn't
>> >> >> always make sense to do it. A good example of this is if you are
>> >> >> "tagging" an object with data. If this data isn't really part of the
>> >> >> object itself, you shouldn't be using a private symbol for it.
>> Another
>> >> >> good example is if you're doing simple caching and you need to clear
>> >> >> the weak map by replacing it. Using private symbols for this doesn't
>> >> >> really fit with the domain here, so you're more likely just to
>> confuse
>> >> >> future readers (including yourself) if you do this.
>> >> >>
>> >> >> [1]:
>> >> >>
>> https://gist.github.com/isiahmeadows/a8494868c4b193dfbf7139589f472ad8
>> >> >> -
>> >> >>
>> >> >> Isiah Meadows
>> >> >> m...@isiahmeadows.com
>> >> >> www.isiahmeadows.com
>> >> >>
>> >> >>
>> >> >> On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot
>> >> >>  wrote:
>> >> >> > Private symbols sounds like an easy win. They would be painfully
>> >> >> > simple,
>> >> >> > real properties, not just variables with property imitation syntax
>> >> >> > that
>> >> >> > undoubtedly confuses people. With the added benefit that children
>> can
>> >> >> > truly
>> >> >> > override the base class, freedom to define private members shared
>> >> >> > across
>> >> >> > otherwise unrelated objects, and even injection. My only concern
>> is
>> >> >> > that
>> >> >> > it
>> >> >> > could cross into WeakMap use cases.
>> >> >> >
>> >> >> >
>> >> >> > On Sunday, July 29, 2018, Isiah Meadows 
>> >> >> > wrote:
>> >> >> >>
>> >> >> >> BTW, I came up with an alternate proposal for privacy altogether:
>> >> >> >> https://github.com/tc39/proposal-class-fields/issues/115
>> >> >> >>
>> >> >> >> TL;DR: private symbols that proxies can't see and that can't be
>> >> >> >> enumerated.
>> >> >> >> -
>> >> >> >>
>> >> >> >> Isiah Meadows
>> >> >> >> m...@isiahmeadows.com
>> >> >> >> www.isiahmeadows.com
>> >> >> >>
>> >> >> >>
>> >> >> >> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
>> >> >>

Re: !Re: proposal: Object Members

2018-07-30 Thread Michael Theriot
I'll just say it feels inconsistent with how every other property is
configured. That the key itself holds magic behavior-changing information.
It's not a use case or overhead concern.

On Monday, July 30, 2018, Isiah Meadows  wrote:

> Um, no. The use case is *extremely* limited, and that ruins a few
> optimizations you could otherwise make with private symbols (like
> caching proxy forwarding without having to bail out).
>
> Besides, whether a symbol is private requires exactly one bit to
> store, so there's no real overhead with storing it on the object.
> Heck, if you want to optimize it better, you might choose to store
> that same bit on both the symbol and the object descriptor itself, and
> I'd expect engines to do just that - it saves a pointer dereference.
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Mon, Jul 30, 2018 at 1:25 AM, Michael Theriot
>  wrote:
> > Also throwing this out there, symbols would now carry additional
> > information: private or normal. Would it be better to configure this on
> > objects instead?
> >
> > E.g. `Object.setPropertySymbolVisibility(object, symbol, true / false)`
> >
> > (and then ideally sugar for this)
> >
> > That way a symbol's visibility on an object is information held on the
> > object rather than the primitive. A little more work involved, but lines
> up
> > with Object.defineProperty and symbols remain purely unique identifiers.
> >
> > On Monday, July 30, 2018, Isiah Meadows  wrote:
> >>
> >> I'm aware it's possible to misuse, but if concerns of misuse were a
> >> serious issue, we wouldn't have iterators, for example [1] [2]. But
> >> IMHO freeing weak maps from a role they weren't designed for
> >> substantially outweighs the risks of abusing them further (and the
> >> abuses are incredibly frequent).
> >>
> >> [1]:
> >> https://esdiscuss.org/topic/iterators-generators-finally-
> and-scarce-resources-was-april-10-2014-meeting-notes
> >> [2]: https://esdiscuss.org/topic/resource-management
> >>
> >> -
> >>
> >> Isiah Meadows
> >> m...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Sun, Jul 29, 2018 at 10:55 PM, Michael Theriot
> >>  wrote:
> >> > Right, I wouldn't, but I'm concerned others would misuse it. I don't
> >> > think
> >> > it's a blocker though, and actually frees weakmaps from trying to fill
> >> > this
> >> > role.
> >> >
> >> >
> >> > On Sunday, July 29, 2018, Isiah Meadows 
> wrote:
> >> >>
> >> >> It will, but weak maps will still remain useful for cases when you're
> >> >> semantically dealing with a key/value map. In theory, you could
> >> >> implement a weak map on top of this [1], but in practice, it doesn't
> >> >> always make sense to do it. A good example of this is if you are
> >> >> "tagging" an object with data. If this data isn't really part of the
> >> >> object itself, you shouldn't be using a private symbol for it.
> Another
> >> >> good example is if you're doing simple caching and you need to clear
> >> >> the weak map by replacing it. Using private symbols for this doesn't
> >> >> really fit with the domain here, so you're more likely just to
> confuse
> >> >> future readers (including yourself) if you do this.
> >> >>
> >> >> [1]:
> >> >> https://gist.github.com/isiahmeadows/a8494868c4b193dfbf7139589f472a
> d8
> >> >> -
> >> >>
> >> >> Isiah Meadows
> >> >> m...@isiahmeadows.com
> >> >> www.isiahmeadows.com
> >> >>
> >> >>
> >> >> On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot
> >> >>  wrote:
> >> >> > Private symbols sounds like an easy win. They would be painfully
> >> >> > simple,
> >> >> > real properties, not just variables with property imitation syntax
> >> >> > that
> >> >> > undoubtedly confuses people. With the added benefit that children
> can
> >> >> > truly
> >> >> > override the base class, freedom to define private members shared
> >> >> > across
> >> >> > otherwise unrelated objects, and even injection. My only concern is
> >> >> > that
> >> >> > it
> >> >> > could cross into WeakMap use cases.
> >> >> >
> >> >> >
> >> >> > On Sunday, July 29, 2018, Isiah Meadows 
> >> >> > wrote:
> >> >> >>
> >> >> >> BTW, I came up with an alternate proposal for privacy altogether:
> >> >> >> https://github.com/tc39/proposal-class-fields/issues/115
> >> >> >>
> >> >> >> TL;DR: private symbols that proxies can't see and that can't be
> >> >> >> enumerated.
> >> >> >> -
> >> >> >>
> >> >> >> Isiah Meadows
> >> >> >> m...@isiahmeadows.com
> >> >> >> www.isiahmeadows.com
> >> >> >>
> >> >> >>
> >> >> >> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
> >> >> >>  wrote:
> >> >> >> >> What you're essentially asking for is a violatable private
> field,
> >> >> >> >> or
> >> >> >> >> as
> >> >> >> >> has been described by others, a "soft private".
> >> >> >> >
> >> >> >> > We might have different definitions here, but I would describe
> >> >> >> > what
> >> >> >> > I’m
> >> >> >> > talking about as hard private. Soft private, at least as it
> >> >> >> > appe

Re: !Re: proposal: Object Members

2018-07-29 Thread Isiah Meadows
Um, no. The use case is *extremely* limited, and that ruins a few
optimizations you could otherwise make with private symbols (like
caching proxy forwarding without having to bail out).

Besides, whether a symbol is private requires exactly one bit to
store, so there's no real overhead with storing it on the object.
Heck, if you want to optimize it better, you might choose to store
that same bit on both the symbol and the object descriptor itself, and
I'd expect engines to do just that - it saves a pointer dereference.
-

Isiah Meadows
m...@isiahmeadows.com
www.isiahmeadows.com


On Mon, Jul 30, 2018 at 1:25 AM, Michael Theriot
 wrote:
> Also throwing this out there, symbols would now carry additional
> information: private or normal. Would it be better to configure this on
> objects instead?
>
> E.g. `Object.setPropertySymbolVisibility(object, symbol, true / false)`
>
> (and then ideally sugar for this)
>
> That way a symbol's visibility on an object is information held on the
> object rather than the primitive. A little more work involved, but lines up
> with Object.defineProperty and symbols remain purely unique identifiers.
>
> On Monday, July 30, 2018, Isiah Meadows  wrote:
>>
>> I'm aware it's possible to misuse, but if concerns of misuse were a
>> serious issue, we wouldn't have iterators, for example [1] [2]. But
>> IMHO freeing weak maps from a role they weren't designed for
>> substantially outweighs the risks of abusing them further (and the
>> abuses are incredibly frequent).
>>
>> [1]:
>> https://esdiscuss.org/topic/iterators-generators-finally-and-scarce-resources-was-april-10-2014-meeting-notes
>> [2]: https://esdiscuss.org/topic/resource-management
>>
>> -
>>
>> Isiah Meadows
>> m...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Sun, Jul 29, 2018 at 10:55 PM, Michael Theriot
>>  wrote:
>> > Right, I wouldn't, but I'm concerned others would misuse it. I don't
>> > think
>> > it's a blocker though, and actually frees weakmaps from trying to fill
>> > this
>> > role.
>> >
>> >
>> > On Sunday, July 29, 2018, Isiah Meadows  wrote:
>> >>
>> >> It will, but weak maps will still remain useful for cases when you're
>> >> semantically dealing with a key/value map. In theory, you could
>> >> implement a weak map on top of this [1], but in practice, it doesn't
>> >> always make sense to do it. A good example of this is if you are
>> >> "tagging" an object with data. If this data isn't really part of the
>> >> object itself, you shouldn't be using a private symbol for it. Another
>> >> good example is if you're doing simple caching and you need to clear
>> >> the weak map by replacing it. Using private symbols for this doesn't
>> >> really fit with the domain here, so you're more likely just to confuse
>> >> future readers (including yourself) if you do this.
>> >>
>> >> [1]:
>> >> https://gist.github.com/isiahmeadows/a8494868c4b193dfbf7139589f472ad8
>> >> -
>> >>
>> >> Isiah Meadows
>> >> m...@isiahmeadows.com
>> >> www.isiahmeadows.com
>> >>
>> >>
>> >> On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot
>> >>  wrote:
>> >> > Private symbols sounds like an easy win. They would be painfully
>> >> > simple,
>> >> > real properties, not just variables with property imitation syntax
>> >> > that
>> >> > undoubtedly confuses people. With the added benefit that children can
>> >> > truly
>> >> > override the base class, freedom to define private members shared
>> >> > across
>> >> > otherwise unrelated objects, and even injection. My only concern is
>> >> > that
>> >> > it
>> >> > could cross into WeakMap use cases.
>> >> >
>> >> >
>> >> > On Sunday, July 29, 2018, Isiah Meadows 
>> >> > wrote:
>> >> >>
>> >> >> BTW, I came up with an alternate proposal for privacy altogether:
>> >> >> https://github.com/tc39/proposal-class-fields/issues/115
>> >> >>
>> >> >> TL;DR: private symbols that proxies can't see and that can't be
>> >> >> enumerated.
>> >> >> -
>> >> >>
>> >> >> Isiah Meadows
>> >> >> m...@isiahmeadows.com
>> >> >> www.isiahmeadows.com
>> >> >>
>> >> >>
>> >> >> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
>> >> >>  wrote:
>> >> >> >> What you're essentially asking for is a violatable private field,
>> >> >> >> or
>> >> >> >> as
>> >> >> >> has been described by others, a "soft private".
>> >> >> >
>> >> >> > We might have different definitions here, but I would describe
>> >> >> > what
>> >> >> > I’m
>> >> >> > talking about as hard private. Soft private, at least as it
>> >> >> > appears
>> >> >> > to
>> >> >> > have
>> >> >> > been defined in [prior
>> >> >> >
>> >> >> >
>> >> >> > discussions](https://github.com/tc39/proposal-private-fields/issues/33),
>> >> >> > described an avenue where symbol keyed properties were given a new
>> >> >> > syntactic
>> >> >> > form — but they were still just regular symbol keys, and therefore
>> >> >> > could
>> >> >> > be
>> >> >> > introspected by outside agents who had not been given express
>> >> >> > privilege
>> >> >> > to
>> >>

Re: !Re: proposal: Object Members

2018-07-29 Thread Michael Theriot
Also throwing this out there, symbols would now carry additional
information: private or normal. Would it be better to configure this on
objects instead?

E.g. `Object.setPropertySymbolVisibility(object, symbol, true / false)`

(and then ideally sugar for this)

That way a symbol's visibility on an object is information held on the
object rather than the primitive. A little more work involved, but lines up
with Object.defineProperty and symbols remain purely unique identifiers.

On Monday, July 30, 2018, Isiah Meadows  wrote:

> I'm aware it's possible to misuse, but if concerns of misuse were a
> serious issue, we wouldn't have iterators, for example [1] [2]. But
> IMHO freeing weak maps from a role they weren't designed for
> substantially outweighs the risks of abusing them further (and the
> abuses are incredibly frequent).
>
> [1]: https://esdiscuss.org/topic/iterators-generators-finally-
> and-scarce-resources-was-april-10-2014-meeting-notes
> [2]: https://esdiscuss.org/topic/resource-management
>
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Sun, Jul 29, 2018 at 10:55 PM, Michael Theriot
>  wrote:
> > Right, I wouldn't, but I'm concerned others would misuse it. I don't
> think
> > it's a blocker though, and actually frees weakmaps from trying to fill
> this
> > role.
> >
> >
> > On Sunday, July 29, 2018, Isiah Meadows  wrote:
> >>
> >> It will, but weak maps will still remain useful for cases when you're
> >> semantically dealing with a key/value map. In theory, you could
> >> implement a weak map on top of this [1], but in practice, it doesn't
> >> always make sense to do it. A good example of this is if you are
> >> "tagging" an object with data. If this data isn't really part of the
> >> object itself, you shouldn't be using a private symbol for it. Another
> >> good example is if you're doing simple caching and you need to clear
> >> the weak map by replacing it. Using private symbols for this doesn't
> >> really fit with the domain here, so you're more likely just to confuse
> >> future readers (including yourself) if you do this.
> >>
> >> [1]: https://gist.github.com/isiahmeadows/
> a8494868c4b193dfbf7139589f472ad8
> >> -
> >>
> >> Isiah Meadows
> >> m...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot
> >>  wrote:
> >> > Private symbols sounds like an easy win. They would be painfully
> simple,
> >> > real properties, not just variables with property imitation syntax
> that
> >> > undoubtedly confuses people. With the added benefit that children can
> >> > truly
> >> > override the base class, freedom to define private members shared
> across
> >> > otherwise unrelated objects, and even injection. My only concern is
> that
> >> > it
> >> > could cross into WeakMap use cases.
> >> >
> >> >
> >> > On Sunday, July 29, 2018, Isiah Meadows 
> wrote:
> >> >>
> >> >> BTW, I came up with an alternate proposal for privacy altogether:
> >> >> https://github.com/tc39/proposal-class-fields/issues/115
> >> >>
> >> >> TL;DR: private symbols that proxies can't see and that can't be
> >> >> enumerated.
> >> >> -
> >> >>
> >> >> Isiah Meadows
> >> >> m...@isiahmeadows.com
> >> >> www.isiahmeadows.com
> >> >>
> >> >>
> >> >> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
> >> >>  wrote:
> >> >> >> What you're essentially asking for is a violatable private field,
> or
> >> >> >> as
> >> >> >> has been described by others, a "soft private".
> >> >> >
> >> >> > We might have different definitions here, but I would describe what
> >> >> > I’m
> >> >> > talking about as hard private. Soft private, at least as it appears
> >> >> > to
> >> >> > have
> >> >> > been defined in [prior
> >> >> >
> >> >> > discussions](https://github.com/tc39/proposal-private-
> fields/issues/33),
> >> >> > described an avenue where symbol keyed properties were given a new
> >> >> > syntactic
> >> >> > form — but they were still just regular symbol keys, and therefore
> >> >> > could
> >> >> > be
> >> >> > introspected by outside agents who had not been given express
> >> >> > privilege
> >> >> > to
> >> >> > do so:
> >> >> >
> >> >> >> [...] the core would be that "private state" is simply (public)
> >> >> >> symbol-named properties, with syntactic sugar for those symbols,
> and
> >> >> >> possibly some kind of introspection over them [...]
> >> >> >
> >> >> > The thread goes on to contrast the soft model with an earlier
> version
> >> >> > of
> >> >> > the
> >> >> > private fields proposal seen today. The hard private example uses
> the
> >> >> > class
> >> >> > declaration as a pseudo-scope, but contrasting these two options as
> >> >> > if
> >> >> > they
> >> >> > are binary is not accurate: hard private through
> >> >> > module/function/block
> >> >> > scope
> >> >> > already exists, it is just difficult to work with in the context of
> >> >> > shared
> >> >> > prototypes — one must either use WeakMaps, technically giving
> >>

Re: !Re: proposal: Object Members

2018-07-29 Thread Isiah Meadows
I'm aware it's possible to misuse, but if concerns of misuse were a
serious issue, we wouldn't have iterators, for example [1] [2]. But
IMHO freeing weak maps from a role they weren't designed for
substantially outweighs the risks of abusing them further (and the
abuses are incredibly frequent).

[1]: 
https://esdiscuss.org/topic/iterators-generators-finally-and-scarce-resources-was-april-10-2014-meeting-notes
[2]: https://esdiscuss.org/topic/resource-management

-

Isiah Meadows
m...@isiahmeadows.com
www.isiahmeadows.com


On Sun, Jul 29, 2018 at 10:55 PM, Michael Theriot
 wrote:
> Right, I wouldn't, but I'm concerned others would misuse it. I don't think
> it's a blocker though, and actually frees weakmaps from trying to fill this
> role.
>
>
> On Sunday, July 29, 2018, Isiah Meadows  wrote:
>>
>> It will, but weak maps will still remain useful for cases when you're
>> semantically dealing with a key/value map. In theory, you could
>> implement a weak map on top of this [1], but in practice, it doesn't
>> always make sense to do it. A good example of this is if you are
>> "tagging" an object with data. If this data isn't really part of the
>> object itself, you shouldn't be using a private symbol for it. Another
>> good example is if you're doing simple caching and you need to clear
>> the weak map by replacing it. Using private symbols for this doesn't
>> really fit with the domain here, so you're more likely just to confuse
>> future readers (including yourself) if you do this.
>>
>> [1]: https://gist.github.com/isiahmeadows/a8494868c4b193dfbf7139589f472ad8
>> -
>>
>> Isiah Meadows
>> m...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot
>>  wrote:
>> > Private symbols sounds like an easy win. They would be painfully simple,
>> > real properties, not just variables with property imitation syntax that
>> > undoubtedly confuses people. With the added benefit that children can
>> > truly
>> > override the base class, freedom to define private members shared across
>> > otherwise unrelated objects, and even injection. My only concern is that
>> > it
>> > could cross into WeakMap use cases.
>> >
>> >
>> > On Sunday, July 29, 2018, Isiah Meadows  wrote:
>> >>
>> >> BTW, I came up with an alternate proposal for privacy altogether:
>> >> https://github.com/tc39/proposal-class-fields/issues/115
>> >>
>> >> TL;DR: private symbols that proxies can't see and that can't be
>> >> enumerated.
>> >> -
>> >>
>> >> Isiah Meadows
>> >> m...@isiahmeadows.com
>> >> www.isiahmeadows.com
>> >>
>> >>
>> >> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
>> >>  wrote:
>> >> >> What you're essentially asking for is a violatable private field, or
>> >> >> as
>> >> >> has been described by others, a "soft private".
>> >> >
>> >> > We might have different definitions here, but I would describe what
>> >> > I’m
>> >> > talking about as hard private. Soft private, at least as it appears
>> >> > to
>> >> > have
>> >> > been defined in [prior
>> >> >
>> >> > discussions](https://github.com/tc39/proposal-private-fields/issues/33),
>> >> > described an avenue where symbol keyed properties were given a new
>> >> > syntactic
>> >> > form — but they were still just regular symbol keys, and therefore
>> >> > could
>> >> > be
>> >> > introspected by outside agents who had not been given express
>> >> > privilege
>> >> > to
>> >> > do so:
>> >> >
>> >> >> [...] the core would be that "private state" is simply (public)
>> >> >> symbol-named properties, with syntactic sugar for those symbols, and
>> >> >> possibly some kind of introspection over them [...]
>> >> >
>> >> > The thread goes on to contrast the soft model with an earlier version
>> >> > of
>> >> > the
>> >> > private fields proposal seen today. The hard private example uses the
>> >> > class
>> >> > declaration as a pseudo-scope, but contrasting these two options as
>> >> > if
>> >> > they
>> >> > are binary is not accurate: hard private through
>> >> > module/function/block
>> >> > scope
>> >> > already exists, it is just difficult to work with in the context of
>> >> > shared
>> >> > prototypes — one must either use WeakMaps, technically giving
>> >> > _hardness_
>> >> > because of the forgeability of `global.WeakMap` / `WeakMap.prototype`
>> >> > /
>> >> > `WeakMap.prototype.get|has|set`, or be willing to either not worry
>> >> > about
>> >> > garbage collection or implement it manually. This could be solved for
>> >> > with a
>> >> > few rather undramatic changes, though.
>> >> >
>> >> > Notably, the first post there lists the following as a disadvantage
>> >> > of
>> >> > the
>> >> > soft model it describes:
>> >> >
>> >> >> Platform objects, both within ECMAScript and in embedding
>> >> >> environments,
>> >> >> contain hard private state. If a library wants to be high-fidelity
>> >> >> and
>> >> >> just
>> >> >> like a platform object, soft-private state does not provide this
>> >> >> (@domenic)
>> >> >
>> >> >

Re: !Re: proposal: Object Members

2018-07-29 Thread Michael Theriot
Right, I wouldn't, but I'm concerned others would misuse it. I don't think
it's a blocker though, and actually frees weakmaps from trying to fill this
role.

On Sunday, July 29, 2018, Isiah Meadows  wrote:

> It will, but weak maps will still remain useful for cases when you're
> semantically dealing with a key/value map. In theory, you could
> implement a weak map on top of this [1], but in practice, it doesn't
> always make sense to do it. A good example of this is if you are
> "tagging" an object with data. If this data isn't really part of the
> object itself, you shouldn't be using a private symbol for it. Another
> good example is if you're doing simple caching and you need to clear
> the weak map by replacing it. Using private symbols for this doesn't
> really fit with the domain here, so you're more likely just to confuse
> future readers (including yourself) if you do this.
>
> [1]: https://gist.github.com/isiahmeadows/a8494868c4b193dfbf7139589f472ad8
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot
>  wrote:
> > Private symbols sounds like an easy win. They would be painfully simple,
> > real properties, not just variables with property imitation syntax that
> > undoubtedly confuses people. With the added benefit that children can
> truly
> > override the base class, freedom to define private members shared across
> > otherwise unrelated objects, and even injection. My only concern is that
> it
> > could cross into WeakMap use cases.
> >
> >
> > On Sunday, July 29, 2018, Isiah Meadows  wrote:
> >>
> >> BTW, I came up with an alternate proposal for privacy altogether:
> >> https://github.com/tc39/proposal-class-fields/issues/115
> >>
> >> TL;DR: private symbols that proxies can't see and that can't be
> >> enumerated.
> >> -
> >>
> >> Isiah Meadows
> >> m...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
> >>  wrote:
> >> >> What you're essentially asking for is a violatable private field, or
> as
> >> >> has been described by others, a "soft private".
> >> >
> >> > We might have different definitions here, but I would describe what
> I’m
> >> > talking about as hard private. Soft private, at least as it appears to
> >> > have
> >> > been defined in [prior
> >> > discussions](https://github.com/tc39/proposal-private-
> fields/issues/33),
> >> > described an avenue where symbol keyed properties were given a new
> >> > syntactic
> >> > form — but they were still just regular symbol keys, and therefore
> could
> >> > be
> >> > introspected by outside agents who had not been given express
> privilege
> >> > to
> >> > do so:
> >> >
> >> >> [...] the core would be that "private state" is simply (public)
> >> >> symbol-named properties, with syntactic sugar for those symbols, and
> >> >> possibly some kind of introspection over them [...]
> >> >
> >> > The thread goes on to contrast the soft model with an earlier version
> of
> >> > the
> >> > private fields proposal seen today. The hard private example uses the
> >> > class
> >> > declaration as a pseudo-scope, but contrasting these two options as if
> >> > they
> >> > are binary is not accurate: hard private through module/function/block
> >> > scope
> >> > already exists, it is just difficult to work with in the context of
> >> > shared
> >> > prototypes — one must either use WeakMaps, technically giving
> _hardness_
> >> > because of the forgeability of `global.WeakMap` / `WeakMap.prototype`
> /
> >> > `WeakMap.prototype.get|has|set`, or be willing to either not worry
> about
> >> > garbage collection or implement it manually. This could be solved for
> >> > with a
> >> > few rather undramatic changes, though.
> >> >
> >> > Notably, the first post there lists the following as a disadvantage of
> >> > the
> >> > soft model it describes:
> >> >
> >> >> Platform objects, both within ECMAScript and in embedding
> environments,
> >> >> contain hard private state. If a library wants to be high-fidelity
> and
> >> >> just
> >> >> like a platform object, soft-private state does not provide this
> >> >> (@domenic)
> >> >
> >> > ...but neither model there quite covers that use case. Platform
> objects
> >> > _can_ see each other’s private state (cf the `isView` example earlier,
> >> > or
> >> > scan the DOM API specs / Chrome source a bit to find numerous
> examples).
> >> > It’s only the ES layer interacting with their interfaces that cannot.
> >> >
> >> > Such things can be achieved with ordinary scope, which is why the
> >> > WeakMap
> >> > pattern has worked in practice in my experience to date, while
> >> > class-declaration-scoped privacy has not. It isn’t uncommon for a
> >> > library’s
> >> > exposed interface to be composed of an object graph, where privacy is
> a
> >> > concern at this public interface level, but library internal state may
> >> > be
> >> > interconnected in unexposed ways under the hood. Th

Re: !Re: proposal: Object Members

2018-07-29 Thread Isiah Meadows
It will, but weak maps will still remain useful for cases when you're
semantically dealing with a key/value map. In theory, you could
implement a weak map on top of this [1], but in practice, it doesn't
always make sense to do it. A good example of this is if you are
"tagging" an object with data. If this data isn't really part of the
object itself, you shouldn't be using a private symbol for it. Another
good example is if you're doing simple caching and you need to clear
the weak map by replacing it. Using private symbols for this doesn't
really fit with the domain here, so you're more likely just to confuse
future readers (including yourself) if you do this.

[1]: https://gist.github.com/isiahmeadows/a8494868c4b193dfbf7139589f472ad8
-

Isiah Meadows
m...@isiahmeadows.com
www.isiahmeadows.com


On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot
 wrote:
> Private symbols sounds like an easy win. They would be painfully simple,
> real properties, not just variables with property imitation syntax that
> undoubtedly confuses people. With the added benefit that children can truly
> override the base class, freedom to define private members shared across
> otherwise unrelated objects, and even injection. My only concern is that it
> could cross into WeakMap use cases.
>
>
> On Sunday, July 29, 2018, Isiah Meadows  wrote:
>>
>> BTW, I came up with an alternate proposal for privacy altogether:
>> https://github.com/tc39/proposal-class-fields/issues/115
>>
>> TL;DR: private symbols that proxies can't see and that can't be
>> enumerated.
>> -
>>
>> Isiah Meadows
>> m...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
>>  wrote:
>> >> What you're essentially asking for is a violatable private field, or as
>> >> has been described by others, a "soft private".
>> >
>> > We might have different definitions here, but I would describe what I’m
>> > talking about as hard private. Soft private, at least as it appears to
>> > have
>> > been defined in [prior
>> > discussions](https://github.com/tc39/proposal-private-fields/issues/33),
>> > described an avenue where symbol keyed properties were given a new
>> > syntactic
>> > form — but they were still just regular symbol keys, and therefore could
>> > be
>> > introspected by outside agents who had not been given express privilege
>> > to
>> > do so:
>> >
>> >> [...] the core would be that "private state" is simply (public)
>> >> symbol-named properties, with syntactic sugar for those symbols, and
>> >> possibly some kind of introspection over them [...]
>> >
>> > The thread goes on to contrast the soft model with an earlier version of
>> > the
>> > private fields proposal seen today. The hard private example uses the
>> > class
>> > declaration as a pseudo-scope, but contrasting these two options as if
>> > they
>> > are binary is not accurate: hard private through module/function/block
>> > scope
>> > already exists, it is just difficult to work with in the context of
>> > shared
>> > prototypes — one must either use WeakMaps, technically giving _hardness_
>> > because of the forgeability of `global.WeakMap` / `WeakMap.prototype` /
>> > `WeakMap.prototype.get|has|set`, or be willing to either not worry about
>> > garbage collection or implement it manually. This could be solved for
>> > with a
>> > few rather undramatic changes, though.
>> >
>> > Notably, the first post there lists the following as a disadvantage of
>> > the
>> > soft model it describes:
>> >
>> >> Platform objects, both within ECMAScript and in embedding environments,
>> >> contain hard private state. If a library wants to be high-fidelity and
>> >> just
>> >> like a platform object, soft-private state does not provide this
>> >> (@domenic)
>> >
>> > ...but neither model there quite covers that use case. Platform objects
>> > _can_ see each other’s private state (cf the `isView` example earlier,
>> > or
>> > scan the DOM API specs / Chrome source a bit to find numerous examples).
>> > It’s only the ES layer interacting with their interfaces that cannot.
>> >
>> > Such things can be achieved with ordinary scope, which is why the
>> > WeakMap
>> > pattern has worked in practice in my experience to date, while
>> > class-declaration-scoped privacy has not. It isn’t uncommon for a
>> > library’s
>> > exposed interface to be composed of an object graph, where privacy is a
>> > concern at this public interface level, but library internal state may
>> > be
>> > interconnected in unexposed ways under the hood. The most familiar
>> > example
>> > of this is a DOM node tree. As an experiment, perhaps try to implement
>> > the
>> > relationships between HTMLFormElement, HTMLFormControlsCollection and
>> > the
>> > various form control elements using either the main private fields
>> > proposal
>> > or your alternative proposal and see what happens.
>> >
>> >> However, the guardian logic tries to verify that the function trying to
>> >> access the private fi

Re: !Re: proposal: Object Members

2018-07-29 Thread Michael Theriot
Private symbols sounds like an easy win. They would be painfully simple,
real properties, not just variables with property imitation syntax that
undoubtedly confuses people. With the added benefit that children can truly
override the base class, freedom to define private members shared across
otherwise unrelated objects, and even injection. My only concern is that it
could cross into WeakMap use cases.

On Sunday, July 29, 2018, Isiah Meadows  wrote:

> BTW, I came up with an alternate proposal for privacy altogether:
> https://github.com/tc39/proposal-class-fields/issues/115
>
> TL;DR: private symbols that proxies can't see and that can't be enumerated.
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
>  wrote:
> >> What you're essentially asking for is a violatable private field, or as
> >> has been described by others, a "soft private".
> >
> > We might have different definitions here, but I would describe what I’m
> > talking about as hard private. Soft private, at least as it appears to
> have
> > been defined in [prior
> > discussions](https://github.com/tc39/proposal-private-fields/issues/33),
> > described an avenue where symbol keyed properties were given a new
> syntactic
> > form — but they were still just regular symbol keys, and therefore could
> be
> > introspected by outside agents who had not been given express privilege
> to
> > do so:
> >
> >> [...] the core would be that "private state" is simply (public)
> >> symbol-named properties, with syntactic sugar for those symbols, and
> >> possibly some kind of introspection over them [...]
> >
> > The thread goes on to contrast the soft model with an earlier version of
> the
> > private fields proposal seen today. The hard private example uses the
> class
> > declaration as a pseudo-scope, but contrasting these two options as if
> they
> > are binary is not accurate: hard private through module/function/block
> scope
> > already exists, it is just difficult to work with in the context of
> shared
> > prototypes — one must either use WeakMaps, technically giving _hardness_
> > because of the forgeability of `global.WeakMap` / `WeakMap.prototype` /
> > `WeakMap.prototype.get|has|set`, or be willing to either not worry about
> > garbage collection or implement it manually. This could be solved for
> with a
> > few rather undramatic changes, though.
> >
> > Notably, the first post there lists the following as a disadvantage of
> the
> > soft model it describes:
> >
> >> Platform objects, both within ECMAScript and in embedding environments,
> >> contain hard private state. If a library wants to be high-fidelity and
> just
> >> like a platform object, soft-private state does not provide this
> (@domenic)
> >
> > ...but neither model there quite covers that use case. Platform objects
> > _can_ see each other’s private state (cf the `isView` example earlier, or
> > scan the DOM API specs / Chrome source a bit to find numerous examples).
> > It’s only the ES layer interacting with their interfaces that cannot.
> >
> > Such things can be achieved with ordinary scope, which is why the WeakMap
> > pattern has worked in practice in my experience to date, while
> > class-declaration-scoped privacy has not. It isn’t uncommon for a
> library’s
> > exposed interface to be composed of an object graph, where privacy is a
> > concern at this public interface level, but library internal state may be
> > interconnected in unexposed ways under the hood. The most familiar
> example
> > of this is a DOM node tree. As an experiment, perhaps try to implement
> the
> > relationships between HTMLFormElement, HTMLFormControlsCollection and the
> > various form control elements using either the main private fields
> proposal
> > or your alternative proposal and see what happens.
> >
> >> However, the guardian logic tries to verify that the function trying to
> >> access the private fields of an instance is a member of the same or
> >> descending prototype that was used to create that instance.
> >
> > Because I’m looking at this in terms of slots, I’d first point out that
> > prototypes don’t determine slottedness, the execution of some specific
> > constructor does. It’s during this process that slots are associated with
> > the newly minted object by its identity. But even the current private
> fields
> > proposal tracks this behavior closely, and I’m not sure how else it could
> > work. The [[Prototype]] slot of an object is typically mutable
> > (`R|O.setPrototypeOf`, `__proto__`) and forgeable (Proxy’s
> `getPrototypeOf`
> > trap). Why/how would its value matter when it comes to accessing private
> > state?
> >
> > ```js
> > const pattern = /foo/;
> > Reflect.setPrototypeOf(pattern, Date.prototype);
> > pattern instanceof Date; // true
> > pattern instanceof RegExp; // false
> > pattern.getMinutes(); // throws TypeError because [[DateValue]] slot is
> > missing
> > RegExp.prototype.exec.c

Re: !Re: proposal: Object Members

2018-07-29 Thread Isiah Meadows
1. I don't believe tampering is a major issue, especially considering
most tampering problems occur *after* the type is instantiated. If it
is, the follow-on proposal of added syntax would likely avoid it.
2. The prototype part is just for consistency and code reuse. And it's
not about the object it's associated, but about the key lookup itself.

-

Isiah Meadows
m...@isiahmeadows.com
www.isiahmeadows.com


On Sun, Jul 29, 2018 at 8:00 PM, Darien Valentine  wrote:
> Isaiah, that’s pretty similar to what I was [talking about
> earlier](https://mail.mozilla.org/pipermail/es-discuss/2018-July/051410.html)
> — and I think it’s awesome that multiple people have arrived there, since it
> seems like soft confirmation of the idea that private symbols likely
> represent the most minimal possible “surgery” to achieve the functionality.
>
> There are some differences; I saw `Symbol.private` as an obvious API too,
> but specifically mentioned it to point out that it’s not viable if we
> consider one of the goals here to be the elimination of the
> “tamperability-hole” that exists for any non-syntactic solution (unless
> global.Symbol is redefined as non-configurable, non-writable, etc, but this
> is likely not an option).
>
> The proxy forwarding is _very_ interesting, but the prototype lookup doesn’t
> make sense to me. Slots/fields are associated with _an_ object, not subject
> to the vagaries of that object’s present prototype chain. I don’t think
> changing that relationship is a good idea.
>
> On Sun, Jul 29, 2018 at 7:38 PM Isiah Meadows 
> wrote:
>>
>> BTW, I came up with an alternate proposal for privacy altogether:
>> https://github.com/tc39/proposal-class-fields/issues/115
>>
>> TL;DR: private symbols that proxies can't see and that can't be
>> enumerated.
>> -
>>
>> Isiah Meadows
>> m...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
>>  wrote:
>> >> What you're essentially asking for is a violatable private field, or as
>> >> has been described by others, a "soft private".
>> >
>> > We might have different definitions here, but I would describe what I’m
>> > talking about as hard private. Soft private, at least as it appears to
>> > have
>> > been defined in [prior
>> > discussions](https://github.com/tc39/proposal-private-fields/issues/33),
>> > described an avenue where symbol keyed properties were given a new
>> > syntactic
>> > form — but they were still just regular symbol keys, and therefore could
>> > be
>> > introspected by outside agents who had not been given express privilege
>> > to
>> > do so:
>> >
>> >> [...] the core would be that "private state" is simply (public)
>> >> symbol-named properties, with syntactic sugar for those symbols, and
>> >> possibly some kind of introspection over them [...]
>> >
>> > The thread goes on to contrast the soft model with an earlier version of
>> > the
>> > private fields proposal seen today. The hard private example uses the
>> > class
>> > declaration as a pseudo-scope, but contrasting these two options as if
>> > they
>> > are binary is not accurate: hard private through module/function/block
>> > scope
>> > already exists, it is just difficult to work with in the context of
>> > shared
>> > prototypes — one must either use WeakMaps, technically giving _hardness_
>> > because of the forgeability of `global.WeakMap` / `WeakMap.prototype` /
>> > `WeakMap.prototype.get|has|set`, or be willing to either not worry about
>> > garbage collection or implement it manually. This could be solved for
>> > with a
>> > few rather undramatic changes, though.
>> >
>> > Notably, the first post there lists the following as a disadvantage of
>> > the
>> > soft model it describes:
>> >
>> >> Platform objects, both within ECMAScript and in embedding environments,
>> >> contain hard private state. If a library wants to be high-fidelity and
>> >> just
>> >> like a platform object, soft-private state does not provide this
>> >> (@domenic)
>> >
>> > ...but neither model there quite covers that use case. Platform objects
>> > _can_ see each other’s private state (cf the `isView` example earlier,
>> > or
>> > scan the DOM API specs / Chrome source a bit to find numerous examples).
>> > It’s only the ES layer interacting with their interfaces that cannot.
>> >
>> > Such things can be achieved with ordinary scope, which is why the
>> > WeakMap
>> > pattern has worked in practice in my experience to date, while
>> > class-declaration-scoped privacy has not. It isn’t uncommon for a
>> > library’s
>> > exposed interface to be composed of an object graph, where privacy is a
>> > concern at this public interface level, but library internal state may
>> > be
>> > interconnected in unexposed ways under the hood. The most familiar
>> > example
>> > of this is a DOM node tree. As an experiment, perhaps try to implement
>> > the
>> > relationships between HTMLFormElement, HTMLFormControlsCollection and
>> > the
>> > various form con

Re: !Re: proposal: Object Members

2018-07-29 Thread Darien Valentine
Isaiah, that’s pretty similar to what I was [talking about earlier](
https://mail.mozilla.org/pipermail/es-discuss/2018-July/051410.html) — and
I think it’s awesome that multiple people have arrived there, since it
seems like soft confirmation of the idea that private symbols likely
represent the most minimal possible “surgery” to achieve the functionality.

There are some differences; I saw `Symbol.private` as an obvious API too,
but specifically mentioned it to point out that it’s not viable if we
consider one of the goals here to be the elimination of the
“tamperability-hole” that exists for any non-syntactic solution (unless
global.Symbol is redefined as non-configurable, non-writable, etc, but this
is likely not an option).

The proxy forwarding is _very_ interesting, but the prototype lookup
doesn’t make sense to me. Slots/fields are associated with _an_ object, not
subject to the vagaries of that object’s present prototype chain. I don’t
think changing that relationship is a good idea.

On Sun, Jul 29, 2018 at 7:38 PM Isiah Meadows 
wrote:

> BTW, I came up with an alternate proposal for privacy altogether:
> https://github.com/tc39/proposal-class-fields/issues/115
>
> TL;DR: private symbols that proxies can't see and that can't be enumerated.
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
>  wrote:
> >> What you're essentially asking for is a violatable private field, or as
> >> has been described by others, a "soft private".
> >
> > We might have different definitions here, but I would describe what I’m
> > talking about as hard private. Soft private, at least as it appears to
> have
> > been defined in [prior
> > discussions](https://github.com/tc39/proposal-private-fields/issues/33),
> > described an avenue where symbol keyed properties were given a new
> syntactic
> > form — but they were still just regular symbol keys, and therefore could
> be
> > introspected by outside agents who had not been given express privilege
> to
> > do so:
> >
> >> [...] the core would be that "private state" is simply (public)
> >> symbol-named properties, with syntactic sugar for those symbols, and
> >> possibly some kind of introspection over them [...]
> >
> > The thread goes on to contrast the soft model with an earlier version of
> the
> > private fields proposal seen today. The hard private example uses the
> class
> > declaration as a pseudo-scope, but contrasting these two options as if
> they
> > are binary is not accurate: hard private through module/function/block
> scope
> > already exists, it is just difficult to work with in the context of
> shared
> > prototypes — one must either use WeakMaps, technically giving _hardness_
> > because of the forgeability of `global.WeakMap` / `WeakMap.prototype` /
> > `WeakMap.prototype.get|has|set`, or be willing to either not worry about
> > garbage collection or implement it manually. This could be solved for
> with a
> > few rather undramatic changes, though.
> >
> > Notably, the first post there lists the following as a disadvantage of
> the
> > soft model it describes:
> >
> >> Platform objects, both within ECMAScript and in embedding environments,
> >> contain hard private state. If a library wants to be high-fidelity and
> just
> >> like a platform object, soft-private state does not provide this
> (@domenic)
> >
> > ...but neither model there quite covers that use case. Platform objects
> > _can_ see each other’s private state (cf the `isView` example earlier, or
> > scan the DOM API specs / Chrome source a bit to find numerous examples).
> > It’s only the ES layer interacting with their interfaces that cannot.
> >
> > Such things can be achieved with ordinary scope, which is why the WeakMap
> > pattern has worked in practice in my experience to date, while
> > class-declaration-scoped privacy has not. It isn’t uncommon for a
> library’s
> > exposed interface to be composed of an object graph, where privacy is a
> > concern at this public interface level, but library internal state may be
> > interconnected in unexposed ways under the hood. The most familiar
> example
> > of this is a DOM node tree. As an experiment, perhaps try to implement
> the
> > relationships between HTMLFormElement, HTMLFormControlsCollection and the
> > various form control elements using either the main private fields
> proposal
> > or your alternative proposal and see what happens.
> >
> >> However, the guardian logic tries to verify that the function trying to
> >> access the private fields of an instance is a member of the same or
> >> descending prototype that was used to create that instance.
> >
> > Because I’m looking at this in terms of slots, I’d first point out that
> > prototypes don’t determine slottedness, the execution of some specific
> > constructor does. It’s during this process that slots are associated with
> > the newly minted object by its identity. But even the current private
> 

Re: !Re: proposal: Object Members

2018-07-29 Thread Ranando King
Let me see if I can roll this up: you're looking for syntax support for
something akin to Java and C#'s "internal" privilege level, and a means to
declare a "common private name" so that something like this will work:

```js
var {A, B, C} = (() => {
  static common = Symbol("common");

  class A {
internal [common] = 1;
sum(...arg) {
  var retval = this#[common];
  for (let obj of arg) {
retval += obj#[common];
  }
  return retval;
}
  }

  class B {
internal [common] = 2;
sum(...arg) {
  var retval = this#[common];
  for (let obj of arg) {
retval += obj#[common];
  }
  return retval;
}
  }

  class C {
internal [common] = 3;
sum(...arg) {
  var retval = this#[common];
  for (let obj of arg) {
retval += obj#[common];
  }
  return retval;
}
  }

  return { A, B, C };
})();

(new A()).sum(new B(), new C()); //If it works, returns 6
```

It's already the case that A, B, & C will have to include the
`[[DeclarationInfo]]` of the arrow function in each of their respective
methods' `__proto__` chains. That and the `Symbol` for direct use as a
private name, solves the problem, and avoids the original issue without
much of a change. The "internal" keyword would be trickier to implement as
it would require that the corresponding declarations be added to the
`[[DeclarationInfo]]` of the containing scope while the storage exists in
the `[[PrivateValues]]` of the owning objects. It's not impossible,
possibly not even difficult. I'll have to give it some thought.


On Sat, Jul 28, 2018 at 11:24 PM Darien Valentine 
wrote:

> > What you're essentially asking for is a violatable private field, or as
> has been described by others, a "soft private".
>
> We might have different definitions here, but I would describe what I’m
> talking about as hard private. Soft private, at least as it appears to have
> been defined in [prior discussions](
> https://github.com/tc39/proposal-private-fields/issues/33), described an
> avenue where symbol keyed properties were given a new syntactic form — but
> they were still just regular symbol keys, and therefore could be
> introspected by outside agents who had not been given express privilege to
> do so:
>
> > [...] the core would be that "private state" is simply (public)
> symbol-named properties, with syntactic sugar for those symbols, and
> possibly some kind of introspection over them [...]
>
> The thread goes on to contrast the soft model with an earlier version of
> the private fields proposal seen today. The hard private example uses the
> class declaration as a pseudo-scope, but contrasting these two options as
> if they are binary is not accurate: hard private through
> module/function/block scope already exists, it is just difficult to work
> with in the context of shared prototypes — one must either use WeakMaps,
> technically giving _hardness_ because of the forgeability of
> `global.WeakMap` / `WeakMap.prototype` / `WeakMap.prototype.get|has|set`,
> or be willing to either not worry about garbage collection or implement it
> manually. This could be solved for with a few rather undramatic changes,
> though.
>
> Notably, the first post there lists the following as a disadvantage of the
> soft model it describes:
>
> > Platform objects, both within ECMAScript and in embedding environments,
> contain hard private state. If a library wants to be high-fidelity and just
> like a platform object, soft-private state does not provide this (@domenic)
>
> ...but neither model there quite covers that use case. Platform objects
> _can_ see each other’s private state (cf the `isView` example earlier, or
> scan the DOM API specs / Chrome source a bit to find numerous examples).
> It’s only the ES layer interacting with their interfaces that cannot.
>
> Such things can be achieved with ordinary scope, which is why the WeakMap
> pattern has worked in practice in my experience to date, while
> class-declaration-scoped privacy has not. It isn’t uncommon for a library’s
> exposed interface to be composed of an object graph, where privacy is a
> concern at this public interface level, but library internal state may be
> interconnected in unexposed ways under the hood. The most familiar example
> of this is a DOM node tree. As an experiment, perhaps try to implement the
> relationships between HTMLFormElement, HTMLFormControlsCollection and the
> various form control elements using either the main private fields proposal
> or your alternative proposal and see what happens.
>
> > However, the guardian logic tries to verify that the function trying to
> access the private fields of an instance is a member of the same or
> descending prototype that was used to create that instance.
>
> Because I’m looking at this in terms of slots, I’d first point out that
> prototypes don’t determine slottedness, the execution of some specific
> constructor does. It’s during this process that slots are associat

Re: !Re: proposal: Object Members

2018-07-29 Thread Isiah Meadows
BTW, I came up with an alternate proposal for privacy altogether:
https://github.com/tc39/proposal-class-fields/issues/115

TL;DR: private symbols that proxies can't see and that can't be enumerated.
-

Isiah Meadows
m...@isiahmeadows.com
www.isiahmeadows.com


On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
 wrote:
>> What you're essentially asking for is a violatable private field, or as
>> has been described by others, a "soft private".
>
> We might have different definitions here, but I would describe what I’m
> talking about as hard private. Soft private, at least as it appears to have
> been defined in [prior
> discussions](https://github.com/tc39/proposal-private-fields/issues/33),
> described an avenue where symbol keyed properties were given a new syntactic
> form — but they were still just regular symbol keys, and therefore could be
> introspected by outside agents who had not been given express privilege to
> do so:
>
>> [...] the core would be that "private state" is simply (public)
>> symbol-named properties, with syntactic sugar for those symbols, and
>> possibly some kind of introspection over them [...]
>
> The thread goes on to contrast the soft model with an earlier version of the
> private fields proposal seen today. The hard private example uses the class
> declaration as a pseudo-scope, but contrasting these two options as if they
> are binary is not accurate: hard private through module/function/block scope
> already exists, it is just difficult to work with in the context of shared
> prototypes — one must either use WeakMaps, technically giving _hardness_
> because of the forgeability of `global.WeakMap` / `WeakMap.prototype` /
> `WeakMap.prototype.get|has|set`, or be willing to either not worry about
> garbage collection or implement it manually. This could be solved for with a
> few rather undramatic changes, though.
>
> Notably, the first post there lists the following as a disadvantage of the
> soft model it describes:
>
>> Platform objects, both within ECMAScript and in embedding environments,
>> contain hard private state. If a library wants to be high-fidelity and just
>> like a platform object, soft-private state does not provide this (@domenic)
>
> ...but neither model there quite covers that use case. Platform objects
> _can_ see each other’s private state (cf the `isView` example earlier, or
> scan the DOM API specs / Chrome source a bit to find numerous examples).
> It’s only the ES layer interacting with their interfaces that cannot.
>
> Such things can be achieved with ordinary scope, which is why the WeakMap
> pattern has worked in practice in my experience to date, while
> class-declaration-scoped privacy has not. It isn’t uncommon for a library’s
> exposed interface to be composed of an object graph, where privacy is a
> concern at this public interface level, but library internal state may be
> interconnected in unexposed ways under the hood. The most familiar example
> of this is a DOM node tree. As an experiment, perhaps try to implement the
> relationships between HTMLFormElement, HTMLFormControlsCollection and the
> various form control elements using either the main private fields proposal
> or your alternative proposal and see what happens.
>
>> However, the guardian logic tries to verify that the function trying to
>> access the private fields of an instance is a member of the same or
>> descending prototype that was used to create that instance.
>
> Because I’m looking at this in terms of slots, I’d first point out that
> prototypes don’t determine slottedness, the execution of some specific
> constructor does. It’s during this process that slots are associated with
> the newly minted object by its identity. But even the current private fields
> proposal tracks this behavior closely, and I’m not sure how else it could
> work. The [[Prototype]] slot of an object is typically mutable
> (`R|O.setPrototypeOf`, `__proto__`) and forgeable (Proxy’s `getPrototypeOf`
> trap). Why/how would its value matter when it comes to accessing private
> state?
>
> ```js
> const pattern = /foo/;
> Reflect.setPrototypeOf(pattern, Date.prototype);
> pattern instanceof Date; // true
> pattern instanceof RegExp; // false
> pattern.getMinutes(); // throws TypeError because [[DateValue]] slot is
> missing
> RegExp.prototype.exec.call(pattern, 'foo'); // works; object has RegExp
> private slots
> ```
>
>> If I removed that requirement, it would work. However, there'd be no way
>> to keep the private data from being leaked. Sadly, it's all or nothing with
>> this approach. Hard private or soft private, those are the only choices.
>
> In the context of what you’ve described here this may be true, but no such
> limitation presently exists. We can already do all this — hard, leak-free
> privacy, brandedness, “friends” etc — with scopes and WeakMaps, but for the
> fact that the `WeakMap` intrinsics may be forged. So what’s baffled me is
> this: why are all the proposals exploring thi

Re: !Re: proposal: Object Members

2018-07-28 Thread Darien Valentine
> What you're essentially asking for is a violatable private field, or as
has been described by others, a "soft private".

We might have different definitions here, but I would describe what I’m
talking about as hard private. Soft private, at least as it appears to have
been defined in [prior discussions](
https://github.com/tc39/proposal-private-fields/issues/33), described an
avenue where symbol keyed properties were given a new syntactic form — but
they were still just regular symbol keys, and therefore could be
introspected by outside agents who had not been given express privilege to
do so:

> [...] the core would be that "private state" is simply (public)
symbol-named properties, with syntactic sugar for those symbols, and
possibly some kind of introspection over them [...]

The thread goes on to contrast the soft model with an earlier version of
the private fields proposal seen today. The hard private example uses the
class declaration as a pseudo-scope, but contrasting these two options as
if they are binary is not accurate: hard private through
module/function/block scope already exists, it is just difficult to work
with in the context of shared prototypes — one must either use WeakMaps,
technically giving _hardness_ because of the forgeability of
`global.WeakMap` / `WeakMap.prototype` / `WeakMap.prototype.get|has|set`,
or be willing to either not worry about garbage collection or implement it
manually. This could be solved for with a few rather undramatic changes,
though.

Notably, the first post there lists the following as a disadvantage of the
soft model it describes:

> Platform objects, both within ECMAScript and in embedding environments,
contain hard private state. If a library wants to be high-fidelity and just
like a platform object, soft-private state does not provide this (@domenic)

...but neither model there quite covers that use case. Platform objects
_can_ see each other’s private state (cf the `isView` example earlier, or
scan the DOM API specs / Chrome source a bit to find numerous examples).
It’s only the ES layer interacting with their interfaces that cannot.

Such things can be achieved with ordinary scope, which is why the WeakMap
pattern has worked in practice in my experience to date, while
class-declaration-scoped privacy has not. It isn’t uncommon for a library’s
exposed interface to be composed of an object graph, where privacy is a
concern at this public interface level, but library internal state may be
interconnected in unexposed ways under the hood. The most familiar example
of this is a DOM node tree. As an experiment, perhaps try to implement the
relationships between HTMLFormElement, HTMLFormControlsCollection and the
various form control elements using either the main private fields proposal
or your alternative proposal and see what happens.

> However, the guardian logic tries to verify that the function trying to
access the private fields of an instance is a member of the same or
descending prototype that was used to create that instance.

Because I’m looking at this in terms of slots, I’d first point out that
prototypes don’t determine slottedness, the execution of some specific
constructor does. It’s during this process that slots are associated with
the newly minted object by its identity. But even the current private
fields proposal tracks this behavior closely, and I’m not sure how else it
could work. The [[Prototype]] slot of an object is typically mutable
(`R|O.setPrototypeOf`, `__proto__`) and forgeable (Proxy’s `getPrototypeOf`
trap). Why/how would its value matter when it comes to accessing private
state?

```js
const pattern = /foo/;
Reflect.setPrototypeOf(pattern, Date.prototype);
pattern instanceof Date; // true
pattern instanceof RegExp; // false
pattern.getMinutes(); // throws TypeError because [[DateValue]] slot is
missing
RegExp.prototype.exec.call(pattern, 'foo'); // works; object has RegExp
private slots
```

> If I removed that requirement, it would work. However, there'd be no way
to keep the private data from being leaked. Sadly, it's all or nothing with
this approach. Hard private or soft private, those are the only choices.

In the context of what you’ve described here this may be true, but no such
limitation presently exists. We can already do all this — hard, leak-free
privacy, brandedness, “friends” etc — with scopes and WeakMaps, but for the
fact that the `WeakMap` intrinsics may be forged. So what’s baffled me is
this: why are all the proposals exploring this space not addressing that
relatively simple existing problem, and instead starting off from a place
of significant new complexity? You said “maybe after the private fields
problem has been resolved, someone will figure out a better way to handle
your use cases,” but I’d have hoped for the opposite — I want the primitive
building blocks which things like class field syntax could be built over,
if it is found that they are still necessary once the root issue is solved
for.

> The

Re: !Re: proposal: Object Members

2018-07-28 Thread Ranando King
I've almost given up on making any significant headway in either adjusting
or flat-out correcting the flaws in that proposal, but I don't intend to
stop trying until either we get stuck with that proposal, or they
understand and accept what I'm telling them, or logically prove that my
concerns are either irrational or inconsequential.

> Private object state in particular is only _made complex_ by associating
it with declarations instead of scopes that happen to contain declarations
(or into which constructors are passed, etc). The complexity is artificial
— not a good sign imo.

That's not quite right. What you're essentially asking for is a violatable
private field, or as has been described by others, a "soft private". Since
we agree that the "friendly" & "befriend" pair is a somewhat (if not
completely) bad idea, I'm going to take 1 more pass at your 3 requests with
a different angle.

> Adding the same “slot” to multiple classes which don’t inherit from each
other
> Selectively sharing access to private state through functions declared
outside the class body

```js
//Using my proposal
var {A, B, C} = (() => {
  const common = Symbol("common");

  class A {
private [common] = 1;
add(...args) {
  var retval = this#[common];
  for (let obj of args) {
retval += obj#[common];
  }
  return retval;
}
  }
  class B {
private [common] = 2;
optional() {
  console.log(`common member = ${this#[common]}`);
}
  }
  var C = {
private [common]: 3,
required() {
  console.log(`common member = ${this#[common]}`);
}
  }

  return { A, B, C };
})();

//So you want the following statement to not throw a TypeError and return 6
(new A()).add(new B(), C);
```
I'm not sure I can make this work in my proposal, and I'm absolutely sure
you'd be flatly refused by the other proposal. If a `Symbol` is provided as
the `[[IdentifierName]]` of a private or protected field, then I can let
that `Symbol` be both the key and value that are added to the
`[[DeclarationInfo]]` and `[[InheritanceInfo]]` records. That way there
will be a common private field name usable by all 3 objects. However, the
guardian logic tries to verify that the function trying to access the
private fields of an instance is a member of the same or descending
prototype that was used to create that instance. If I removed that
requirement, it would work. However, there'd be no way to keep the private
data from being leaked. Sadly, it's all or nothing with this approach. Hard
private or soft private, those are the only choices. The TC39 board has
already decided that what they want new syntax for is hard private.

> 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

Because the TC39 board has set their sights on hard private, this will
require new syntax like what I suggested earlier Adding private members
dynamically would also pose a leak risk if it could be done after the
prototype has been fully constructed. The main reason the privacy is set on
a declaration level is because scope-level inheritance isn't very good for
`class`-oriented inheritance. The `class` keyword was provided to simplify
the vertical inheritance model, along with some API to enable inheritance
from native objects even without using `class`. The syntax changes for
simplifying private field declaration are just an extension of that. Even
though it's not unusual for some developers to spend a lot of time working
with fringe use-cases, syntax changes are almost always going to be made
for the most common use cases first. Maybe after the private fields problem
has been resolved, someone will figure out a better way to handle your use
cases.


On Sat, Jul 28, 2018 at 3:52 PM Darien Valentine 
wrote:

> > Are you saying you want multiple non-hierarchally related classes to
> have an instance private field with shared name [...]
>
> Yeah. This is a hard problem to solve when trying to integrate private
> fields with class syntax, but it’s not a problem at all when privacy is a
> more generic tool based on scope. This also isn’t a foreign concept in ES:
> consider this intrinsic method:
>
> https://tc39.github.io/ecma262/#sec-arraybuffer.isview
>
> This method returns true if the argument has the `[[ViewedArrayBuffer]]`
> slot. This slot exists on genuine instances of both `%TypedArray%` and
> `%DataView%`, but they do not receive these slots by way of inheritance
> from a common constructor. There are similar cases in HTML host APIs.
>
> > 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.
>
> I don’t think it is either, no. It’s too much complexity for too little
> gain. But again, this is achievable “for free” just by divorcing “private
> object state” from class declarations (or object literals). I would ask:
> what problem is solved by 

Re: !Re: proposal: Object Members

2018-07-28 Thread Darien Valentine
> Are you saying you want multiple non-hierarchally related classes to have
an instance private field with shared name [...]

Yeah. This is a hard problem to solve when trying to integrate private
fields with class syntax, but it’s not a problem at all when privacy is a
more generic tool based on scope. This also isn’t a foreign concept in ES:
consider this intrinsic method:

https://tc39.github.io/ecma262/#sec-arraybuffer.isview

This method returns true if the argument has the `[[ViewedArrayBuffer]]`
slot. This slot exists on genuine instances of both `%TypedArray%` and
`%DataView%`, but they do not receive these slots by way of inheritance
from a common constructor. There are similar cases in HTML host APIs.

> 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.

I don’t think it is either, no. It’s too much complexity for too little
gain. But again, this is achievable “for free” just by divorcing “private
object state” from class declarations (or object literals). I would ask:
what problem is solved by making this a feature of the declarations
themselves? Does it merit the complexity and the hoop jumping needed to
handle edge cases?\*

\* One person’s edge case; another’s everyday concern haha.

> The example you gave above still declares the functions in question
inside the class body, so that's not really a solution.

If you’re referring to the first example, that is a demonstration of what
is possible using the existing stage 3 class fields proposal as implemented
in Chrome. It isn’t what I want; it’s what’s necessary to achieve this with
the current stage 3 proposed model.

> Sounds to me like you'd love for class syntax to look like this [[example
with mixin syntax in declaration]]

Perhaps — it’s interesting for sure! But the pattern that already works,
`mixin(Cstr)`, is not presently a source of problems for me. Private object
state in particular is only _made complex_ by associating it with
declarations instead of scopes that happen to contain declarations (or into
which constructors are passed, etc). The complexity is artificial — not a
good sign imo.

>  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.

Both the WeakMap solution and the stub concept I provided after are more
generic than privacy in either of those proposals. When I say "object
private state," it’s true that the object in question could be any object.
But in practice, any realization of the feature would pertain chiefly to
class instances, and the examples I gave, though contrived, do concern
class instances. The reason private object state is chiefly an issue of
class instances stems directly from the nature of prototype methods and
accessors, so if you are not making use of prototypes, you could instead
have used a closure+factory directly.

---

In a nutshell, my issue with existing proposals could probably be
summarized as a concern that they are neither as generic nor as simple as
native slots. To be clear, proper “slots” are an internal concept, only
observable indirectly — but they are the special sauce underlying a number
of behaviors which are presently awkward to achieve in ES code itself, and
they are a nice simple model of private object state which is tantalizingly
close to, but not _exactly_ the same as in two critical ways, symbol keyed
properties. That said, “real” slots would continue to have an advantage
with regard to cross-realm stuff even if private symbol keys existed.

That such a model is radically simpler — minmax and all that — feels very
important to me, but I dunno. I’m not holding my breath for big changes
here. The current stage 3 proposal seems to be unstoppable; much smarter /
more important people than me have already tried and failed. :)


On Sat, Jul 28, 2018 at 3:14 PM Ranando King  wrote:

> 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 t

Re: !Re: proposal: Object Members

2018-07-28 Thread Ranando King
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 [] [extends ] [mixes
[, [, ...]]] { ... }
```
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 
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
>

Re: !Re: proposal: Object Members

2018-07-28 Thread Darien Valentine
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


Re:!Re: proposal: Object Members

2018-07-28 Thread Darien Valentine
Ranando, I share your reservations about private fields being bound too
tightly to class syntax. In my case it isn’t because I don’t want to use
classes, but rather because in the last few years, using the WeakMap
solution, a good number of times I’ve needed to do things which the private
field proposal either doesn’t permit or account for:

- Adding the same “slot” to multiple classes which don’t inherit from each
other
- Selectively sharing access to private state through functions declared
outside the class body
- 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

With the WeakMap solution, the privacy mechanism is one that already
exists: a scope. This makes it very flexible (it handles the above three
cases fine), but it has a key limitation in terms of achieving privacy,
which is that `global.WeakMap` and `WeakMap.prototype` may be compromised.
Given this limitation — plus the amount of boilerplate WeakMap privacy can
entail — I am very happy to see private instance state being addressed
syntactically. However because the model chosen for “scope of privacy” is
“class declaration body” — not previously something that provided a
closure/scope at all? — instead of just using existing scopes, I have found
them impractical to use in some cases.

If I’m understanding your alternative proposal, Ranando, I don’t think it
addresses these issues either, not in the way I’m looking for anyway — I’m
wishing for a syntactic solution for true private slots on objects, but
where said slots are associated with a scope (almost always a module scope)
rather than a class declaration. In particular, I’m not convinced that the
concept of “protected” makes sense within the JS models of objects and
dispatch.

I’m gonna get more detailed about what I see as inadequacies in the current
proposal. These are subjective, but not hypothetical: I’ve been doing
WeakMap-based privacy for a few years now and I’ve tried converting
existing code to use private fields since Chrome shipped it behind a flag.
I found that, unfortunately, it did not meet my needs.

---

Regarding exposing functions that operate on private state but which do not
live on the constructor or prototype — there is a way to achieve this in
the proposed spec. It’s awkward, but it is technically possible:

```js
class Foo {
  #bar = 1;

  getBarOfFoo(foo) {
return this.#bar;
  }

  // [[ ... other methods that may manipulate but do not expose #bar here
... ]]
}

const { getBarOfFoo } = Foo.prototype;
delete Foo.prototype.getBarOfFoo;
```

It gets more awkward in the “multiple classes with the same semantic slot”
case, since one will have to wrap each attempted access in a try-catch, as
there is no other way to be certain whether the target has the slot. With
WeakMap, in contrast, one will just get undefined — and one may use the
same WeakMap to manage the same slot across multiple classes that are
declared in the same scope as the WeakMap.

Assume we have two classes with a private bar “slot” which is meant to be
semantically equivalent. It holds an integer. We want to create a function
that adds together two bar values from any classes that implement this
slot. If an argument has no bar slot, bar defaults to zero. With WeakMaps,
such a function might look like this:

```js
function addBars(a, b) {
  return (wm.get(a).bar || 0) + (wm.get(b).bar || 0);
}
```

Realizing the same logic with classes that use private field syntax is
still possible (using the aforementioned “pop off a method” pattern), but
now it looks like this:

```js
function addBars(a, b) {
  let aBar, bBar;

  try {
aBar = getBarOfFoo(a);
  } catch {
try {
  aBar = getBarOfBaz(a);
} catch {
  aBar = 0;
}
  }

  try {
bBar = getBarOfFoo(b);
  } catch {
try {
  bBar = getBarOfBaz(b);
} catch {
  bBar = 0;
}
  }

  return aBar + bBar;
}
```

¯\_(ツ)_/¯

---

This is a more minor issue, but assuming we *can’t* have dynamic slots, I
would like to take advantage of the fact that
whether-a-function-may-access-a-slot is statically knowable by having
immediate brand checking occur in all methods that may access private
state. This is actually the main source of boilerplate in the WeakMap
solution (for me, but admittedly I’m probably in a tiny minority here):

```js
set foo(value) {
  if (!wm.has(this)) throw new TypeError(`Illegal invocation`);

  const str = String(value);

  if (VALID_FOO_VALUES.has(str)) {
wm.get(this).foo = str;
  } else {
throw new Error(`Invalid value for foo`);
  }
}
```

The difference between the above function with and without the guard
concerns guarantees about behavior. The `String(value)` call actually might
throw, but it ought to be predictable that a method which requires a
branded receiver always throws the same error when called on anything
unbranded — even if (especially if!) private state access occurs in the

Re: Re: proposal: Object Members

2018-07-23 Thread Darien Valentine
> That, and that the existing builtins already impose those limitations -
and only class allows you to do those things, with them.

I’m surprised by that statement — it appeared to me that it currently
remains possible to create classes, including classes that extend
built-ins, with class syntax.

```
const test = value => {
  if (typeof value !== 'string') throw new TypeError('nope');
  return value;
};

function StringSet(init) {
  if (new.target === undefined)
throw new TypeError('StringSet is not a constructor');
  if (init !== undefined)
init = Array.from(init, test);

  return Reflect.construct(Set, [ init ], new.target);
}

Reflect.defineProperty(StringSet.prototype, 'add', {
  configurable: true,
  value: Object.setPrototypeOf({
add(value) {
  return super.add(test(value));
}
  }, Set.prototype).add
});

Reflect.defineProperty(StringSet.prototype, Symbol.toStringTag, {
  configurable: true,
  value: 'StringSet'
});

Reflect.setPrototypeOf(StringSet, Set);
Reflect.setPrototypeOf(StringSet.prototype, Set.prototype);

new StringSet('abc');
```

Not that this is something one is apt to want to do normally, though it
being possible does remain useful sometimes for meta/compositiony stuff. It
cannot be achieved in an <= ES5 environment, but it seems all the
reflection tools needed are present in environments that actually have
class syntax — even, despite the awkwardness necessitated by HomeObject
stuff, what is needed to employ super in methods.

I’m curious if, aside from the possibility of implementation-specific
things like type error messages being different, there there is anything
about the above class which ends up observably different from the ES-side
from one created with class syntax instead?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss