Re: proposal: Object Members

2018-08-15 Thread Ranando King
The POC has been completed. This is a completely viable POC in that it can
be used in its present form in production code. I cannot speak for its
performance yet as I have done no performance testing on it. Seeing as how
it uses Proxy extensively to control access to private declarations, it is
likely to be slow. So this POC may not be suitable for use in high
performance applications. The biggest pain point for this POC is the fact
that `Function.caller` and `arguments.callee` have been completely crippled
to the the point of being useless. While I understand that their presence
prevented optimizations, it would be far more useful to allow the existence
of something like `Function.callerFrame` object with a `containsFn(fn)`
method to allow exact method identification without call access, and a
`previousFrame()` method to allow walking the call stack... but that's an
issue for a different proposal.

On Sun, Aug 5, 2018 at 9:41 AM Ranando King  wrote:

> Just released the POC code for review. Using the `Privacy()` export, you
> can now wrap any class or object definition and add `private` and
> `protected` members. To add privileged members to a `class`, declare a
> function `static [Privacy.Data]() {}` and return an object containing your
> `public` data and `private`/`protected` members. To add privileged members
> to any object, declare the field name with array notation, including the
> privilege level in the name. The "internal" privilege level has been left
> out of this POC and will be released as a separate proposal if this
> proposal gains any traction.
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


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 

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: proposal: Object Members

2018-08-05 Thread Ranando King
Just released the POC code for review. Using the `Privacy()` export, you
can now wrap any class or object definition and add `private` and
`protected` members. To add privileged members to a `class`, declare a
function `static [Privacy.Data]() {}` and return an object containing your
`public` data and `private`/`protected` members. To add privileged members
to any object, declare the field name with array notation, including the
privilege level in the name. The "internal" privilege level has been left
out of this POC and will be released as a separate proposal if this
proposal gains any traction.
___
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 

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 

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

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

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 

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 

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 

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 

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 

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 

Re: !Re: proposal: Object Members

2018-08-01 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 

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 

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 

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 

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 

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 

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 

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 

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

Re: !Re: proposal: Object Members

2018-07-30 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. 

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 

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

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 

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 

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 

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.

> 

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 

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: proposal: Object Members

2018-07-28 Thread Ranando King
You're almost right about that. The guardian logic that ensures this cannot
happen is that the `[[DeclarationInfo]]` of the instance whose private
fields are being accessed must either be or be a prototype of the
`[[DeclarationInfo]]` of the current function. This was part of the update
I made to the proposal last night after replying to Waldemar. The only way
for this to be true is that the current function would have been declared
within the same declaration scope as the function used to create the
instance. When this match doesn't occur, use of the `#` operator causes a
TypeError.

On Sat, Jul 28, 2018 at 1:47 AM Jordan Harband  wrote:

> If the "name" is just a string, though, then it's just another global
> namespace. I could access a private field named "id" on every object that
> had one, in a try/catch, and i'd be able to not just observe if an object
> has an "id" private field, but access or alter its contents.
>
> On Fri, Jul 27, 2018 at 9:37 PM, Ranando King  wrote:
>
>> > The proposal commingles static and instance private properties.  In
>> the first example, you could read or write this#.field2, and it would
>> work.  How would you encode the generic expression a#.[b]?
>>
>> That's not quite right. I added some details about how all this works a
>> few hours after you wrote this message. Here's the gist:
>> The `static` keyword would cause `field2` to be placed in the
>> `[[PrivateValues]]` record of the function. The `protected` keyword would
>> cause a key/value pair resembling `"field2": Symbol("field2")` to be placed
>> in the `[[DeclarationInfo]]` record of the function. Since you used `this`,
>> I will assume it is an instance of `ExampleFn`. The expression
>> `this#.field2` within `ExampleFn` would translate into
>>
>> `this.[[PrivateValues]][this.[[DeclarationInfo]].field2] ->
>> this.[[PrivateValues]][undefined] -> TypeError`
>>
>> assuming that the prototype of `ExampleFn` contained no definition for
>> field2. Since the `static` field belongs to the function it is declared in,
>> it can only be accessed via the function object itself, i.e.
>> `ExampleFn#.field2` or `this.constructor#.field2` or the array-notation
>> equivalents. I can't say that I'm understanding what you're looking for
>> with `a#.[b]` That looks like a syntax error to me. If you're trying to
>> understand how `a#[b]` works, it would be exactly the same. The best way to
>> understand how it works is to look at this equation for the `#` operator.
>>
>> # ===
>> .[[PrivateValues]][.[[DeclarationInfo]]]
>>
>> In the case of `a#[b]`, the result would be:
>>
>> a.[[PrivateValues]][a.[[DeclarationInfo]] [b] ]
>>
>> I get that all the square braces can make that hard to read, so here's
>> the step by step:
>>
>>1. Throw a type error if a is not an object
>>2. Let D be the [[DeclarationInfo]] record of object.
>>3. if D is not in the lexical scope chain of the current function,
>>throw a TypeError
>>4. Let N be the value for the key matching b in D, or undefined if no
>>such key exists.
>>5. Let P be the [[PrivateValues]] record of object a
>>6. If N is not a key of P, Throw a TypeError
>>7. return P[N]
>>
>> > Worse, the proposal commingles all private properties across all
>> classes.  There's nothing in the proposed code stopping you from reading
>> and writing private properties defined by class A on instances of an
>> unrelated class B.
>>
>> That's not right either. The example desugaring does indeed throw all
>> maps into the same WeakMap. I'll work on that to make a better example.
>> However, to get a better understanding of how I see the implementation, you
>> should read the implementation details section. There's a much better
>> description there. Besides, the 7 step description I just wrote for you
>> should help you realize that:
>>
>>- If the function you're in doesn't know the names of the private
>>fields of your object, you get a TypeError.
>>- If the object you're accessing doesn't recognize the name of the
>>field you're trying to access, you get a TypeError.
>>
>> So there really is no way to apply the private field names of `class A`
>> onto an instance of `class B`.
>>
>> I'll spend some time tonight re-tooling my example desugaring and a few
>> other details I thought of while writing this in the proposal. Hopefully,
>> that'll prevent more confusion.
>>
>>
>> On Fri, Jul 27, 2018 at 7:55 PM Waldemar Horwat 
>> wrote:
>>
>>> On 07/26/2018 01:55 PM, Ranando King wrote:
>>> > I've just finished updating my proposal with an [Existing proposals](
>>> https://github.com/rdking/proposal-object-members/blob/master/README.md#existing-proposals)
>>> section that lists the major differences.
>>>
>>> Reading the proposal, I'm not yet sure what it's supposed to do.  Some
>>> things I've noticed:
>>>
>>> - The proposal commingles static and instance private properties.  In
>>> the first example, you could read or write this#.field2, and it would
>>> work.  

Re: proposal: Object Members

2018-07-28 Thread Jordan Harband
If the "name" is just a string, though, then it's just another global
namespace. I could access a private field named "id" on every object that
had one, in a try/catch, and i'd be able to not just observe if an object
has an "id" private field, but access or alter its contents.

On Fri, Jul 27, 2018 at 9:37 PM, Ranando King  wrote:

> > The proposal commingles static and instance private properties.  In the
> first example, you could read or write this#.field2, and it would work.
> How would you encode the generic expression a#.[b]?
>
> That's not quite right. I added some details about how all this works a
> few hours after you wrote this message. Here's the gist:
> The `static` keyword would cause `field2` to be placed in the
> `[[PrivateValues]]` record of the function. The `protected` keyword would
> cause a key/value pair resembling `"field2": Symbol("field2")` to be placed
> in the `[[DeclarationInfo]]` record of the function. Since you used `this`,
> I will assume it is an instance of `ExampleFn`. The expression
> `this#.field2` within `ExampleFn` would translate into
>
> `this.[[PrivateValues]][this.[[DeclarationInfo]].field2] ->
> this.[[PrivateValues]][undefined] -> TypeError`
>
> assuming that the prototype of `ExampleFn` contained no definition for
> field2. Since the `static` field belongs to the function it is declared in,
> it can only be accessed via the function object itself, i.e.
> `ExampleFn#.field2` or `this.constructor#.field2` or the array-notation
> equivalents. I can't say that I'm understanding what you're looking for
> with `a#.[b]` That looks like a syntax error to me. If you're trying to
> understand how `a#[b]` works, it would be exactly the same. The best way to
> understand how it works is to look at this equation for the `#` operator.
>
> # === .[[PrivateValues]][<
> lParam>.[[DeclarationInfo]]]
>
> In the case of `a#[b]`, the result would be:
>
> a.[[PrivateValues]][a.[[DeclarationInfo]] [b] ]
>
> I get that all the square braces can make that hard to read, so here's the
> step by step:
>
>1. Throw a type error if a is not an object
>2. Let D be the [[DeclarationInfo]] record of object.
>3. if D is not in the lexical scope chain of the current function,
>throw a TypeError
>4. Let N be the value for the key matching b in D, or undefined if no
>such key exists.
>5. Let P be the [[PrivateValues]] record of object a
>6. If N is not a key of P, Throw a TypeError
>7. return P[N]
>
> > Worse, the proposal commingles all private properties across all
> classes.  There's nothing in the proposed code stopping you from reading
> and writing private properties defined by class A on instances of an
> unrelated class B.
>
> That's not right either. The example desugaring does indeed throw all maps
> into the same WeakMap. I'll work on that to make a better example. However,
> to get a better understanding of how I see the implementation, you should
> read the implementation details section. There's a much better description
> there. Besides, the 7 step description I just wrote for you should help you
> realize that:
>
>- If the function you're in doesn't know the names of the private
>fields of your object, you get a TypeError.
>- If the object you're accessing doesn't recognize the name of the
>field you're trying to access, you get a TypeError.
>
> So there really is no way to apply the private field names of `class A`
> onto an instance of `class B`.
>
> I'll spend some time tonight re-tooling my example desugaring and a few
> other details I thought of while writing this in the proposal. Hopefully,
> that'll prevent more confusion.
>
>
> On Fri, Jul 27, 2018 at 7:55 PM Waldemar Horwat 
> wrote:
>
>> On 07/26/2018 01:55 PM, Ranando King wrote:
>> > I've just finished updating my proposal with an [Existing proposals](
>> https://github.com/rdking/proposal-object-members/blob/master/README.md#
>> existing-proposals) section that lists the major differences.
>>
>> Reading the proposal, I'm not yet sure what it's supposed to do.  Some
>> things I've noticed:
>>
>> - The proposal commingles static and instance private properties.  In the
>> first example, you could read or write this#.field2, and it would work.
>> How would you encode the generic expression a#.[b]?
>>
>> - Worse, the proposal commingles all private properties across all
>> classes.  There's nothing in the proposed code stopping you from reading
>> and writing private properties defined by class A on instances of an
>> unrelated class B.
>>
>>  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: proposal: Object Members

2018-07-27 Thread Ranando King
> The proposal commingles static and instance private properties.  In the
first example, you could read or write this#.field2, and it would work.
How would you encode the generic expression a#.[b]?

That's not quite right. I added some details about how all this works a few
hours after you wrote this message. Here's the gist:
The `static` keyword would cause `field2` to be placed in the
`[[PrivateValues]]` record of the function. The `protected` keyword would
cause a key/value pair resembling `"field2": Symbol("field2")` to be placed
in the `[[DeclarationInfo]]` record of the function. Since you used `this`,
I will assume it is an instance of `ExampleFn`. The expression
`this#.field2` within `ExampleFn` would translate into

`this.[[PrivateValues]][this.[[DeclarationInfo]].field2] ->
this.[[PrivateValues]][undefined] -> TypeError`

assuming that the prototype of `ExampleFn` contained no definition for
field2. Since the `static` field belongs to the function it is declared in,
it can only be accessed via the function object itself, i.e.
`ExampleFn#.field2` or `this.constructor#.field2` or the array-notation
equivalents. I can't say that I'm understanding what you're looking for
with `a#.[b]` That looks like a syntax error to me. If you're trying to
understand how `a#[b]` works, it would be exactly the same. The best way to
understand how it works is to look at this equation for the `#` operator.

# ===
.[[PrivateValues]][.[[DeclarationInfo]]]

In the case of `a#[b]`, the result would be:

a.[[PrivateValues]][a.[[DeclarationInfo]] [b] ]

I get that all the square braces can make that hard to read, so here's the
step by step:

   1. Throw a type error if a is not an object
   2. Let D be the [[DeclarationInfo]] record of object.
   3. if D is not in the lexical scope chain of the current function, throw
   a TypeError
   4. Let N be the value for the key matching b in D, or undefined if no
   such key exists.
   5. Let P be the [[PrivateValues]] record of object a
   6. If N is not a key of P, Throw a TypeError
   7. return P[N]

> Worse, the proposal commingles all private properties across all
classes.  There's nothing in the proposed code stopping you from reading
and writing private properties defined by class A on instances of an
unrelated class B.

That's not right either. The example desugaring does indeed throw all maps
into the same WeakMap. I'll work on that to make a better example. However,
to get a better understanding of how I see the implementation, you should
read the implementation details section. There's a much better description
there. Besides, the 7 step description I just wrote for you should help you
realize that:

   - If the function you're in doesn't know the names of the private fields
   of your object, you get a TypeError.
   - If the object you're accessing doesn't recognize the name of the field
   you're trying to access, you get a TypeError.

So there really is no way to apply the private field names of `class A`
onto an instance of `class B`.

I'll spend some time tonight re-tooling my example desugaring and a few
other details I thought of while writing this in the proposal. Hopefully,
that'll prevent more confusion.


On Fri, Jul 27, 2018 at 7:55 PM Waldemar Horwat  wrote:

> On 07/26/2018 01:55 PM, Ranando King wrote:
> > I've just finished updating my proposal with an [Existing proposals](
> https://github.com/rdking/proposal-object-members/blob/master/README.md#existing-proposals)
> section that lists the major differences.
>
> Reading the proposal, I'm not yet sure what it's supposed to do.  Some
> things I've noticed:
>
> - The proposal commingles static and instance private properties.  In the
> first example, you could read or write this#.field2, and it would work.
> How would you encode the generic expression a#.[b]?
>
> - Worse, the proposal commingles all private properties across all
> classes.  There's nothing in the proposed code stopping you from reading
> and writing private properties defined by class A on instances of an
> unrelated class B.
>
>  Waldemar
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-27 Thread Waldemar Horwat

On 07/26/2018 01:55 PM, Ranando King wrote:

I've just finished updating my proposal with an [Existing 
proposals](https://github.com/rdking/proposal-object-members/blob/master/README.md#existing-proposals)
 section that lists the major differences.


Reading the proposal, I'm not yet sure what it's supposed to do.  Some things 
I've noticed:

- The proposal commingles static and instance private properties.  In the first 
example, you could read or write this#.field2, and it would work.  How would 
you encode the generic expression a#.[b]?

- Worse, the proposal commingles all private properties across all classes.  
There's nothing in the proposed code stopping you from reading and writing 
private properties defined by class A on instances of an unrelated class B.

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


Re: proposal: Object Members

2018-07-26 Thread Ranando King
I've just finished updating my proposal with an [Existing proposals](
https://github.com/rdking/proposal-object-members/blob/master/README.md#existing-proposals)
section that lists the major differences.

On Thu, Jul 26, 2018 at 9:00 AM Ranando King  wrote:

> Thank you for the advice. Those will be the next updates I make to the
> proposal.
>
> On Thu, Jul 26, 2018 at 3:32 AM T.J. Crowder <
> tj.crow...@farsightsoftware.com> wrote:
>
>> On Thu, Jul 26, 2018 at 7:28 AM, Ranando King  wrote:
>> > Let me see if I can clarify things a bit:
>>
>> Thanks! That does indeed clear things up a lot.
>>
>> I'd find it helpful (just speaking for myself here) if the proposal
>> opened with a series of specific differences with the two existing
>> proposals and statements of why your way is better. (If it refers to
>> existing issues raised on their repos, links are great with a summary of
>> where you think the issue stands.) You've made a few statements along those
>> lines in that list, but if you could flesh it out in the proposal, that
>> would be really helpful.
>>
>> -- T.J. Crowder
>>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-26 Thread Ranando King
Thank you for the advice. Those will be the next updates I make to the
proposal.

On Thu, Jul 26, 2018 at 3:32 AM T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Thu, Jul 26, 2018 at 7:28 AM, Ranando King  wrote:
> > Let me see if I can clarify things a bit:
>
> Thanks! That does indeed clear things up a lot.
>
> I'd find it helpful (just speaking for myself here) if the proposal opened
> with a series of specific differences with the two existing proposals and
> statements of why your way is better. (If it refers to existing issues
> raised on their repos, links are great with a summary of where you think
> the issue stands.) You've made a few statements along those lines in that
> list, but if you could flesh it out in the proposal, that would be really
> helpful.
>
> -- T.J. Crowder
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-26 Thread T.J. Crowder
On Thu, Jul 26, 2018 at 7:28 AM, Ranando King  wrote:
> Let me see if I can clarify things a bit:

Thanks! That does indeed clear things up a lot.

I'd find it helpful (just speaking for myself here) if the proposal opened
with a series of specific differences with the two existing proposals and
statements of why your way is better. (If it refers to existing issues
raised on their repos, links are great with a summary of where you think
the issue stands.) You've made a few statements along those lines in that
list, but if you could flesh it out in the proposal, that would be really
helpful.

-- T.J. Crowder
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-26 Thread Ranando King
Let me see if I can clarify things a bit:

You're not misunderstanding. I've spent a fair amount of time in discussion
on github in those very same issues. For various reasons, probably mostly
due to the time investment the proponents of those proposals have given, it
seems to be the prevailing view that the proposal as it stands, not
withstanding the many glaring issues its detractors keep raising, is the
best possible proposal that can be given. What I'm doing with my proposal
is raising a formal counter-argument. I'm not simply developing a new
proposal adhoc. Instead, I'm taking advantage of the many points and issues
raised about the existing proposals and integrating the best possible
solutions I and others can come up with that haven't been shot down for any
logical or rational reason into a single new, self-coherent, non-binding,
and mostly "means what you'd expect at first glance" proposal.

My goals are straight forward. I'll list them:
1. Introduce the concept of non-public privilege levels (`private` &
`protected`)
2. Introduce a self-consistent means of accessing non-public members
(operator `#`)
3. Introduce a means of declaring non-public members **with and without**
the `class` keyword
4. Prevent the introduction of special case characters in an
`[[IdentifierName]]`
5. Prevent the breaking of the `obj.field === obj['field']` usage pattern
6. Prevent the unnecessary isolation of functionality into the `class`
keyword
7. Prevent the unnecessary limiting of future language expansion due to
excessively limiting new feature.

Truth be told, the proposal I'm offering can be thought of as a heavy
handed revision of the two proposals above. I am presently adding to my
proposal a description of the implementation details required to make it
all work. I hope that at the very least, from this you and others will be
able to see that there is indeed a less limiting possibility than what has
been proposed by proposal-class-fields. Even though I am submitting my own
proposal, I will still continue to add my observations to the existing
proposals.

On Wed, Jul 25, 2018 at 2:23 AM T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Mon, Jul 23, 2018 at 8:38 PM, Ranando King
>  wrote:
> > I've written up a new draft proposal based on my own work with ES5 & ES6
> > compatible classes with fields. That can be found
> > [here](https://github.com/rdking/proposal-object-members). I'm already
> aware
> > of the class-members proposal, but I think it breaks far to many
> things...
>
> That's quite vague.
>
> Am I misunderstanding your intent here? It seems like you're proposing
> dropping the existing Stage 3 proposals ([1][1], [2][2]) in favor of this
> new proposal. Those proposals are the result of years of work and
> collaboration. It seems like any issues you have with them would be better
> addressed by raising issues on those proposals and engaging with the people
> working on them, rather than suggesting just throwing them out entirely and
> replacing them with something new and different. But perhaps I'm
> misunderstanding your intent?
>
> -- T.J. Crowder
>
> [1]: https://github.com/tc39/proposal-class-fields
> [2]: https://github.com/tc39/proposal-static-class-features/
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-25 Thread T.J. Crowder
On Mon, Jul 23, 2018 at 8:38 PM, Ranando King
 wrote:
> I've written up a new draft proposal based on my own work with ES5 & ES6
> compatible classes with fields. That can be found
> [here](https://github.com/rdking/proposal-object-members). I'm already
aware
> of the class-members proposal, but I think it breaks far to many things...

That's quite vague.

Am I misunderstanding your intent here? It seems like you're proposing
dropping the existing Stage 3 proposals ([1][1], [2][2]) in favor of this
new proposal. Those proposals are the result of years of work and
collaboration. It seems like any issues you have with them would be better
addressed by raising issues on those proposals and engaging with the people
working on them, rather than suggesting just throwing them out entirely and
replacing them with something new and different. But perhaps I'm
misunderstanding your intent?

-- T.J. Crowder

[1]: https://github.com/tc39/proposal-class-fields
[2]: https://github.com/tc39/proposal-static-class-features/
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-24 Thread Ranando King
Since it seems to be such an inflammatory statement, I have removed most of
the comments that infer the sugar-like nature of `class` from my proposal.
It counterproductive to get stuck on whether or not `class` is syntactic
sugar when the point is supposed to be about how to extend the language
features around the `class` keyword.

On Tue, Jul 24, 2018 at 9:14 AM Ranando King  wrote:

> @ljharb: It seems you now understand what I was trying to say. Sadly, I'm
> not always the most eloquent.
>
> >  As you've all pointed out, it's not "just sugar" in the sense that you
> couldn't do it in ES5; it's more that parallel syntax and API were
> created for the new functionality in ES6.
>
> The intent of my proposal is to provide both member fields and privilege
> levels to the `class` keyword, and the equivalent for object literals in a
> way that meets with both an intuitive declaration style, and a reasonable
> access notation that breaks as little as few as possible of the developers
> expectations of what can and can't be done.
>
> On Tue, Jul 24, 2018 at 3:18 AM Jordan Harband  wrote:
>
>> As you've all pointed out, it's not "just sugar" in the sense that you
>> couldn't do it in ES5; it's more that parallel syntax and API were created
>> for the new functionality in ES6. Thanks for providing clear code examples
>> of how one might extend builtins without `class`.
>>
>> @kai: yes, extending builtins makes sense, in that it's an important part
>> of ES6. Invoking "the web" doesn't negate *any* of the features of the
>> language, new or old. Separately, not every web use involves any JSON
>> serialization in either direction.
>>
>> On Tue, Jul 24, 2018 at 12:15 AM, T.J. Crowder <
>> tj.crow...@farsightsoftware.com> wrote:
>>
>>> On Tue, Jul 24, 2018 at 8:00 AM, Michael Theriot
>>>  wrote:
>>> > `Reflect.construct` allows subclasses to obtain internal slots without
>>> > `super()` / class syntax.
>>>
>>> Indeed, Darien pointed that out as well (and if you two hadn't, I would
>>> have. :-)
>>>
>>> > This is the first I have heard `class` is anything but sugar.
>>>
>>> The accurate statement would be that `class` lets you do things you
>>> couldn't do in ES5. But so does `Reflect.construct`. I believe it was
>>> important to the "no `new`" crowd that a non-`class` mechanism existed for
>>> creating objects using Error and Array as prototypes.
>>>
>>> -- T.J. Crowder
>>>
>>
>> ___
>> 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: proposal: Object Members

2018-07-24 Thread Ranando King
> this already underlines what I mean: classes are not just syntactic sugar
because you cannot replicate what they do, not even using ES6.

You're misunderstanding a few things.
1. Any ES6 class I create using the `class` keyword, I can recreate without
the `class` keyword. Period. There's no exception to this.
2. What I was describing to you was the work I put in to create a `class`
factory function that allows developers to easily create `class` instances
with data fields of varying privilege. This work is the **_conceptual
basis_** of my proposal. I never claimed even once that my example code was
somehow a flawless implementation of my proposal. That would be expressly
impossible. If it weren't, then I wouldn't be asking for a new feature. The
fact that in ES6 I cannot prevent a developer from passing the proxied
context object to an external method or assign it to an external variable
is not an issue that would be suffered by an in engine implementation of my
proposal. However, that would be a different version of ES, not ES6.

On Tue, Jul 24, 2018 at 10:29 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> > Proxy was used to create a membrane between the public and private
> storage, and I can't prevent that proxy from being passed to external
> functions
>
> this already underlines what I mean: classes are not just syntactic sugar
> because you cannot replicate what they do, not even using ES6.
>
> having privates / proxies maybe exposed is not how I'd personally code.
>
>
>
> On Tue, Jul 24, 2018 at 5:15 PM Ranando King  wrote:
>
>> > Private fields also won't work as expected...
>>
>> Can you clarify what you're referring to? I've created a library that
>> essentially implements the functional parts of what I intend with this
>> proposal. Of course the syntax isn't the same, and Proxy was used to create
>> a membrane between the public and private storage, and I can't prevent that
>> proxy from being passed to external functions, but those are ES-specific
>> implementation details and not how it would be implemented in the engine.
>>
>> >  ... the mandatory super call in constructor is also different from
>> ES5.
>>
>> You shouldn't really try to compare ES5 and ES6. My statement that
>> "`class` is syntactic sugar" refers to the fact that anything you can do
>> with `class` in ES6 can also be done without `class` in ES6.
>>
>> > P.S. Babel mistakenly sold classes as "just sugar" and never worked
>> properly with Custom Elements and builtins extend until version 7 which is
>> still not perfect but at least it doesn't throw errors for no reason.
>>
>> Just because `class` is essentially syntactic sugar doesn't mean that the
>> desugaring is backwards compatible with older versions of the language. I
>> do not wish to imply that. Nor do I see the need to make such a statement
>> true. Such an attempt to enforce backwards compatibility to that degree
>> would prove excessively burdensome on the process of improving and adding
>> features to the language.
>>
>> On Tue, Jul 24, 2018 at 9:41 AM Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> Private fields also won't work as expected and the mandatory super call
>>> in constructor is also different from ES5. Let's add species and special
>>> class related Symbol so that it makes no sense to define classes "just
>>> sugar" + there's no point in avoiding classes at all costs when any of
>>> these features is needed.
>>>
>>> Regards
>>>
>>> P.S. Babel mistakenly sold classes as "just sugar" and never worked
>>> properly with Custom Elements and builtins extend until version 7 which is
>>> still not perfect but at least it doesn't throw errors for no reason
>>>
>>>
>>> On Tue, Jul 24, 2018 at 4:15 PM Ranando King  wrote:
>>>
 @ljharb: It seems you now understand what I was trying to say. Sadly,
 I'm not always the most eloquent.

 >  As you've all pointed out, it's not "just sugar" in the sense that
 you couldn't do it in ES5; it's more that parallel syntax and API were
 created for the new functionality in ES6.

 The intent of my proposal is to provide both member fields and
 privilege levels to the `class` keyword, and the equivalent for object
 literals in a way that meets with both an intuitive declaration style, and
 a reasonable access notation that breaks as little as few as possible of
 the developers expectations of what can and can't be done.

 On Tue, Jul 24, 2018 at 3:18 AM Jordan Harband 
 wrote:

> As you've all pointed out, it's not "just sugar" in the sense that you
> couldn't do it in ES5; it's more that parallel syntax and API were created
> for the new functionality in ES6. Thanks for providing clear code examples
> of how one might extend builtins without `class`.
>
> @kai: yes, extending builtins makes sense, in that it's an important
> part of ES6. Invoking "the web" doesn't negate *any* of the features of 
> 

Re: proposal: Object Members

2018-07-24 Thread Michael Theriot
What can classes do that ES6 can't?

On Tuesday, July 24, 2018, Andrea Giammarchi 
wrote:

> > Proxy was used to create a membrane between the public and private
> storage, and I can't prevent that proxy from being passed to external
> functions
>
> this already underlines what I mean: classes are not just syntactic sugar
> because you cannot replicate what they do, not even using ES6.
>
> having privates / proxies maybe exposed is not how I'd personally code.
>
>
>
> On Tue, Jul 24, 2018 at 5:15 PM Ranando King  wrote:
>
>> > Private fields also won't work as expected...
>>
>> Can you clarify what you're referring to? I've created a library that
>> essentially implements the functional parts of what I intend with this
>> proposal. Of course the syntax isn't the same, and Proxy was used to create
>> a membrane between the public and private storage, and I can't prevent that
>> proxy from being passed to external functions, but those are ES-specific
>> implementation details and not how it would be implemented in the engine.
>>
>> >  ... the mandatory super call in constructor is also different from
>> ES5.
>>
>> You shouldn't really try to compare ES5 and ES6. My statement that
>> "`class` is syntactic sugar" refers to the fact that anything you can do
>> with `class` in ES6 can also be done without `class` in ES6.
>>
>> > P.S. Babel mistakenly sold classes as "just sugar" and never worked
>> properly with Custom Elements and builtins extend until version 7 which is
>> still not perfect but at least it doesn't throw errors for no reason.
>>
>> Just because `class` is essentially syntactic sugar doesn't mean that the
>> desugaring is backwards compatible with older versions of the language. I
>> do not wish to imply that. Nor do I see the need to make such a statement
>> true. Such an attempt to enforce backwards compatibility to that degree
>> would prove excessively burdensome on the process of improving and adding
>> features to the language.
>>
>> On Tue, Jul 24, 2018 at 9:41 AM Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> Private fields also won't work as expected and the mandatory super call
>>> in constructor is also different from ES5. Let's add species and special
>>> class related Symbol so that it makes no sense to define classes "just
>>> sugar" + there's no point in avoiding classes at all costs when any of
>>> these features is needed.
>>>
>>> Regards
>>>
>>> P.S. Babel mistakenly sold classes as "just sugar" and never worked
>>> properly with Custom Elements and builtins extend until version 7 which is
>>> still not perfect but at least it doesn't throw errors for no reason
>>>
>>>
>>> On Tue, Jul 24, 2018 at 4:15 PM Ranando King  wrote:
>>>
 @ljharb: It seems you now understand what I was trying to say. Sadly,
 I'm not always the most eloquent.

 >  As you've all pointed out, it's not "just sugar" in the sense that
 you couldn't do it in ES5; it's more that parallel syntax and API were
 created for the new functionality in ES6.

 The intent of my proposal is to provide both member fields and
 privilege levels to the `class` keyword, and the equivalent for object
 literals in a way that meets with both an intuitive declaration style, and
 a reasonable access notation that breaks as little as few as possible of
 the developers expectations of what can and can't be done.

 On Tue, Jul 24, 2018 at 3:18 AM Jordan Harband 
 wrote:

> As you've all pointed out, it's not "just sugar" in the sense that you
> couldn't do it in ES5; it's more that parallel syntax and API were created
> for the new functionality in ES6. Thanks for providing clear code examples
> of how one might extend builtins without `class`.
>
> @kai: yes, extending builtins makes sense, in that it's an important
> part of ES6. Invoking "the web" doesn't negate *any* of the features of 
> the
> language, new or old. Separately, not every web use involves any JSON
> serialization in either direction.
>
> On Tue, Jul 24, 2018 at 12:15 AM, T.J. Crowder <
> tj.crow...@farsightsoftware.com> wrote:
>
>> On Tue, Jul 24, 2018 at 8:00 AM, Michael Theriot
>>  wrote:
>> > `Reflect.construct` allows subclasses to obtain internal slots
>> without
>> > `super()` / class syntax.
>>
>> Indeed, Darien pointed that out as well (and if you two hadn't, I
>> would have. :-)
>>
>> > This is the first I have heard `class` is anything but sugar.
>>
>> The accurate statement would be that `class` lets you do things you
>> couldn't do in ES5. But so does `Reflect.construct`. I believe it was
>> important to the "no `new`" crowd that a non-`class` mechanism existed 
>> for
>> creating objects using Error and Array as prototypes.
>>
>> -- T.J. Crowder
>>
>
> ___
> es-discuss mailing list

Re: proposal: Object Members

2018-07-24 Thread Andrea Giammarchi
> Proxy was used to create a membrane between the public and private
storage, and I can't prevent that proxy from being passed to external
functions

this already underlines what I mean: classes are not just syntactic sugar
because you cannot replicate what they do, not even using ES6.

having privates / proxies maybe exposed is not how I'd personally code.



On Tue, Jul 24, 2018 at 5:15 PM Ranando King  wrote:

> > Private fields also won't work as expected...
>
> Can you clarify what you're referring to? I've created a library that
> essentially implements the functional parts of what I intend with this
> proposal. Of course the syntax isn't the same, and Proxy was used to create
> a membrane between the public and private storage, and I can't prevent that
> proxy from being passed to external functions, but those are ES-specific
> implementation details and not how it would be implemented in the engine.
>
> >  ... the mandatory super call in constructor is also different from ES5.
>
> You shouldn't really try to compare ES5 and ES6. My statement that
> "`class` is syntactic sugar" refers to the fact that anything you can do
> with `class` in ES6 can also be done without `class` in ES6.
>
> > P.S. Babel mistakenly sold classes as "just sugar" and never worked
> properly with Custom Elements and builtins extend until version 7 which is
> still not perfect but at least it doesn't throw errors for no reason.
>
> Just because `class` is essentially syntactic sugar doesn't mean that the
> desugaring is backwards compatible with older versions of the language. I
> do not wish to imply that. Nor do I see the need to make such a statement
> true. Such an attempt to enforce backwards compatibility to that degree
> would prove excessively burdensome on the process of improving and adding
> features to the language.
>
> On Tue, Jul 24, 2018 at 9:41 AM Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> Private fields also won't work as expected and the mandatory super call
>> in constructor is also different from ES5. Let's add species and special
>> class related Symbol so that it makes no sense to define classes "just
>> sugar" + there's no point in avoiding classes at all costs when any of
>> these features is needed.
>>
>> Regards
>>
>> P.S. Babel mistakenly sold classes as "just sugar" and never worked
>> properly with Custom Elements and builtins extend until version 7 which is
>> still not perfect but at least it doesn't throw errors for no reason
>>
>>
>> On Tue, Jul 24, 2018 at 4:15 PM Ranando King  wrote:
>>
>>> @ljharb: It seems you now understand what I was trying to say. Sadly,
>>> I'm not always the most eloquent.
>>>
>>> >  As you've all pointed out, it's not "just sugar" in the sense that
>>> you couldn't do it in ES5; it's more that parallel syntax and API were
>>> created for the new functionality in ES6.
>>>
>>> The intent of my proposal is to provide both member fields and privilege
>>> levels to the `class` keyword, and the equivalent for object literals in a
>>> way that meets with both an intuitive declaration style, and a reasonable
>>> access notation that breaks as little as few as possible of the developers
>>> expectations of what can and can't be done.
>>>
>>> On Tue, Jul 24, 2018 at 3:18 AM Jordan Harband  wrote:
>>>
 As you've all pointed out, it's not "just sugar" in the sense that you
 couldn't do it in ES5; it's more that parallel syntax and API were created
 for the new functionality in ES6. Thanks for providing clear code examples
 of how one might extend builtins without `class`.

 @kai: yes, extending builtins makes sense, in that it's an important
 part of ES6. Invoking "the web" doesn't negate *any* of the features of the
 language, new or old. Separately, not every web use involves any JSON
 serialization in either direction.

 On Tue, Jul 24, 2018 at 12:15 AM, T.J. Crowder <
 tj.crow...@farsightsoftware.com> wrote:

> On Tue, Jul 24, 2018 at 8:00 AM, Michael Theriot
>  wrote:
> > `Reflect.construct` allows subclasses to obtain internal slots
> without
> > `super()` / class syntax.
>
> Indeed, Darien pointed that out as well (and if you two hadn't, I
> would have. :-)
>
> > This is the first I have heard `class` is anything but sugar.
>
> The accurate statement would be that `class` lets you do things you
> couldn't do in ES5. But so does `Reflect.construct`. I believe it was
> important to the "no `new`" crowd that a non-`class` mechanism existed for
> creating objects using Error and Array as prototypes.
>
> -- T.J. Crowder
>

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

>>> ___
>>> es-discuss mailing list
>>> es-discuss@mozilla.org
>>> 

Re: proposal: Object Members

2018-07-24 Thread Ranando King
> Private fields also won't work as expected...

Can you clarify what you're referring to? I've created a library that
essentially implements the functional parts of what I intend with this
proposal. Of course the syntax isn't the same, and Proxy was used to create
a membrane between the public and private storage, and I can't prevent that
proxy from being passed to external functions, but those are ES-specific
implementation details and not how it would be implemented in the engine.

>  ... the mandatory super call in constructor is also different from ES5.

You shouldn't really try to compare ES5 and ES6. My statement that "`class`
is syntactic sugar" refers to the fact that anything you can do with
`class` in ES6 can also be done without `class` in ES6.

> P.S. Babel mistakenly sold classes as "just sugar" and never worked
properly with Custom Elements and builtins extend until version 7 which is
still not perfect but at least it doesn't throw errors for no reason.

Just because `class` is essentially syntactic sugar doesn't mean that the
desugaring is backwards compatible with older versions of the language. I
do not wish to imply that. Nor do I see the need to make such a statement
true. Such an attempt to enforce backwards compatibility to that degree
would prove excessively burdensome on the process of improving and adding
features to the language.

On Tue, Jul 24, 2018 at 9:41 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> Private fields also won't work as expected and the mandatory super call in
> constructor is also different from ES5. Let's add species and special class
> related Symbol so that it makes no sense to define classes "just sugar" +
> there's no point in avoiding classes at all costs when any of these
> features is needed.
>
> Regards
>
> P.S. Babel mistakenly sold classes as "just sugar" and never worked
> properly with Custom Elements and builtins extend until version 7 which is
> still not perfect but at least it doesn't throw errors for no reason
>
>
> On Tue, Jul 24, 2018 at 4:15 PM Ranando King  wrote:
>
>> @ljharb: It seems you now understand what I was trying to say. Sadly, I'm
>> not always the most eloquent.
>>
>> >  As you've all pointed out, it's not "just sugar" in the sense that
>> you couldn't do it in ES5; it's more that parallel syntax and API were
>> created for the new functionality in ES6.
>>
>> The intent of my proposal is to provide both member fields and privilege
>> levels to the `class` keyword, and the equivalent for object literals in a
>> way that meets with both an intuitive declaration style, and a reasonable
>> access notation that breaks as little as few as possible of the developers
>> expectations of what can and can't be done.
>>
>> On Tue, Jul 24, 2018 at 3:18 AM Jordan Harband  wrote:
>>
>>> As you've all pointed out, it's not "just sugar" in the sense that you
>>> couldn't do it in ES5; it's more that parallel syntax and API were created
>>> for the new functionality in ES6. Thanks for providing clear code examples
>>> of how one might extend builtins without `class`.
>>>
>>> @kai: yes, extending builtins makes sense, in that it's an important
>>> part of ES6. Invoking "the web" doesn't negate *any* of the features of the
>>> language, new or old. Separately, not every web use involves any JSON
>>> serialization in either direction.
>>>
>>> On Tue, Jul 24, 2018 at 12:15 AM, T.J. Crowder <
>>> tj.crow...@farsightsoftware.com> wrote:
>>>
 On Tue, Jul 24, 2018 at 8:00 AM, Michael Theriot
  wrote:
 > `Reflect.construct` allows subclasses to obtain internal slots without
 > `super()` / class syntax.

 Indeed, Darien pointed that out as well (and if you two hadn't, I would
 have. :-)

 > This is the first I have heard `class` is anything but sugar.

 The accurate statement would be that `class` lets you do things you
 couldn't do in ES5. But so does `Reflect.construct`. I believe it was
 important to the "no `new`" crowd that a non-`class` mechanism existed for
 creating objects using Error and Array as prototypes.

 -- T.J. Crowder

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


Re: proposal: Object Members

2018-07-24 Thread Andrea Giammarchi
Private fields also won't work as expected and the mandatory super call in
constructor is also different from ES5. Let's add species and special class
related Symbol so that it makes no sense to define classes "just sugar" +
there's no point in avoiding classes at all costs when any of these
features is needed.

Regards

P.S. Babel mistakenly sold classes as "just sugar" and never worked
properly with Custom Elements and builtins extend until version 7 which is
still not perfect but at least it doesn't throw errors for no reason


On Tue, Jul 24, 2018 at 4:15 PM Ranando King  wrote:

> @ljharb: It seems you now understand what I was trying to say. Sadly, I'm
> not always the most eloquent.
>
> >  As you've all pointed out, it's not "just sugar" in the sense that you
> couldn't do it in ES5; it's more that parallel syntax and API were
> created for the new functionality in ES6.
>
> The intent of my proposal is to provide both member fields and privilege
> levels to the `class` keyword, and the equivalent for object literals in a
> way that meets with both an intuitive declaration style, and a reasonable
> access notation that breaks as little as few as possible of the developers
> expectations of what can and can't be done.
>
> On Tue, Jul 24, 2018 at 3:18 AM Jordan Harband  wrote:
>
>> As you've all pointed out, it's not "just sugar" in the sense that you
>> couldn't do it in ES5; it's more that parallel syntax and API were created
>> for the new functionality in ES6. Thanks for providing clear code examples
>> of how one might extend builtins without `class`.
>>
>> @kai: yes, extending builtins makes sense, in that it's an important part
>> of ES6. Invoking "the web" doesn't negate *any* of the features of the
>> language, new or old. Separately, not every web use involves any JSON
>> serialization in either direction.
>>
>> On Tue, Jul 24, 2018 at 12:15 AM, T.J. Crowder <
>> tj.crow...@farsightsoftware.com> wrote:
>>
>>> On Tue, Jul 24, 2018 at 8:00 AM, Michael Theriot
>>>  wrote:
>>> > `Reflect.construct` allows subclasses to obtain internal slots without
>>> > `super()` / class syntax.
>>>
>>> Indeed, Darien pointed that out as well (and if you two hadn't, I would
>>> have. :-)
>>>
>>> > This is the first I have heard `class` is anything but sugar.
>>>
>>> The accurate statement would be that `class` lets you do things you
>>> couldn't do in ES5. But so does `Reflect.construct`. I believe it was
>>> important to the "no `new`" crowd that a non-`class` mechanism existed for
>>> creating objects using Error and Array as prototypes.
>>>
>>> -- T.J. Crowder
>>>
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-24 Thread Ranando King
@ljharb: It seems you now understand what I was trying to say. Sadly, I'm
not always the most eloquent.

>  As you've all pointed out, it's not "just sugar" in the sense that you
couldn't do it in ES5; it's more that parallel syntax and API were created
for the new functionality in ES6.

The intent of my proposal is to provide both member fields and privilege
levels to the `class` keyword, and the equivalent for object literals in a
way that meets with both an intuitive declaration style, and a reasonable
access notation that breaks as little as few as possible of the developers
expectations of what can and can't be done.

On Tue, Jul 24, 2018 at 3:18 AM Jordan Harband  wrote:

> As you've all pointed out, it's not "just sugar" in the sense that you
> couldn't do it in ES5; it's more that parallel syntax and API were created
> for the new functionality in ES6. Thanks for providing clear code examples
> of how one might extend builtins without `class`.
>
> @kai: yes, extending builtins makes sense, in that it's an important part
> of ES6. Invoking "the web" doesn't negate *any* of the features of the
> language, new or old. Separately, not every web use involves any JSON
> serialization in either direction.
>
> On Tue, Jul 24, 2018 at 12:15 AM, T.J. Crowder <
> tj.crow...@farsightsoftware.com> wrote:
>
>> On Tue, Jul 24, 2018 at 8:00 AM, Michael Theriot
>>  wrote:
>> > `Reflect.construct` allows subclasses to obtain internal slots without
>> > `super()` / class syntax.
>>
>> Indeed, Darien pointed that out as well (and if you two hadn't, I would
>> have. :-)
>>
>> > This is the first I have heard `class` is anything but sugar.
>>
>> The accurate statement would be that `class` lets you do things you
>> couldn't do in ES5. But so does `Reflect.construct`. I believe it was
>> important to the "no `new`" crowd that a non-`class` mechanism existed for
>> creating objects using Error and Array as prototypes.
>>
>> -- T.J. Crowder
>>
>
> ___
> 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: proposal: Object Members

2018-07-24 Thread Jordan Harband
As you've all pointed out, it's not "just sugar" in the sense that you
couldn't do it in ES5; it's more that parallel syntax and API were created
for the new functionality in ES6. Thanks for providing clear code examples
of how one might extend builtins without `class`.

@kai: yes, extending builtins makes sense, in that it's an important part
of ES6. Invoking "the web" doesn't negate *any* of the features of the
language, new or old. Separately, not every web use involves any JSON
serialization in either direction.

On Tue, Jul 24, 2018 at 12:15 AM, T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Tue, Jul 24, 2018 at 8:00 AM, Michael Theriot
>  wrote:
> > `Reflect.construct` allows subclasses to obtain internal slots without
> > `super()` / class syntax.
>
> Indeed, Darien pointed that out as well (and if you two hadn't, I would
> have. :-)
>
> > This is the first I have heard `class` is anything but sugar.
>
> The accurate statement would be that `class` lets you do things you
> couldn't do in ES5. But so does `Reflect.construct`. I believe it was
> important to the "no `new`" crowd that a non-`class` mechanism existed for
> creating objects using Error and Array as prototypes.
>
> -- T.J. Crowder
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-24 Thread T.J. Crowder
On Tue, Jul 24, 2018 at 8:00 AM, Michael Theriot
 wrote:
> `Reflect.construct` allows subclasses to obtain internal slots without
> `super()` / class syntax.

Indeed, Darien pointed that out as well (and if you two hadn't, I would
have. :-)

> This is the first I have heard `class` is anything but sugar.

The accurate statement would be that `class` lets you do things you
couldn't do in ES5. But so does `Reflect.construct`. I believe it was
important to the "no `new`" crowd that a non-`class` mechanism existed for
creating objects using Error and Array as prototypes.

-- T.J. Crowder
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-24 Thread Michael Theriot
>
> Extend builtins, in particular - ie, `super()` allows your subclass to
> obtain internal slots it can't otherwise get.
>
> Even if `class` were just sugar, I don't think I see the argument that
> that's a *good* thing to preserve.
>

`Reflect.construct` allows subclasses to obtain internal slots without
`super()` / class syntax.

```js
const SubDate = function (...args) {
  const instance = Reflect.construct(Date, args, SubDate);
  return instance;
};

Object.setPrototypeOf(SubDate.prototype, Date.prototype);

const sub = new SubDate();
sub.getDate(); // has internal slots, does not throw
sub instanceof SubDate; // true
sub instanceof Date; // true
```

This is the first I have heard `class` is anything but sugar.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-24 Thread kai zhu
> Extend builtins, in particular - ie, `super()` allows your subclass to obtain 
> internal slots it can't otherwise get.

does extending builtins in the javascript-language even make sense, given the 
dominant industry application of it in a web-context?  as i've said before, the 
primary industry-painpoints with javascript are integration-related, namely 
serializing/reconstructing JSON data between client <-> server.  whatever 
low-level benefit you gain from extending builtins, typically is not worth the 
extra high-level integration-cost of serializing/reconstructing these custom 
data-structures to/from JSON.

p.s. - as an aside, new primitives like BigInt should have focused more on 
ease-of-use with JSON-serialization.  BigInt’s primary use-case in industry as 
i see it, is as a mechanism for JSON-serializing 64-bit integers between client 
<-> server <-> database.

kai zhu
kaizhu...@gmail.com



> On 24 Jul 2018, at 5:56 AM, Jordan Harband  wrote:
> 
> That, and that the existing builtins already impose those limitations - and 
> only `class` allows you to do those things, with them.
> 
> On Mon, Jul 23, 2018 at 3:52 PM, Ben Wiley  <mailto:therealbenwi...@gmail.com>> wrote:
> I see, so it's not that you can't do things without class as much as you can 
> impose limitations by using class. Thanks for clarifying
> 
> Le lun. 23 juill. 2018 18 h 49, Jordan Harband  <mailto:ljh...@gmail.com>> a écrit :
> When extending builtins, `super()` is the only way you can get the 
> appropriate internal slots applied to the instance. (Private fields work the 
> same way by providing a matching guarantee - that the only way someone can 
> subclass you successfully is using `class extends` and `super`)
> 
> On Mon, Jul 23, 2018 at 3:43 PM, Ben Wiley  <mailto:therealbenwi...@gmail.com>> wrote:
> What exactly can be accomplished with super that can't be accomplished 
> otherwise? I know the transpiled code is very verbose and unintuitive to read 
> if you avoid explicitly naming the base class, but I wasn't aware of new 
> capabilities that were previously impossible.
> 
> Ben
> 
> 
> Le lun. 23 juill. 2018 18 h 06, Ranando King  <mailto:king...@gmail.com>> a écrit :
> Granted about `super()`. That's the one thing I can't easily reproduce. 
> However, barring those internal slots, I can reproduce the functionality of 
> `super` and the checks performed as a result of the internal slots, all in 
> ES6. As for built-ins, I can easily and properly extend builtins without 
> `class` since ES6 officially has `Object.setPrototypeOf()`. If you don't 
> think it's possible, you should take a close look at what I'm doing in the 
> repl.it <http://repl.it/> link from my first post.
> 
> As for whether or not the sugary nature of `class` is a good thing, it really 
> is a matter of opinion. I just happen to be of the persuasion that since 
> there's literally no construct that `class` can produce that I cannot 
> reproduce by other means, then that means the `class` keyword (even in light 
> of `super`) is little more than syntactic sugar. As such, we shouldn't be so 
> hasty to turn an Object Oriented Prototype Based language into an Object 
> Oriented Class Based language. The only way to do that reasonably is to 
> ensure that whatever you can construct with `class` can always be 
> equivalently constructed without it.
> 
> Here's a more logical argument instead. Even if there are subtle differences 
> between `class` constructors and object factory functions, providing an 
> isolated path specific to `class` is likely to lead to situations very 
> similar to what happens when an open source package gets forked. Eventually, 
> the difference between the two paths may become so great that one is 
> eventually abandoned (by developers) in favor of the other. This is only a 
> valid argument because the power of ES is in it's simplicity. It's like 
> building a house with wood, nails, sheetrock, etc... (JS) vs. building a 
> house with pre-fabricated parts (class-based languages).
> 
> Don't get me wrong. The `class` keyword is a great thing. It simplifies the 
> production of creating object factories with prototypes. As I understand it, 
> that was the purpose. Let's not make the mistake of allowing something to be 
> done with `class` that cannot be reasonably reproduced without it. The moment 
> we do that, we're diverging from the intended purpose of `class`.
> 
> 
> 
> On Mon, Jul 23, 2018 at 4:17 PM Jordan Harband  <mailto:ljh...@gmail.com>> wrote:
> Extend builtins, in particular - ie, `super()` allows your subclass to obtain 
> internal slots it can't otherwise get.
> 
> Even if `class` were just sugar, I don't think I see the argument that that's 

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


Re: proposal: Object Members

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

On Mon, Jul 23, 2018 at 3:52 PM, Ben Wiley 
wrote:

> I see, so it's not that you can't do things without class as much as you
> can impose limitations by using class. Thanks for clarifying
>
> Le lun. 23 juill. 2018 18 h 49, Jordan Harband  a
> écrit :
>
>> When extending builtins, `super()` is the only way you can get the
>> appropriate internal slots applied to the instance. (Private fields work
>> the same way by providing a matching guarantee - that the only way someone
>> can subclass you successfully is using `class extends` and `super`)
>>
>> On Mon, Jul 23, 2018 at 3:43 PM, Ben Wiley 
>> wrote:
>>
>>> What exactly can be accomplished with super that can't be accomplished
>>> otherwise? I know the transpiled code is very verbose and unintuitive to
>>> read if you avoid explicitly naming the base class, but I wasn't aware of
>>> new capabilities that were previously impossible.
>>>
>>> Ben
>>>
>>>
>>> Le lun. 23 juill. 2018 18 h 06, Ranando King  a
>>> écrit :
>>>
>>>> Granted about `super()`. That's the one thing I can't easily reproduce.
>>>> However, barring those internal slots, I can reproduce the functionality of
>>>> `super` and the checks performed as a result of the internal slots, all in
>>>> ES6. As for built-ins, I can easily and properly extend builtins without
>>>> `class` since ES6 officially has `Object.setPrototypeOf()`. If you don't
>>>> think it's possible, you should take a close look at what I'm doing in the
>>>> repl.it link from my first post.
>>>>
>>>> As for whether or not the sugary nature of `class` is a good thing, it
>>>> really is a matter of opinion. I just happen to be of the persuasion that
>>>> since there's literally no construct that `class` can produce that I cannot
>>>> reproduce by other means, then that means the `class` keyword (even in
>>>> light of `super`) is little more than syntactic sugar. As such, we
>>>> shouldn't be so hasty to turn an Object Oriented Prototype Based language
>>>> into an Object Oriented Class Based language. The only way to do that
>>>> reasonably is to ensure that whatever you can construct with `class` can
>>>> always be equivalently constructed without it.
>>>>
>>>> Here's a more logical argument instead. Even if there are subtle
>>>> differences between `class` constructors and object factory functions,
>>>> providing an isolated path specific to `class` is likely to lead to
>>>> situations very similar to what happens when an open source package gets
>>>> forked. Eventually, the difference between the two paths may become so
>>>> great that one is eventually abandoned (by developers) in favor of the
>>>> other. This is only a valid argument because the power of ES is in it's
>>>> simplicity. It's like building a house with wood, nails, sheetrock, etc...
>>>> (JS) vs. building a house with pre-fabricated parts (class-based 
>>>> languages).
>>>>
>>>> Don't get me wrong. The `class` keyword is a great thing. It simplifies
>>>> the production of creating object factories with prototypes. As I
>>>> understand it, that was the purpose. Let's not make the mistake of allowing
>>>> something to be done with `class` that cannot be reasonably reproduced
>>>> without it. The moment we do that, we're diverging from the intended
>>>> purpose of `class`.
>>>>
>>>>
>>>>
>>>> On Mon, Jul 23, 2018 at 4:17 PM Jordan Harband 
>>>> wrote:
>>>>
>>>>> Extend builtins, in particular - ie, `super()` allows your subclass to
>>>>> obtain internal slots it can't otherwise get.
>>>>>
>>>>> Even if `class` were just sugar, I don't think I see the argument that
>>>>> that's a *good* thing to preserve.
>>>>>
>>>>> On Mon, Jul 23, 2018 at 2:05 PM, Ranando King 
>>>>> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> -- Forwarded message -
>>>>>> From: Ranando King 
>>>>>> Date: Mon, Jul 23, 2018 at 4:04 PM
>>>>>> Subject: Re: proposal: Object Members
>>>>>> To: 
>>>>>>
>>>>>>
>>>>

Re: proposal: Object Members

2018-07-23 Thread Ben Wiley
I see, so it's not that you can't do things without class as much as you
can impose limitations by using class. Thanks for clarifying

Le lun. 23 juill. 2018 18 h 49, Jordan Harband  a écrit :

> When extending builtins, `super()` is the only way you can get the
> appropriate internal slots applied to the instance. (Private fields work
> the same way by providing a matching guarantee - that the only way someone
> can subclass you successfully is using `class extends` and `super`)
>
> On Mon, Jul 23, 2018 at 3:43 PM, Ben Wiley 
> wrote:
>
>> What exactly can be accomplished with super that can't be accomplished
>> otherwise? I know the transpiled code is very verbose and unintuitive to
>> read if you avoid explicitly naming the base class, but I wasn't aware of
>> new capabilities that were previously impossible.
>>
>> Ben
>>
>>
>> Le lun. 23 juill. 2018 18 h 06, Ranando King  a
>> écrit :
>>
>>> Granted about `super()`. That's the one thing I can't easily reproduce.
>>> However, barring those internal slots, I can reproduce the functionality of
>>> `super` and the checks performed as a result of the internal slots, all in
>>> ES6. As for built-ins, I can easily and properly extend builtins without
>>> `class` since ES6 officially has `Object.setPrototypeOf()`. If you don't
>>> think it's possible, you should take a close look at what I'm doing in the
>>> repl.it link from my first post.
>>>
>>> As for whether or not the sugary nature of `class` is a good thing, it
>>> really is a matter of opinion. I just happen to be of the persuasion that
>>> since there's literally no construct that `class` can produce that I cannot
>>> reproduce by other means, then that means the `class` keyword (even in
>>> light of `super`) is little more than syntactic sugar. As such, we
>>> shouldn't be so hasty to turn an Object Oriented Prototype Based language
>>> into an Object Oriented Class Based language. The only way to do that
>>> reasonably is to ensure that whatever you can construct with `class` can
>>> always be equivalently constructed without it.
>>>
>>> Here's a more logical argument instead. Even if there are subtle
>>> differences between `class` constructors and object factory functions,
>>> providing an isolated path specific to `class` is likely to lead to
>>> situations very similar to what happens when an open source package gets
>>> forked. Eventually, the difference between the two paths may become so
>>> great that one is eventually abandoned (by developers) in favor of the
>>> other. This is only a valid argument because the power of ES is in it's
>>> simplicity. It's like building a house with wood, nails, sheetrock, etc...
>>> (JS) vs. building a house with pre-fabricated parts (class-based languages).
>>>
>>> Don't get me wrong. The `class` keyword is a great thing. It simplifies
>>> the production of creating object factories with prototypes. As I
>>> understand it, that was the purpose. Let's not make the mistake of allowing
>>> something to be done with `class` that cannot be reasonably reproduced
>>> without it. The moment we do that, we're diverging from the intended
>>> purpose of `class`.
>>>
>>>
>>>
>>> On Mon, Jul 23, 2018 at 4:17 PM Jordan Harband  wrote:
>>>
>>>> Extend builtins, in particular - ie, `super()` allows your subclass to
>>>> obtain internal slots it can't otherwise get.
>>>>
>>>> Even if `class` were just sugar, I don't think I see the argument that
>>>> that's a *good* thing to preserve.
>>>>
>>>> On Mon, Jul 23, 2018 at 2:05 PM, Ranando King 
>>>> wrote:
>>>>
>>>>>
>>>>>
>>>>> -- Forwarded message -
>>>>> From: Ranando King 
>>>>> Date: Mon, Jul 23, 2018 at 4:04 PM
>>>>> Subject: Re: proposal: Object Members
>>>>> To: 
>>>>>
>>>>>
>>>>> You've made that argument before. Exactly what is it in ES6 that you
>>>>> **can** do with `class` that you cannot do without class? I'd like some
>>>>> clarification on this.
>>>>>
>>>>> On Mon, Jul 23, 2018 at 3:30 PM Jordan Harband 
>>>>> wrote:
>>>>>
>>>>>> `class` is already not just syntactic sugar, so that notion isn't
>>>>>> correct, and shouldn't be maintained.
>>>>>>
>>>>>&

Re: proposal: Object Members

2018-07-23 Thread Jordan Harband
When extending builtins, `super()` is the only way you can get the
appropriate internal slots applied to the instance. (Private fields work
the same way by providing a matching guarantee - that the only way someone
can subclass you successfully is using `class extends` and `super`)

On Mon, Jul 23, 2018 at 3:43 PM, Ben Wiley 
wrote:

> What exactly can be accomplished with super that can't be accomplished
> otherwise? I know the transpiled code is very verbose and unintuitive to
> read if you avoid explicitly naming the base class, but I wasn't aware of
> new capabilities that were previously impossible.
>
> Ben
>
>
> Le lun. 23 juill. 2018 18 h 06, Ranando King  a écrit :
>
>> Granted about `super()`. That's the one thing I can't easily reproduce.
>> However, barring those internal slots, I can reproduce the functionality of
>> `super` and the checks performed as a result of the internal slots, all in
>> ES6. As for built-ins, I can easily and properly extend builtins without
>> `class` since ES6 officially has `Object.setPrototypeOf()`. If you don't
>> think it's possible, you should take a close look at what I'm doing in the
>> repl.it link from my first post.
>>
>> As for whether or not the sugary nature of `class` is a good thing, it
>> really is a matter of opinion. I just happen to be of the persuasion that
>> since there's literally no construct that `class` can produce that I cannot
>> reproduce by other means, then that means the `class` keyword (even in
>> light of `super`) is little more than syntactic sugar. As such, we
>> shouldn't be so hasty to turn an Object Oriented Prototype Based language
>> into an Object Oriented Class Based language. The only way to do that
>> reasonably is to ensure that whatever you can construct with `class` can
>> always be equivalently constructed without it.
>>
>> Here's a more logical argument instead. Even if there are subtle
>> differences between `class` constructors and object factory functions,
>> providing an isolated path specific to `class` is likely to lead to
>> situations very similar to what happens when an open source package gets
>> forked. Eventually, the difference between the two paths may become so
>> great that one is eventually abandoned (by developers) in favor of the
>> other. This is only a valid argument because the power of ES is in it's
>> simplicity. It's like building a house with wood, nails, sheetrock, etc...
>> (JS) vs. building a house with pre-fabricated parts (class-based languages).
>>
>> Don't get me wrong. The `class` keyword is a great thing. It simplifies
>> the production of creating object factories with prototypes. As I
>> understand it, that was the purpose. Let's not make the mistake of allowing
>> something to be done with `class` that cannot be reasonably reproduced
>> without it. The moment we do that, we're diverging from the intended
>> purpose of `class`.
>>
>>
>>
>> On Mon, Jul 23, 2018 at 4:17 PM Jordan Harband  wrote:
>>
>>> Extend builtins, in particular - ie, `super()` allows your subclass to
>>> obtain internal slots it can't otherwise get.
>>>
>>> Even if `class` were just sugar, I don't think I see the argument that
>>> that's a *good* thing to preserve.
>>>
>>> On Mon, Jul 23, 2018 at 2:05 PM, Ranando King  wrote:
>>>
>>>>
>>>>
>>>> -- Forwarded message -
>>>> From: Ranando King 
>>>> Date: Mon, Jul 23, 2018 at 4:04 PM
>>>> Subject: Re: proposal: Object Members
>>>> To: 
>>>>
>>>>
>>>> You've made that argument before. Exactly what is it in ES6 that you
>>>> **can** do with `class` that you cannot do without class? I'd like some
>>>> clarification on this.
>>>>
>>>> On Mon, Jul 23, 2018 at 3:30 PM Jordan Harband 
>>>> wrote:
>>>>
>>>>> `class` is already not just syntactic sugar, so that notion isn't
>>>>> correct, and shouldn't be maintained.
>>>>>
>>>>> On Mon, Jul 23, 2018 at 12:38 PM, Ranando King 
>>>>> wrote:
>>>>>
>>>>>> I've written up a new draft proposal based on my own work with ES5 &
>>>>>> ES6 compatible classes with fields. That can be found [here](
>>>>>> https://github.com/rdking/proposal-object-members). I'm already
>>>>>> aware of the class-members proposal, but I think it breaks far to many
>>>>>> things and doesn't do anything to maintain the notion that "`c

Re: proposal: Object Members

2018-07-23 Thread Ben Wiley
What exactly can be accomplished with super that can't be accomplished
otherwise? I know the transpiled code is very verbose and unintuitive to
read if you avoid explicitly naming the base class, but I wasn't aware of
new capabilities that were previously impossible.

Ben


Le lun. 23 juill. 2018 18 h 06, Ranando King  a écrit :

> Granted about `super()`. That's the one thing I can't easily reproduce.
> However, barring those internal slots, I can reproduce the functionality of
> `super` and the checks performed as a result of the internal slots, all in
> ES6. As for built-ins, I can easily and properly extend builtins without
> `class` since ES6 officially has `Object.setPrototypeOf()`. If you don't
> think it's possible, you should take a close look at what I'm doing in the
> repl.it link from my first post.
>
> As for whether or not the sugary nature of `class` is a good thing, it
> really is a matter of opinion. I just happen to be of the persuasion that
> since there's literally no construct that `class` can produce that I cannot
> reproduce by other means, then that means the `class` keyword (even in
> light of `super`) is little more than syntactic sugar. As such, we
> shouldn't be so hasty to turn an Object Oriented Prototype Based language
> into an Object Oriented Class Based language. The only way to do that
> reasonably is to ensure that whatever you can construct with `class` can
> always be equivalently constructed without it.
>
> Here's a more logical argument instead. Even if there are subtle
> differences between `class` constructors and object factory functions,
> providing an isolated path specific to `class` is likely to lead to
> situations very similar to what happens when an open source package gets
> forked. Eventually, the difference between the two paths may become so
> great that one is eventually abandoned (by developers) in favor of the
> other. This is only a valid argument because the power of ES is in it's
> simplicity. It's like building a house with wood, nails, sheetrock, etc...
> (JS) vs. building a house with pre-fabricated parts (class-based languages).
>
> Don't get me wrong. The `class` keyword is a great thing. It simplifies
> the production of creating object factories with prototypes. As I
> understand it, that was the purpose. Let's not make the mistake of allowing
> something to be done with `class` that cannot be reasonably reproduced
> without it. The moment we do that, we're diverging from the intended
> purpose of `class`.
>
>
>
> On Mon, Jul 23, 2018 at 4:17 PM Jordan Harband  wrote:
>
>> Extend builtins, in particular - ie, `super()` allows your subclass to
>> obtain internal slots it can't otherwise get.
>>
>> Even if `class` were just sugar, I don't think I see the argument that
>> that's a *good* thing to preserve.
>>
>> On Mon, Jul 23, 2018 at 2:05 PM, Ranando King  wrote:
>>
>>>
>>>
>>> -- Forwarded message -
>>> From: Ranando King 
>>> Date: Mon, Jul 23, 2018 at 4:04 PM
>>> Subject: Re: proposal: Object Members
>>> To: 
>>>
>>>
>>> You've made that argument before. Exactly what is it in ES6 that you
>>> **can** do with `class` that you cannot do without class? I'd like some
>>> clarification on this.
>>>
>>> On Mon, Jul 23, 2018 at 3:30 PM Jordan Harband  wrote:
>>>
>>>> `class` is already not just syntactic sugar, so that notion isn't
>>>> correct, and shouldn't be maintained.
>>>>
>>>> On Mon, Jul 23, 2018 at 12:38 PM, Ranando King 
>>>> wrote:
>>>>
>>>>> I've written up a new draft proposal based on my own work with ES5 &
>>>>> ES6 compatible classes with fields. That can be found [here](
>>>>> https://github.com/rdking/proposal-object-members). I'm already aware
>>>>> of the class-members proposal, but I think it breaks far to many things 
>>>>> and
>>>>> doesn't do anything to maintain the notion that "`class` is just syntactic
>>>>> sugar".
>>>>>
>>>>> This proposal is specifically based on the code [here](
>>>>> https://github.com/rdking/Class.js/tree/master/es6c). I've also got a
>>>>> [repl.it](https://repl.it/@arkain/Classjs-Compact-Syntax-ES6) that
>>>>> shows the same code running.
>>>>>
>>>>> The idea behind the proposal is that instead of injecting a lot of new
>>>>> logic into how `class` works, let's allow `class` to remain syntactic
>>>>> sugar, and put

Re: proposal: Object Members

2018-07-23 Thread Ranando King
Granted about `super()`. That's the one thing I can't easily reproduce.
However, barring those internal slots, I can reproduce the functionality of
`super` and the checks performed as a result of the internal slots, all in
ES6. As for built-ins, I can easily and properly extend builtins without
`class` since ES6 officially has `Object.setPrototypeOf()`. If you don't
think it's possible, you should take a close look at what I'm doing in the
repl.it link from my first post.

As for whether or not the sugary nature of `class` is a good thing, it
really is a matter of opinion. I just happen to be of the persuasion that
since there's literally no construct that `class` can produce that I cannot
reproduce by other means, then that means the `class` keyword (even in
light of `super`) is little more than syntactic sugar. As such, we
shouldn't be so hasty to turn an Object Oriented Prototype Based language
into an Object Oriented Class Based language. The only way to do that
reasonably is to ensure that whatever you can construct with `class` can
always be equivalently constructed without it.

Here's a more logical argument instead. Even if there are subtle
differences between `class` constructors and object factory functions,
providing an isolated path specific to `class` is likely to lead to
situations very similar to what happens when an open source package gets
forked. Eventually, the difference between the two paths may become so
great that one is eventually abandoned (by developers) in favor of the
other. This is only a valid argument because the power of ES is in it's
simplicity. It's like building a house with wood, nails, sheetrock, etc...
(JS) vs. building a house with pre-fabricated parts (class-based languages).

Don't get me wrong. The `class` keyword is a great thing. It simplifies the
production of creating object factories with prototypes. As I understand
it, that was the purpose. Let's not make the mistake of allowing something
to be done with `class` that cannot be reasonably reproduced without it.
The moment we do that, we're diverging from the intended purpose of `class`.



On Mon, Jul 23, 2018 at 4:17 PM Jordan Harband  wrote:

> Extend builtins, in particular - ie, `super()` allows your subclass to
> obtain internal slots it can't otherwise get.
>
> Even if `class` were just sugar, I don't think I see the argument that
> that's a *good* thing to preserve.
>
> On Mon, Jul 23, 2018 at 2:05 PM, Ranando King  wrote:
>
>>
>>
>> -- Forwarded message -
>> From: Ranando King 
>> Date: Mon, Jul 23, 2018 at 4:04 PM
>> Subject: Re: proposal: Object Members
>> To: 
>>
>>
>> You've made that argument before. Exactly what is it in ES6 that you
>> **can** do with `class` that you cannot do without class? I'd like some
>> clarification on this.
>>
>> On Mon, Jul 23, 2018 at 3:30 PM Jordan Harband  wrote:
>>
>>> `class` is already not just syntactic sugar, so that notion isn't
>>> correct, and shouldn't be maintained.
>>>
>>> On Mon, Jul 23, 2018 at 12:38 PM, Ranando King 
>>> wrote:
>>>
>>>> I've written up a new draft proposal based on my own work with ES5 &
>>>> ES6 compatible classes with fields. That can be found [here](
>>>> https://github.com/rdking/proposal-object-members). I'm already aware
>>>> of the class-members proposal, but I think it breaks far to many things and
>>>> doesn't do anything to maintain the notion that "`class` is just syntactic
>>>> sugar".
>>>>
>>>> This proposal is specifically based on the code [here](
>>>> https://github.com/rdking/Class.js/tree/master/es6c). I've also got a [
>>>> repl.it](https://repl.it/@arkain/Classjs-Compact-Syntax-ES6) that
>>>> shows the same code running.
>>>>
>>>> The idea behind the proposal is that instead of injecting a lot of new
>>>> logic into how `class` works, let's allow `class` to remain syntactic
>>>> sugar, and put that extra ability into object declarations instead. Then
>>>> simply allow `class` to do the same with it's own prototypes.
>>>>
>>>> ___
>>>> es-discuss mailing list
>>>> es-discuss@mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>>>
>>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-23 Thread Jordan Harband
Extend builtins, in particular - ie, `super()` allows your subclass to
obtain internal slots it can't otherwise get.

Even if `class` were just sugar, I don't think I see the argument that
that's a *good* thing to preserve.

On Mon, Jul 23, 2018 at 2:05 PM, Ranando King  wrote:

>
>
> -- Forwarded message -
> From: Ranando King 
> Date: Mon, Jul 23, 2018 at 4:04 PM
> Subject: Re: proposal: Object Members
> To: 
>
>
> You've made that argument before. Exactly what is it in ES6 that you
> **can** do with `class` that you cannot do without class? I'd like some
> clarification on this.
>
> On Mon, Jul 23, 2018 at 3:30 PM Jordan Harband  wrote:
>
>> `class` is already not just syntactic sugar, so that notion isn't
>> correct, and shouldn't be maintained.
>>
>> On Mon, Jul 23, 2018 at 12:38 PM, Ranando King  wrote:
>>
>>> I've written up a new draft proposal based on my own work with ES5 & ES6
>>> compatible classes with fields. That can be found [here](
>>> https://github.com/rdking/proposal-object-members). I'm already aware
>>> of the class-members proposal, but I think it breaks far to many things and
>>> doesn't do anything to maintain the notion that "`class` is just syntactic
>>> sugar".
>>>
>>> This proposal is specifically based on the code [here](
>>> https://github.com/rdking/Class.js/tree/master/es6c). I've also got a [
>>> repl.it](https://repl.it/@arkain/Classjs-Compact-Syntax-ES6) that shows
>>> the same code running.
>>>
>>> The idea behind the proposal is that instead of injecting a lot of new
>>> logic into how `class` works, let's allow `class` to remain syntactic
>>> sugar, and put that extra ability into object declarations instead. Then
>>> simply allow `class` to do the same with it's own prototypes.
>>>
>>> ___
>>> es-discuss mailing list
>>> es-discuss@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-23 Thread Jordan Harband
`class` is already not just syntactic sugar, so that notion isn't correct,
and shouldn't be maintained.

On Mon, Jul 23, 2018 at 12:38 PM, Ranando King  wrote:

> I've written up a new draft proposal based on my own work with ES5 & ES6
> compatible classes with fields. That can be found [here](
> https://github.com/rdking/proposal-object-members). I'm already aware of
> the class-members proposal, but I think it breaks far to many things and
> doesn't do anything to maintain the notion that "`class` is just syntactic
> sugar".
>
> This proposal is specifically based on the code [here](https://github.com/
> rdking/Class.js/tree/master/es6c). I've also got a [repl.it](
> https://repl.it/@arkain/Classjs-Compact-Syntax-ES6) that shows the same
> code running.
>
> The idea behind the proposal is that instead of injecting a lot of new
> logic into how `class` works, let's allow `class` to remain syntactic
> sugar, and put that extra ability into object declarations instead. Then
> simply allow `class` to do the same with it's own prototypes.
>
> ___
> 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