Re: Proposal: Typeof Trap

2019-07-28 Thread Ranando King
On one hand, I agree with Jordan. Don't grief the language due to a bad 3rd
party API. Whether we accept it or not, a browser's API is a 3rd party API
with respect to Javascript. Otherwise, node would have to include that API
to be spec compliant.

On the other hand, let's be a little more pragmatic about it. If that
busted-up Web API wasn't important, ES wouldn't be so highly constrained in
its changes vs what's running in browsers.

On Sun, Jul 28, 2019 at 1:10 AM Jordan Harband  wrote:

> The existence of `document.all` (which is now specified in Annex B of the
> JS spec) doesn't make `typeof` broken, it makes web browsers broken.
>
> On Sat, Jul 27, 2019 at 3:42 PM Michael Haufe 
> wrote:
>
>> Congratz. It was document.all.
>>
>> "In case you're wondering, I've never seen anyone return or store
>> `document.all` ever."
>>
>> Before W3C standard you could (and some people did):
>>
>> function elements() {
>> if(document.all) {
>> return document.all
>> } else if(document.layers) {
>> return document.layers
>> } else {
>> throw "You must use IE4+ or NS 4.7!"
>> }
>> }
>>
>> This is actually the wrong way to use document.layers, but it was not
>> uncommon to see. Later when the W3C was standardizing, you managed the
>> three pathways by passing the id to the function.
>>
>> You can see examples of this on comp.lang.javascript, and through a
>> search engine by looking for "return document.all" or "return
>> document.layers". There are also some legacy books showing the practice.
>>
>> /Michael
>>
>>
>> -Original Message-
>> From: Isiah Meadows 
>> Sent: Saturday, July 27, 2019 4:42 PM
>> To: Michael Haufe 
>> Cc: Jordan Harband ; es-discuss@mozilla.org
>> Subject: Re: Proposal: Typeof Trap
>>
>> `document.all`, and that's only required for web browsers to implement
>> - it's in Annex B. Some newer JS engines targeting non-browser platforms
>> (like Moddable's XS and I believe Nashorn as well) don't even implement it,
>> and it leads to a slightly simpler runtime.
>>
>> And it's only there thanks to a bunch of people relying on `if
>> (document.all) doSomething()` for detecting legacy crap while others at
>> the same time just assuming it's there without checking for it first,
>> almost always on ancient web pages. Oh, and people were also calling it via
>> `document.all(nameOrIndex)` instead of `document.all[nameOrIndex]`, so the
>> HTML spec also has it implementing `[[Call]]`.
>>
>> - HTML spec:
>> https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#the-htmlallcollection-interface
>> - ES spec: https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot
>>
>> In case you're wondering, I've never seen anyone return or store
>> `document.all` ever.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Sat, Jul 27, 2019 at 5:20 PM Michael Haufe 
>> wrote:
>> >
>> > More than one case:
>> >
>> >
>> >
>> > 
>> >
>> > var foo = f()
>> >
>> > typeof foo // object
>> >
>> > foo instanceof Object // false
>> >
>> >
>> >
>> > var bar = g()
>> >
>> > typeof bar //undefined
>> >
>> > bar instanceof Object //true
>> >
>> > bar() //
>> >
>> > 
>> >
>> >
>> >
>> > You could probably guess what the value of foo is. Can you guess what
>> the second is in any useful way?
>> >
>> >
>> >
>> > From: Jordan Harband 
>> > Sent: Saturday, July 27, 2019 3:56 PM
>> > To: Michael Haufe 
>> > Cc: es-discuss@mozilla.org
>> > Subject: Re: Proposal: Typeof Trap
>> >
>> >
>> >
>> > With something that while unintuitive in one case, is eternally robust
>> and reliable.
>> >
>> >
>> >
>> > If you want extensibility, define Symbol.toStringTag on your objects.
>> >
>> >
>> >
>> > On Sat, Jul 27, 2019 at 1:23 PM Michael Haufe 
>> wrote:
>> >
>> > If it's unfixably broken[1], non-extensible, excessively vague, and
>> non-orthogonal, where does that leave you?
>> >
>> >
>> >
>> > [1] 
>> >
>> >
>> >
>> > From: Jordan Harband 
>> > Sent: Saturday, July 27, 2019 3:00 PM
>> > To: Michael Haufe 
>> > Cc: ViliusCreator ;
>> > es-discuss@mozilla.org
>> > Subject: Re: Proposal: Typeof Trap
>> >
>> >
>> >
>> > Those two PRs are about removing implementation-defined behavior from
>> `typeof`, making it *more* reliable - there is no trend away from using and
>> relying on `typeof`, full stop.
>> >
>> >
>> >
>> > `Symbol.hasInstance` is a part of why `instanceof` is actually
>> unreliable - because user code can hook into it. It would be a massive loss
>> imo if `typeof` lost its bulletproof status by adding a user hook.
>> >
>> >
>> >
>> > On Sat, Jul 27, 2019 at 12:37 PM Michael Haufe 
>> wrote:
>> >
>> > The trend seems to be to rely on typeof less and less as time passes:
>> >
>> >
>> >
>> > From the  March 2019 Agenda <
>> https://github.com/tc39/agendas/blob/274e49412c09f81a0a82f386e6eead481c69adad/2019/03.md
>> >:
>> >
>> >
>> >
>> > “Implementation-defined typeof still necessary?”
>> > 

Re: Promise resolution handler fires before synchronous constructor stack has finished.

2019-07-28 Thread Ranando King
Isn't it always the case that `Promise.resolve()` returns an immediately
resolved Promise? That means that the `.then` clause would get executed
immediately as well, which is before you have a chance to set `this.foo`.

Seems like what you need to do is something more like this:
```js
// class Foo
constructor() {
  (new Promise((resolve, reject) => { setTimeout(() => { resolve(); },1);
})).then(() => {
this.methodThatSubclassOverrides()
  })
}
```
Done this way, the call to `resolve()` will be thrown onto the run loop for
execution later.

On Sat, Jul 27, 2019 at 8:57 PM #!/JoePea  wrote:

> I feel like I'm going crazy, but I have a class hierarchy, and one of
> the constructors in the hierarchy defers some logic to a microtask,
>
> ```js
> // class Foo
> constructor() {
>   Promise.resolve().then(() => {
> this.methodThatSubclassOverrides()
>   })
> }
>
> methodThatSubclassOverrides() {}
> ```
>
> and in the subclass there is
>
> ```js
> // class Bar extends Foo
> constructor() {
>   super()
>   this.foo = 123
> }
>
> methodThatSubclassOverrides() {
>   console.log(this.foo) // should be "123"
> }
> ```
>
> You'd think the output should be "123" because the deferred code will
> run after construction is complete.
>
> However, in my current project, the promise deferral seems to run
> before the construction returns to the Bar constructor, thus this.foo
> is not set, and calls `methodThatSubclassOverrides` before the Bar
> class has a chance to run `this.foo = 123`. So the result of the
> console.log is "undefined".
>
> It is totally weird. Do Promises ever resolve before a constructor
> stack finishes?
>
> I don't have a simple reproduction at the moment.
>
> - Joe
> ___
> 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: Typeof Trap

2019-07-27 Thread Ranando King
What good is the reliability of something that is more often than not
useless?

Should there be a typeof hook like Symbol.hasInstance? No. `instanceof` was
always sketchy due to the ability to exchange prototypes on an object. When
`class` came along, it became effectively broken since `class` provides no
facility for transfixing the prototype attached to an instance.

On the other hand, `typeof` never had such issues. Unfortunately, when
`class` came along, nothing was done to allow `typeof` to treat classes as
unique types. That was disappointing. However, adding a hook means that
`typeof` would lose its stability and predictability, making it essentially
as useless as `instanceof`. If instead, the two changes I just mentioned
were made, then `typeof` would even be able to supplant `instanceof`
without losing any of its reliability. Just a thought...

On Sat, Jul 27, 2019 at 3:57 PM Jordan Harband  wrote:

> With something that while unintuitive in one case, is eternally robust and
> reliable.
>
> If you want extensibility, define Symbol.toStringTag on your objects.
>
> On Sat, Jul 27, 2019 at 1:23 PM Michael Haufe 
> wrote:
>
>> If it's unfixably broken[1], non-extensible, excessively vague, and
>> non-orthogonal, where does that leave you?
>>
>>
>>
>> [1] 
>>
>>
>>
>> *From:* Jordan Harband 
>> *Sent:* Saturday, July 27, 2019 3:00 PM
>> *To:* Michael Haufe 
>> *Cc:* ViliusCreator ; es-discuss@mozilla.org
>> *Subject:* Re: Proposal: Typeof Trap
>>
>>
>>
>> Those two PRs are about removing implementation-defined behavior from
>> `typeof`, making it *more* reliable - there is no trend away from using and
>> relying on `typeof`, full stop.
>>
>>
>>
>> `Symbol.hasInstance` is a part of why `instanceof` is actually unreliable
>> - because user code can hook into it. It would be a massive loss imo if
>> `typeof` lost its bulletproof status by adding a user hook.
>>
>>
>>
>> On Sat, Jul 27, 2019 at 12:37 PM Michael Haufe 
>> wrote:
>>
>> The trend seems to be to rely on typeof less and less as time passes:
>>
>>
>>
>> From the  March 2019 Agenda <
>> https://github.com/tc39/agendas/blob/274e49412c09f81a0a82f386e6eead481c69adad/2019/03.md
>> >:
>>
>>
>>
>> “Implementation-defined typeof still necessary?” <
>> https://github.com/tc39/ecma262/issues/1440>
>>
>> “Normative: Remove implementation-defined typeof behavior” <
>> https://github.com/tc39/ecma262/pull/1441>
>>
>>
>>
>>
>>
>> The only real discussion around this I can find is from a related
>> proposal from Brendan Eich a few years ago:
>>
>>
>>
>>
>> https://esdiscuss.org/topic/typeof-extensibility-building-on-my-value-objects-slides-from-thursday-s-tc39-meeting
>>
>>
>>
>>
>>
>>
>>
>> *From:* ViliusCreator 
>> *Sent:* Saturday, July 27, 2019 2:04 PM
>> *To:* Michael Haufe 
>> *Subject:* RE: Proposal: Typeof Trap
>>
>>
>>
>> *Yes, but it traps `typeof `, not `instanceof`. There’s difference there.*
>>
>> ___
>> 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: First-class Multi-threading support

2019-04-25 Thread Ranando King
Devil's Advocate time

What can you get from threading that you can't already get on a single
thread? If I subclass Promise, make all of the relevant functions return
this customized promise, I can create fairly easy to debug code that
behaves as though it is multithreaded. I can even go 1 step further and do
this for all of my code and essentially turn each function into a
stand-alone fiber. Like this, I can get the benefit of thread-like behavior
without the engine having to carry the burden of maintaining thread
contexts on top of its own script contexts.

On Thu, Apr 25, 2019 at 1:41 PM Chinenye Onuegbu  wrote:

> I am not exactly sure why multi-threading support in JavaScript has been
> avoided, even though there is a strong case for real multi-threading
> support in JavaScript. This is usually reflected in the race to fit every
> event callback within 16ms to avoid dropping frames.
>
> To cover for some of these deficiencies, web workers, worker_threads,
> process.fork, etc have been introduced in the past, all of which are
> cumbersome to use. I understand that multi-threading is difficult to get
> right, and it provides a number of challenges including making it easy to
> create difficult-to-debug bugs, but I am of the opinion that we can at
> least start a discussion on this.
>
> In light of this, I created a draft of what I think is a "safe" way to add
> "user-space", first-class multi-threading support in JavaScript. The link
> to the gist:
> https://gist.github.com/xkizer/d63ac72ef48720c2066fbc9d3580ea90
>
> A few things to note:
> 1. I am not an expert in multi-threading, and could have made some
> otherwise obvious wrong assumptions/blunders
> 2. I am not an expert in JS engines, and do not know how easy/difficult
> these are to actually bring to fruition
>
> I am looking for comments and constructive criticisms. Thanks in advance.
> --
> Kizer
> ___
> 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: Static Typing

2019-04-05 Thread Ranando King
Similar but not the same. Within any given scope, a Type declared within
that scope would need to be "set-in-stone" to be of any value. Furthermore,
for a variable to honor that type, it must be able to carry around an
unmodified reference to the tyoe as it existed at the time the variable was
declared. If either one of these two conditions is not met, then the type
system cannot claim to be static. It would be more of an "advisory" dynamic
type system, where the specified type gives the engine a hint on what kind
of data will be stored in a given variable.

On Fri, Apr 5, 2019 at 1:51 PM guest271314  wrote:

> Similar concepts is not being able to re-declare a variable in any scope,
> or a "Scope Controller"
>
> - Why does .then() chained to Promise.resolve() allow const declaration
> to be reassigned?
> 
>
> -
> https://stackoverflow.com/questions/54776759/how-to-avoid-accidentally-implicitly-referring-to-properties-on-the-global-objec
>
> ___
> 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: Static Typing

2019-04-05 Thread Ranando King
>  That should solves all cases, right?

Only if a non `:any` type **must** extend `Typed()`. Put another way:

class MyType extends Typed {}
class OtherType {}

let a: any = new Object; //Valid
let b: OtherType; //Error: Invalid type specification
let c: MyType = new Object; //Error: Invalid cast assignment
let d: MyType = new MyType; //Valid


On Fri, Apr 5, 2019 at 3:44 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> we could add a `Typed` primitive every typed value inherits from, similar
> way every object implicitly inherits from `Object` these days.
>
> That, by contract, would disallow any prototype related operation to
> either classes or instances, and it will simplify the
> `Reflect.isTyped(thing)` algo.
>
> class MyType extends Typed {}
> const num:i32 = 123;
>
> the `MyType` class, and every instance of it, cannot have mutated
> prototype, and so cannot the `num`.
>
> Typed values will be all shortcuts that behave like a Typed instance.
>
> That should solves all cases, right?
>
>
>
>
>
> On Thu, Apr 4, 2019 at 8:52 PM Ranando King  wrote:
>
>> >  if we base any assumption only to the current highly dynamic nature of
>> JS we won't go too far.
>>
>> Problem is that if we infringe on the "current highly dynamic nature of
>> JS", we'll end up breaking valuable use cases. Any new feature added should
>> always be 100% compatible with the non-competing portions of the existing
>> language.
>>
>> > I think the mutable prototype issue can be solved through static
>> classes where no changes would be possible and all instances would be
>> immune to `setPrototypeOf`
>>
>> That solves half of the problem. What of the other half (`Type v =
>> "somevalue";` where `Type` is not a static class)? With your approach, that
>> would need to be restricted to solve the other half. Otherwise, you'd still
>> be facing the issues Waldemar spoke about.
>>
>> On Thu, Apr 4, 2019 at 2:49 AM Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> If something is missing, let's move forward finding out solutions,
>>> 'cause if we base any assumption only to the current highly dynamic nature
>>> of JS we won't go too far.
>>>
>>> As example, I think the mutable prototype issue can be solved through
>>> static classes where no changes would be possible and all instances would
>>> be immune to `setPrototypeOf`
>>>
>>> ```
>>> static class MyType {}
>>>
>>> Reflect.setPrototypeOf(MyType, Array); // nope
>>> Reflect.setPrototypeOf(new MyType, []); // nope
>>> ```
>>>
>>> we'll also need a `Reflect.isTyped(ref)` in case we'd like to throw
>>> errors on prototype set attempts.
>>>
>>>
>>>
>>> On Thu, Apr 4, 2019 at 6:11 AM Ranando King  wrote:
>>>
>>>> > - If you allow user-defined types, objects can spontaneously change
>>>> their type by mutating their prototype.  Thus, you can declare a variable x
>>>> to have type Foo and check that you're assigning an instance of Foo to it,
>>>> but the value x can become a Bar (different from a Foo) spontaneously
>>>> without any operations on x.
>>>>
>>>> At least for static typing, the engine will need to freeze a copy of
>>>> the class definition at the time when the static type is referenced. That
>>>> frozen type will be associated with the variable in a fixed way, making all
>>>> attempts to change the type of the variable fail. Also, that would need to
>>>> divorce the frozen type from the dynamic version so the dynamic version can
>>>> still be mutated. That concept should work, but it might prove to be
>>>> ridiculously complicated since it risks a proliferation of objects all of
>>>> type Foo but with different type definitions. One way to get around that is
>>>> to flag a type as static the first time it is used in a statically typed
>>>> variable definition. This would cause an error to be thrown should any part
>>>> of the class be altered. Not sure how workable that is.
>>>>
>>>> > but that begs the question of what is the type of just ['a', 'b'].
>>>>
>>>> It should be any[]. Typing should be as non-aggressive as possible.
>>>> Auto typing should only consider the top level data to determine the type,
>>>> and in this case, that's an Array. To make c restricted to string elements,
>>>> the type would need to be specified as string[].
>&

Re: Proposal: Static Typing

2019-04-04 Thread Ranando King
>  if we base any assumption only to the current highly dynamic nature of
JS we won't go too far.

Problem is that if we infringe on the "current highly dynamic nature of
JS", we'll end up breaking valuable use cases. Any new feature added should
always be 100% compatible with the non-competing portions of the existing
language.

> I think the mutable prototype issue can be solved through static classes
where no changes would be possible and all instances would be immune to
`setPrototypeOf`

That solves half of the problem. What of the other half (`Type v =
"somevalue";` where `Type` is not a static class)? With your approach, that
would need to be restricted to solve the other half. Otherwise, you'd still
be facing the issues Waldemar spoke about.

On Thu, Apr 4, 2019 at 2:49 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> If something is missing, let's move forward finding out solutions, 'cause
> if we base any assumption only to the current highly dynamic nature of JS
> we won't go too far.
>
> As example, I think the mutable prototype issue can be solved through
> static classes where no changes would be possible and all instances would
> be immune to `setPrototypeOf`
>
> ```
> static class MyType {}
>
> Reflect.setPrototypeOf(MyType, Array); // nope
> Reflect.setPrototypeOf(new MyType, []); // nope
> ```
>
> we'll also need a `Reflect.isTyped(ref)` in case we'd like to throw errors
> on prototype set attempts.
>
>
>
> On Thu, Apr 4, 2019 at 6:11 AM Ranando King  wrote:
>
>> > - If you allow user-defined types, objects can spontaneously change
>> their type by mutating their prototype.  Thus, you can declare a variable x
>> to have type Foo and check that you're assigning an instance of Foo to it,
>> but the value x can become a Bar (different from a Foo) spontaneously
>> without any operations on x.
>>
>> At least for static typing, the engine will need to freeze a copy of the
>> class definition at the time when the static type is referenced. That
>> frozen type will be associated with the variable in a fixed way, making all
>> attempts to change the type of the variable fail. Also, that would need to
>> divorce the frozen type from the dynamic version so the dynamic version can
>> still be mutated. That concept should work, but it might prove to be
>> ridiculously complicated since it risks a proliferation of objects all of
>> type Foo but with different type definitions. One way to get around that is
>> to flag a type as static the first time it is used in a statically typed
>> variable definition. This would cause an error to be thrown should any part
>> of the class be altered. Not sure how workable that is.
>>
>> > but that begs the question of what is the type of just ['a', 'b'].
>>
>> It should be any[]. Typing should be as non-aggressive as possible. Auto
>> typing should only consider the top level data to determine the type, and
>> in this case, that's an Array. To make c restricted to string elements, the
>> type would need to be specified as string[].
>>
>> > If you follow this to its logical conclusion and think about what the
>> types of various methods that work on arrays should be, you end up with an
>> enormous and confusing variety of array and object types, which is
>> something we explored years ago.
>>
>> Maybe, but that's always the case with any type system that allows for
>> user-defined types. The main problem here is the memory requirements for
>> storing all of those types. If I remember the description of V8 internals,
>> it seems to have already managed this issue. At least in V8, the challenge
>> would be in permanently associating a specific evolution of an internal
>> type to a variable.
>>
>> On Wed, Apr 3, 2019 at 7:50 PM Waldemar Horwat 
>> wrote:
>>
>>> On 3/23/19 1:34 PM, IdkGoodName Vilius wrote:
>>> > This is a proposal for static typing. Here is the github repository
>>> link: https://github.com/CreatorVilius/Proposal-Static-Typing
>>> > I think it would be great thing in JS.
>>>
>>> We intentionally reserved syntax so that something like that would be
>>> possible in the future.
>>>
>>> I've also spent a lot of time working on past proposals to do such
>>> things.  A few interesting issues would invariably arise that make both
>>> static and runtime typing unsound:
>>>
>>> - If you allow user-defined types, objects can spontaneously change
>>> their type by mutating their prototype.  Thus, you can declare a variable x
>>> to have type Foo and check that yo

Re: Proposal: Static Typing

2019-04-03 Thread Ranando King
> - If you allow user-defined types, objects can spontaneously change their
type by mutating their prototype.  Thus, you can declare a variable x to
have type Foo and check that you're assigning an instance of Foo to it, but
the value x can become a Bar (different from a Foo) spontaneously without
any operations on x.

At least for static typing, the engine will need to freeze a copy of the
class definition at the time when the static type is referenced. That
frozen type will be associated with the variable in a fixed way, making all
attempts to change the type of the variable fail. Also, that would need to
divorce the frozen type from the dynamic version so the dynamic version can
still be mutated. That concept should work, but it might prove to be
ridiculously complicated since it risks a proliferation of objects all of
type Foo but with different type definitions. One way to get around that is
to flag a type as static the first time it is used in a statically typed
variable definition. This would cause an error to be thrown should any part
of the class be altered. Not sure how workable that is.

> but that begs the question of what is the type of just ['a', 'b'].

It should be any[]. Typing should be as non-aggressive as possible. Auto
typing should only consider the top level data to determine the type, and
in this case, that's an Array. To make c restricted to string elements, the
type would need to be specified as string[].

> If you follow this to its logical conclusion and think about what the
types of various methods that work on arrays should be, you end up with an
enormous and confusing variety of array and object types, which is
something we explored years ago.

Maybe, but that's always the case with any type system that allows for
user-defined types. The main problem here is the memory requirements for
storing all of those types. If I remember the description of V8 internals,
it seems to have already managed this issue. At least in V8, the challenge
would be in permanently associating a specific evolution of an internal
type to a variable.

On Wed, Apr 3, 2019 at 7:50 PM Waldemar Horwat  wrote:

> On 3/23/19 1:34 PM, IdkGoodName Vilius wrote:
> > This is a proposal for static typing. Here is the github repository
> link: https://github.com/CreatorVilius/Proposal-Static-Typing
> > I think it would be great thing in JS.
>
> We intentionally reserved syntax so that something like that would be
> possible in the future.
>
> I've also spent a lot of time working on past proposals to do such
> things.  A few interesting issues would invariably arise that make both
> static and runtime typing unsound:
>
> - If you allow user-defined types, objects can spontaneously change their
> type by mutating their prototype.  Thus, you can declare a variable x to
> have type Foo and check that you're assigning an instance of Foo to it, but
> the value x can become a Bar (different from a Foo) spontaneously without
> any operations on x.
>
> - Something similar happens with trying to type arrays.  You wrote:
>
> let c: auto = ['a', 'b']  // c is now string[]
>
> but that begs the question of what is the type of just ['a', 'b'].
>
> - Is it string[]?  No, it can't be that because you can replace its second
> element with a number.
> - Is it any[]?  Well, in that case c should have type any[], not string[]
> - Is it object?  In that case c should have type Object.
> and so on.
>
> If you follow this to its logical conclusion and think about what the
> types of various methods that work on arrays should be, you end up with an
> enormous and confusing variety of array and object types, which is
> something we explored years ago.  In some cases you'd want structural
> types, in some cases you'd want 'like' types (an array of anything which
> just happens to hold numbers at the moment), and so on.
>
>  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: Static Typing

2019-03-27 Thread Ranando King
> Would an error at runtime or compiletime occur here?

There's no "compile time" per se in ES, but setting b += '1' when b is
strictly typed shouldn't throw an error at all. The type of the '1' would
be coerced to a number first, then added to b.

If instead it was something like
```js
let a: string = "1";
let b: number = 2;
b += a; //TypeError
```
This would cause an error because it would be invalid to coerce a into a
number.

> If it is a runtime error, is it optimal for the engine to keep track of
typed variables vs regular for the same value?

Engines like V8 already keep track of the type of variables. Static typing
would simply add a flag to these types that prevents type coercion if set.

On Wed, Mar 27, 2019 at 7:20 PM guest271314  wrote:

>
>
> -- Forwarded message -
> From: guest271314 
> Date: Thu, Mar 28, 2019 at 12:19 AM
> Subject: Re: Proposal: Static Typing
> To: Claude Pache 
>
>
>
> > `a = object[Math.random() < 0.5 ? "method_returning_number" :
> "method_returning_string"]()`
>
> Interesting case. See also
>
> How do I check if a JavaScript function returns a Promise?
>> 
>
> Say I have two functions:
>> ```function f1() {
>> return new Promise((resolve, reject) => {
>> resolve(true);
>> });
>> }
>> function f2() {
>> }```
>> How do I know if f1 will return Promise and f2 will not?
>
>
> Can a regular expression be crafted which determines the return type of a
> function? 
>
> Has it been mathematically proven that antivirus can't detect all viruses?
> 
>
> On Wed, Mar 27, 2019 at 6:10 PM Claude Pache 
> wrote:
>
>>
>>
>> Le 27 mars 2019 à 18:26, Michael Theriot 
>> a écrit :
>>
>> Would an error at runtime or compiletime occur here?
>>
>>
>> The check cannot be reliably done at compile time in general; it must be
>> a runtime check. (Tools may provide partial static analysis, but that’s an
>> extra.)
>>
>> The simplest reason is that statically typed code must run together with
>> non-statically typed code.
>>
>> And even ignoring legacy code, it is not desirable to have static types
>> everywhere; for instance, `Array.prototype.sort()` must continue to work
>> with both arrays of strings and arrays of numbers, and even with arrays of
>> mixed types.
>>
>> And even if everything everywhere was statically typed, you still cannot
>> statically analyse situations like: `a = object[Math.random() < 0.5 ?
>> "method_returning_number" : "method_returning_string"]()`.
>>
>> If it is a runtime error, is it optimal for the engine to keep track of
>> typed variables vs regular for the same value?
>>
>>
>> Today’s JS engines typically do already clever speculative optimisations
>> based on expected types. For example:
>> https://stackoverflow.com/a/46144917. So, I guess, it depends...
>>
>> —Claude
>>
>> ___
>> 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: Static Typing

2019-03-25 Thread Ranando King
Doesn't V8 already use such a concept to manage optimization? When a
reference's structure mutates, V8 generates a new type by extending the
previous one with the changes, then kills any affected optimizations around
the mutated object, forcing re-optimization. Static types would essentially
provide a guarantee that such re-optimizations would be completely
unnecessary for the lifetime of the object since it would be impossible to
mutate the object's structure. It would also allow for early optimization
since the structure would already be known. These are the benefits of
static typing. It's not just a matter of developer trust but also engine
efficiency.

On Tue, Mar 26, 2019 at 12:21 AM Randy Buchholz 
wrote:

> I recently started doing a lot of ES, coming from C# and really missed
> “typings” at first. But once I learned to think more in es,  they became
> less necessary – even cumbersome in some ways. The question for me on this
> really comes down to what is a ”type” and what value does it bring. As I
> see it, a type is a structural contract, in the same way an interface is a
> behavioral contract. The value of contracts is that they minimize the need
> to trust. I.e., if I pass a known-type to a function, I can know that it
> will have a specific structure (e.g., known properties and methods in a
> class).  Without types, I must trust or check the structure. But, types
> aren’t really self-aware. It is the environment that enforces types. Once
> you have types, you must have what I call a “Type Authority”. Built-in
> types are always known by the authority, and when you declare a type,  you
> are adding to what the authority knows. The authority can look at the code
> and do the “checking” of what is passed based on what it knows. Having
> types lets me not have to trust in what I am receiving – it can be verified
> for me.
>
>
>
> In a compiled language, types provide “hidden” value. The compiler can
> look at the entire code based and make optimization decisions around types
> (e.g., in-lining). In a dynamic, interpreted language, (for the most part)
> this doesn’t happen. Types must be processed at each point of use. So, the
> value of types stays mostly limited to knowing the structure. Which is
> though, extremely useful. The problem with static types, is that they exist
> at the wrong place in time. A static type is a design-time constraint. Yet
> the environment doesn’t really know about the type until each run-time use.
> This puts unnecessary limits on the language – adding a property at
> run-time (while scary at first) is one of my favorite features of the
> language. Static typing adds other layers of complexity – like namespaces.
> Locking down a type at design-time essentially “hijacks” a name. A static
> type “Person” must be consistent across the entire application environment.
> In uses like Web, where it is common to pull code from many remote sources
> and libraries,  how does “Person” remain “static” across these?
>
>
>
> I would propose an alternative to static typing – the Type Authority. The
> Type Authority is a architecture component that (among other things)
> provides “scoped/run-time statics”. Essentially, the Type Authority is an
> application-wide dynamic repository of types, in the run-time environment.
> This opt-in feature would allow dynamically creating types, and then making
> them “fixed” them with application scope. Once registered, the type is
> basically static. Using a hierarchal approach and “dotted” naming notation,
> (e.g., library.component.typename) types can be localized or extended. For
> example, a library can be imported, and types given a “namespace prefix”.
> The qualified name would effectively be a static type within the
> application context. Properties could be dynamically added, and the new
> type registered as a ”child type” (e.g., Person => Person.Domain). This
> would then allow casting - (Person)DomainPersonInstance. A simple Type
> Authority would support basic “is a”/”typeof” capabilities. A more advanced
> system could provide factory methods.
>
>
>
> This approach provides a way to enforce the structural contract nature of
> types, while retaining the dynamic nature of the language.
> ___
> 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: Static Typing

2019-03-24 Thread Ranando King
One thing is definitively true. Any static type system added to ES must not
be mandatory. Untyped code must be able to call typed code without forcing
references into a fixed type. Likewise, typed code must be able to call
untyped code without forcing references to give up type guarantees.

On Sun, Mar 24, 2019 at 8:48 PM kai zhu  wrote:

> i share a similar concern that static-typing makes little sense in
> high-churn-rate UX-workflow-programming.
>
> it encourage people to bikeshed for correctness, on low-level code that
> frequently gets rewritten every few weeks/months -- and with often
> demoralizing effects.
>
> > On 24 Mar 2019, at 17:26, Bergi  wrote:
> >
> > Hello,
> > to play the devils advocate: why does JavaScript need static typing?
> >
> > Your proposal doesn't really answer that. Sure, it mentions tooling and
> > IDEs that can provide you with type hints and complain on mistakes, but
> > things like Flow and Typescript do this today already.
> > What's your goal, to have JS engines run Typescript(-like) code natively
> > without transpiling? For backwards-compatibility you'd have to do that
> > anyway, especially if new type system features are introduced
> incrementally.
> >
> > What's the point of building this feature into engines? It just provides
> > additional complexity. Not to mention the difficulty of finding a
> > suitable type system that is both sophisticated enough to describe all
> > useful code (not taking away too much flexibility) and simple enough to
> > understand without a CS degree. And which interfaces well with un-typed
> > completely dynamic code.
> >
> > What does "static typing" even mean to you in a dynamic scripting
> > language? JavaScript is not compiled by the developer, it is run by the
> > user. Where (when) do you expect types to be checked? Should the engine
> > throw early errors (during parsing)? During parsing of which parts of
> > the code, even when "normal" (untyped) code is calling into typed code?
> > Or do you expect dynamic runtime errors, like when assigning an invalid
> > value to a "typed variable" or calling a "typed function" with wrong
> > arguments? Are type definitions completely constant or could they be
> > mutated/extended/etc dynamically (and what happens when you introduce
> > new types with `eval` or by loading another script)?
> >
> > A proposal would need to provide an objective that answers all these
> > questions, before even considering any particular type system or syntax.
> >
> > One way to go forward that I can see would be a proposal that reserves a
> > relatively unrestricted syntax for type annotations (which are already
> > considered during every grammar amendment anyway, for compatibility with
> > Flow/Typescript), but not assign any semantics to them and require
> > engines to simply ignore them. External tooling could then use these
> > annotations according to its own rules.
> >
> > kind regards,
> > Bergi
> > ___
> > 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: Destructuring for Array-like objects

2019-03-19 Thread Ranando King
Why is that any different or better than

const [a, b] = [a, b]

?

On Tue, Mar 19, 2019 at 7:59 PM Sultan  wrote:

> Afford array destructuring to Array-like objects.
>
> const [a, b] = {0: a, 1: b, length: 2}
>
>
> ___
> 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 For A New Alternative Keyword To “this” For Classes

2019-03-12 Thread Ranando King
@Isiah Remember, the class-fields proposal has absorbed the private-fields
proposal, and it is those private fields that have no precise equivalent.
WeakMap and closures can approximate what private fields do. However,
private fields has semantics and capabilities that cannot be fully
reproduced in current ES. For instance, I can wrap both WeakMap and Proxy
in a way that Babel private-fields will be proxy safe. With native private
fields, that's impossible.

On Tue, Mar 12, 2019 at 10:39 AM Isiah Meadows 
wrote:

> @Ranando Minor nit: class fields can be purely implemented in terms of
> `defineProperty` (for public) and weak maps (for private - what's used
> today for private data). Private methods could be implemented in terms of
> weak sets/maps and an object with methods outside the class's scope.
> Private static properties could just verify `this === Type`.
>
> So no, those don't quite reify classes, either. (If something can be fully
> transpiled or polyfilled, it doesn't create or reify any new primitives.)
>
> On Tue, Mar 12, 2019 at 09:51 Ranando King  wrote:
>
>> I get what you're after. I touched on the same things when creating my
>> private members proposal. The best of approaches for what you want is
>> indeed relying on the lexical scope to act as a binding for all class
>> members. There's just a couple of problems with doing things that way:
>>
>> 1. ES is a dynamic language. This makes lexical binding difficult because
>> it's entirely possible to call a non-static class method where *this* is
>> undefined or null. Not allowing for that scenario will break existing code.
>> Allowing for that scenario will cause variables to be unexpectedly either
>> written to the global scope or throw.
>> 2. Class isn't really a "thing" in ES, at least, it isn't until
>> class-fields lands. The use of the *class* keyword is currently
>> completely optional. There's nothing in current ES that you can do with
>> *class* that can't be done without it except use the *super()* call in
>> the constructor function. But even that can be substituted with
>> *Reflect.construct*(). Class-fields will destroy this symmetry, making
>> *class* it's own unique "thing". But until then, what do you do about
>> all the "classes" that don't use the *class* keyword?
>>
>> Long and short, this means both the lexical scope approach and the
>> alternate keyword approach will either break existing code or bring
>> dubious-to-no benefit.
>>
>> On Tue, Mar 12, 2019 at 3:06 AM john larson 
>> wrote:
>>
>>> So in terms of implementation, may be having instance method/property
>>> references on the objects and having static method/property references on
>>> the prototype is the solution?
>>>
>>> On Tue, Mar 12, 2019 at 8:14 AM Isiah Meadows 
>>> wrote:
>>>
>>>> I've done a little engine work, and inline caches work by inline type
>>>> maps based on the callee site. This *can* be used to reconstruct values +
>>>> receivers, but only when the value is constant. It is not sufficient to
>>>> ensure identity remains the same, and engines would still need a weak map
>>>> to link methods to instances (as opposed to prototypes).
>>>>
>>>> It's worth noting not even Java or Ruby offers this - their method
>>>> references/objects (like our bound functions) are *not* memoized - they're
>>>> linked to classes, not instances. Python is the exception here in
>>>> auto-binding instance methods, not the norm.
>>>> On Mon, Mar 11, 2019 at 15:37 Bergi  wrote:
>>>>
>>>>> Hi John!
>>>>> > I think the js run-time already has that information at hand, so as
>>>>> > long as we don't implement this as pure syntactical sugar, there
>>>>> would
>>>>> > not be a need to keep an extra reference to anything, because it
>>>>> would
>>>>> > be already there. The run-time will know which instance the invoked
>>>>> > method belongs to.
>>>>>
>>>>> Well no, you're wrong here: the runtime does not have this information
>>>>> at hand. In your example (simplified)
>>>>> ```
>>>>> var reqManager = new RequestManager();
>>>>> function addEventListener(f) {
>>>>>  console.log(f);
>>>>>  f(event);
>>>>> }
>>>>> addEventListener(reqManager.responseHandler);
>>>>> ```
>>>>> the `addEventListener` function 

Re: Proposal For A New Alternative Keyword To “this” For Classes

2019-03-12 Thread Ranando King
I get what you're after. I touched on the same things when creating my
private members proposal. The best of approaches for what you want is
indeed relying on the lexical scope to act as a binding for all class
members. There's just a couple of problems with doing things that way:

1. ES is a dynamic language. This makes lexical binding difficult because
it's entirely possible to call a non-static class method where *this* is
undefined or null. Not allowing for that scenario will break existing code.
Allowing for that scenario will cause variables to be unexpectedly either
written to the global scope or throw.
2. Class isn't really a "thing" in ES, at least, it isn't until
class-fields lands. The use of the *class* keyword is currently completely
optional. There's nothing in current ES that you can do with *class* that
can't be done without it except use the *super()* call in the constructor
function. But even that can be substituted with *Reflect.construct*().
Class-fields will destroy this symmetry, making *class* it's own unique
"thing". But until then, what do you do about all the "classes" that don't
use the *class* keyword?

Long and short, this means both the lexical scope approach and the
alternate keyword approach will either break existing code or bring
dubious-to-no benefit.

On Tue, Mar 12, 2019 at 3:06 AM john larson 
wrote:

> So in terms of implementation, may be having instance method/property
> references on the objects and having static method/property references on
> the prototype is the solution?
>
> On Tue, Mar 12, 2019 at 8:14 AM Isiah Meadows 
> wrote:
>
>> I've done a little engine work, and inline caches work by inline type
>> maps based on the callee site. This *can* be used to reconstruct values +
>> receivers, but only when the value is constant. It is not sufficient to
>> ensure identity remains the same, and engines would still need a weak map
>> to link methods to instances (as opposed to prototypes).
>>
>> It's worth noting not even Java or Ruby offers this - their method
>> references/objects (like our bound functions) are *not* memoized - they're
>> linked to classes, not instances. Python is the exception here in
>> auto-binding instance methods, not the norm.
>> On Mon, Mar 11, 2019 at 15:37 Bergi  wrote:
>>
>>> Hi John!
>>> > I think the js run-time already has that information at hand, so as
>>> > long as we don't implement this as pure syntactical sugar, there would
>>> > not be a need to keep an extra reference to anything, because it would
>>> > be already there. The run-time will know which instance the invoked
>>> > method belongs to.
>>>
>>> Well no, you're wrong here: the runtime does not have this information
>>> at hand. In your example (simplified)
>>> ```
>>> var reqManager = new RequestManager();
>>> function addEventListener(f) {
>>>  console.log(f);
>>>  f(event);
>>> }
>>> addEventListener(reqManager.responseHandler);
>>> ```
>>> the `addEventListener` function will not know that the function `f` you
>>> passed was a method of the `reqManager` instance. It cannot distinguish
>>> that call from
>>> ```
>>> addEventListener(RequestManager.prototype.responseHandler);
>>> ```
>>> or
>>> ```
>>> var g = otherReqManager.responseHandler;
>>> addEventListener(g);
>>> ```
>>>
>>> It is exactly the same function that is passed in all three cases. There
>>> is no instance bound to `f`, and `f(event)` will not invoke it as a
>>> method (with a receiver/`this` value).
>>>
>>> Best regards,
>>>   Bergi
>>> ___
>>> es-discuss mailing list
>>> es-discuss@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: throw null operator

2019-02-25 Thread Ranando King
Wasn't there a proposal that tend to allow for optional access of undefined
fields?
```js
let a = { foo:  "bar" };
let b = a.bar?.alpha; // b == undefined
```
The point, I believe, was to eliminate the field testing sometimes required
to find a nested sub-element, and simply return undefined if any branch
property wasn't an object.

To me, the OP here is asking for a very similar operation, causing the
"throw" action to be abandoned if the parameter doesn't exist, just as in
the above example, the [[GET]] operation would be abandoned and return
undefined.

On Sun, Feb 24, 2019 at 10:03 AM Isiah Meadows 
wrote:

> Not sure what the benefit is over just `if (value != null) throw value`,
> especially for this niche of a use case.
> On Sun, Feb 24, 2019 at 09:46 IdkGoodName Vilius <
> viliuskubilius...@gmail.com> wrote:
>
>> I am proposing a syntatic sugar, which would check if throw value is not
>> null, or not undefined. It would make less typing and no if, for throw
>> statements. Syntax is simple. Here's an example of it:
>> ```js
>> throw? e
>> ```
>> This is basically equivalent to:
>> ```js
>> if(e !== null && e !== undefined) throw e
>> ```
>> What's the purpose of that? Well, in some node js modules, error as null,
>> or undefined is sometimes passed.
>> Example of that is:
>> ```js
>> const {exec} = require('child_process')
>> exec('...', {cwd: '...'}, (err, stdout, stderr) => {
>> if(err !== null) throw err
>> })
>> ```
>>
>>
>> 
>>  Virus-free.
>> www.avast.com
>> 
>> <#m_2762807433789550130_m_-3729250569814530580_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
>> ___
>> 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: Default object method

2019-01-28 Thread Ranando King
Isiah: good find. I was just being sloppy to get the idea across.

J. Decker: The code I gave was just an example of how to do it if it was
for some reason absolutely necessary to use `class`. I don't see the need
and would either tend toward your approach, or just somehow refactor away
the need for the odd construction.

On Mon, Jan 28, 2019 at 6:46 AM J Decker  wrote:

>
>
> On Sun, Jan 27, 2019 at 10:46 PM Ranando King  wrote:
>
>> Jordan's right. This one is best handled by a function. But if there is
>> some reason you need to create callable objects, it's still doable, even
>> with ES as-is. Just extend your classes from something like this:
>>
>> ```js
>> class Callable {
>>constructor(defaultFn) {
>>   return (...args) => { return defaultFn.call(this, ...args); };
>>}
>> }
>> ```
>> Any class extending this will have instances that are functions. So using
>> your UserCreator class...
>>
>> ```js
>> class UserCreator extends Callable {
>>   constructor(repository) {
>> super(this.create);
>> this.repository = repository;
>>   }
>>
>>   create(name) {
>>  return this.repository.createUser(name);
>>   }
>> }
>> ```
>>
>
> Can't you just use a function object?
>
> function UserCreator(repository) {
>  if( !(this instanceof UserCreator ) ) return new
> UserCreator(repostiory);
> var creator = function xyz(name) {
>  return { repo: repository, user: name }
> }:
> creator.repository = repository;
> creator.create = creator
> return   creator;
> }
>
>
>>
>> Now `new UserCreator(someRepo)(someName)` is the same as `new
>> UserCreator(someRepo).create(someName)`.
>>
>
> both of the above also work that way.
>
>
>>
>> On Sun, Jan 27, 2019 at 11:35 PM Jordan Harband  wrote:
>>
>>> Something that can be invoked has a `[[Call]]` slot, and is `typeof`
>>> "function".
>>>
>>> Adding a Symbol that makes something callable would have a number of
>>> effects - it would make `typeof` (one of the most robust operations in the
>>> language) unsafe, because it would have to access the Symbol method, which
>>> could be a throwing getter (or even one that just logs how many typeofs are
>>> called on it). Additionally, it would mean any object could become
>>> callable, and any function could be made *un* callable.
>>>
>>> This seems like a pretty large change, solely to avoid "classes with a
>>> single method", which arguably should just be a function in the first place.
>>>
>>> On Sun, Jan 27, 2019 at 4:05 PM Brasten Sager 
>>> wrote:
>>>
>>>> Apologies if this has been raised before. I was unable to locate
>>>> anything similar.
>>>>
>>>> Any thoughts or ideas on this proposal would be appreciated!
>>>>
>>>> Original:
>>>> https://gist.github.com/brasten/f87b9bb470973dd5ee9de0760f1c81c7
>>>>
>>>> -Brasten
>>>>
>>>> —
>>>>
>>>> # Proposal: Default object method #
>>>>
>>>> Objects w/ default method can be invoked like a function.
>>>>
>>>> ## Problem ##
>>>>
>>>> Objects that are well constrained (single responsibility)
>>>> can tend to end up with a single method, or at least a single method
>>>> that is important to most consumers. These methods tend to be named
>>>> by either verbing the class name (eg. `UserCreator.create()`) or with
>>>> some generic `handle` / `perform` / `doTheObviousThing`.
>>>>
>>>> Whatever the name, downstream consumers of the object end up coupled to
>>>> two implementation details:
>>>>
>>>>1) this thing-doer is an object and not a function
>>>>2) this thing-doer's doing method is called `X`
>>>>
>>>> ### Example ###
>>>>
>>>> Here we are going to create an object that can be used to
>>>> create a user later. Note that downstream consumers will only
>>>> care that this object does one thing: create a user. While it
>>>> make have other methods eventually for use in some limited
>>>> contexts, creating a user is its primary (and often sole-)
>>>> responsibility.
>>>>
>>>> ```js
>>>> class UserCreator {
>>>>   constructor(repository) {
>>>> this.repository = repository;

Re: Proposal: Default object method

2019-01-27 Thread Ranando King
Jordan's right. This one is best handled by a function. But if there is
some reason you need to create callable objects, it's still doable, even
with ES as-is. Just extend your classes from something like this:

```js
class Callable {
   constructor(defaultFn) {
  return (...args) => { return defaultFn.call(this, ...args); };
   }
}
```
Any class extending this will have instances that are functions. So using
your UserCreator class...

```js
class UserCreator extends Callable {
  constructor(repository) {
super(this.create);
this.repository = repository;
  }

  create(name) {
 return this.repository.createUser(name);
  }
}
```

Now `new UserCreator(someRepo)(someName)` is the same as `new
UserCreator(someRepo).create(someName)`.

On Sun, Jan 27, 2019 at 11:35 PM Jordan Harband  wrote:

> Something that can be invoked has a `[[Call]]` slot, and is `typeof`
> "function".
>
> Adding a Symbol that makes something callable would have a number of
> effects - it would make `typeof` (one of the most robust operations in the
> language) unsafe, because it would have to access the Symbol method, which
> could be a throwing getter (or even one that just logs how many typeofs are
> called on it). Additionally, it would mean any object could become
> callable, and any function could be made *un* callable.
>
> This seems like a pretty large change, solely to avoid "classes with a
> single method", which arguably should just be a function in the first place.
>
> On Sun, Jan 27, 2019 at 4:05 PM Brasten Sager  wrote:
>
>> Apologies if this has been raised before. I was unable to locate anything
>> similar.
>>
>> Any thoughts or ideas on this proposal would be appreciated!
>>
>> Original:
>> https://gist.github.com/brasten/f87b9bb470973dd5ee9de0760f1c81c7
>>
>> -Brasten
>>
>> —
>>
>> # Proposal: Default object method #
>>
>> Objects w/ default method can be invoked like a function.
>>
>> ## Problem ##
>>
>> Objects that are well constrained (single responsibility)
>> can tend to end up with a single method, or at least a single method
>> that is important to most consumers. These methods tend to be named
>> by either verbing the class name (eg. `UserCreator.create()`) or with
>> some generic `handle` / `perform` / `doTheObviousThing`.
>>
>> Whatever the name, downstream consumers of the object end up coupled to
>> two implementation details:
>>
>>1) this thing-doer is an object and not a function
>>2) this thing-doer's doing method is called `X`
>>
>> ### Example ###
>>
>> Here we are going to create an object that can be used to
>> create a user later. Note that downstream consumers will only
>> care that this object does one thing: create a user. While it
>> make have other methods eventually for use in some limited
>> contexts, creating a user is its primary (and often sole-)
>> responsibility.
>>
>> ```js
>> class UserCreator {
>>   constructor(repository) {
>> this.repository = repository;
>>   }
>>
>>   create(name) {
>>  return this.repository.createUser(name);
>>   }
>> }
>>
>> const userCreator = new UserCreator(userRepository);
>> ```
>>
>> At this point, the `userCreator` is just a single-method object.
>> It is useful for injecting into other objects that may need to
>> create a user. But the fact that the `userCreator` is an object
>> with a single useful method is an implementation detail to which
>> consumers become coupled.
>>
>> ```js
>>
>> // Consumer of `userCreator`. Although this could itself be a
>> // good example of a "UserCreator"-like object (due to `.handle()`).
>> //
>> class UserSignupHandler {
>>   constructor(userCreator) {
>> this.userCreator = userCreator;
>>   }
>>
>>   handle(userName) {
>> // UserSignupHandler is aware of ".create" when it really doesn't
>> have to be.
>> //
>> return this.userCreator.create(userName);
>>   }
>> }
>>
>> const handler = new UserSignupHandler(userCreator);
>> ```
>>
>> Notably, if we were to change the implementation of UserCreator later to
>> be
>> a pure function, we would have to change all consumers of UserCreator when
>> conceptually it shouldn't be needed. There is still a thing-doer that has
>> the same input/output.
>>
>>
>> ## Proposed Solution ##
>>
>> An object instance can have a default method. This would allow an
>> object to be "invoked" exactly like a function, hiding the implementation
>> detail from consumers.
>>
>> Note that there are several ways to define how the default method is
>> determined, and this proposal is less concerned with this aspect than with
>> what it looks like to invoke the object. We will demonstrate an option
>> here,
>> but alternatives are welcome.
>>
>> ```js
>> // This particular implementataion would use a Symbol.
>> //
>>
>> class UserCreator {
>>   constructor(repository) {
>> this.repository = repository;
>>   }
>>
>>   [Symbol.apply](name) {
>>  return this.repository.createUser(name);
>>   }
>> }
>>
>> const userCreator = new 

Re: NumberFormat maxSignificantDigits Limit

2019-01-26 Thread Ranando King
Here's a wikipedia link for what it's worth.

https://en.wikipedia.org/wiki/Extended_precision

Look at the *Working Range* section.

On Sat, Jan 26, 2019 at 2:03 PM Ranando King  wrote:

> There's another possibility. C++ was the language of choice back then. It
> had a type "long double", a 80-bit extended double type. It was meant to
> match Intel's implementation of IEEE 754. This number format can be safely
> and reversibly converted back and forth with 21 significant digits.
>
> On Thu, Jan 24, 2019 at 1:31 PM Isiah Meadows 
> wrote:
>
>> For all here interested, you might want to follow this Twitter
>> conversation I started. My theory is a subtle spec bug that copied the
>> number instead of recalculating the formula.
>>
>> https://twitter.com/isiahmeadows1/status/108851744948878
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Thu, Jan 24, 2019 at 12:43 AM Anders Rundgren
>>  wrote:
>> >
>> > On 2019-01-24 04:45, Ethan Resnick wrote:
>> > > Well, if you remove the trailing 0s you get an entirely different
>> number.  That's pretty significant.
>> > > Note that this is the default ES serialization as well.
>> > >
>> > >
>> > > This makes no sense to me. Yes, removing trailing 0s, and therefore
>> changing the magnitude of the number, changes its meaning. But significant
>> digits are about capturing precision, not magnitude.
>> >
>> > Hi Ethan,
>> > I'm neither the designer of this API nor have I looked at the
>> implementations either I guess that 21 comes from how number serializer
>> works without locale settings.
>> >
>> > >
>> > > Let's make this concrete:
>> > >
>> > > The number 1344499984510435328 happens to have an exact
>> floating point representation. However, because that number is larger than
>> the max safe integer, many other integers are best approximated by the same
>> floating point value. 13444999800 is one such number.
>> > >
>> > > So, if you do:
>> > >
>> > > 1344499984510435328..toLocaleString('en', {
>> maximumSignificantDigits: 21, useGrouping: false })
>> > >
>> > > and
>> > >
>> > > 13444999800..toLocaleString('en', {
>> maximumSignificantDigits: 21, useGrouping: false })
>> > >
>> > > you actually get the same output in each case, which makes sense,
>> because both numbers are represented by the same floating point behind the
>> scenes.
>> >
>> > Right, the ES number serializer doesn't take these edge cases in
>> consideration.
>> >
>> > >
>> > > Now, it seems like the serialization logic in `toLocaleString` (or
>> `toPrecision`) has two options.
>> > >
>> > > First, it could assume that the number it's serializing started life
>> as a decimal and got converted to the nearest floating point, in which case
>> the serialization code doesn't know the original intended number. In this
>> case, its best bet is probably to output 0s in those places where the
>> original decimal digits are unknown (i.e., for all digits beyond the
>> precision that was stored). This is actually what toLocaleString does;
>> i.e., all digits after the 17th are 0, because 64-bit floating points can
>> only store 17 decimal digits of precision. This is where my original
>> question came in, though: if a float can only encode 17 digits of
>> precision, why would the maximumSignificantDigits be capped at 21? It seems
>> like the values 18–21 are all just equivalent to 17.
>> > >
>> > > The other option is that the serialization code could assume that the
>> number stored in the float is exactly the number the user intended (rather
>> than a best approximation of some other decimal number). This is actually
>> what `toPrecision` does. I.e., if you call `toPrecision(21)` on either of
>> the numbers given above, you get 21 non-zero digits, matching the first 21
>> digits of the underlying float value: `"1.344499984510e+26"`. But,
>> again, the limit of 21 seems odd here too. Because, if you're going to
>> assume the float represents exactly the intended number, why not be willing
>> to output all 27 significant digits in the decimal above? Or more than 27
>> digits for th

Re: NumberFormat maxSignificantDigits Limit

2019-01-26 Thread Ranando King
There's another possibility. C++ was the language of choice back then. It
had a type "long double", a 80-bit extended double type. It was meant to
match Intel's implementation of IEEE 754. This number format can be safely
and reversibly converted back and forth with 21 significant digits.

On Thu, Jan 24, 2019 at 1:31 PM Isiah Meadows 
wrote:

> For all here interested, you might want to follow this Twitter
> conversation I started. My theory is a subtle spec bug that copied the
> number instead of recalculating the formula.
>
> https://twitter.com/isiahmeadows1/status/108851744948878
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Thu, Jan 24, 2019 at 12:43 AM Anders Rundgren
>  wrote:
> >
> > On 2019-01-24 04:45, Ethan Resnick wrote:
> > > Well, if you remove the trailing 0s you get an entirely different
> number.  That's pretty significant.
> > > Note that this is the default ES serialization as well.
> > >
> > >
> > > This makes no sense to me. Yes, removing trailing 0s, and therefore
> changing the magnitude of the number, changes its meaning. But significant
> digits are about capturing precision, not magnitude.
> >
> > Hi Ethan,
> > I'm neither the designer of this API nor have I looked at the
> implementations either I guess that 21 comes from how number serializer
> works without locale settings.
> >
> > >
> > > Let's make this concrete:
> > >
> > > The number 1344499984510435328 happens to have an exact
> floating point representation. However, because that number is larger than
> the max safe integer, many other integers are best approximated by the same
> floating point value. 13444999800 is one such number.
> > >
> > > So, if you do:
> > >
> > > 1344499984510435328..toLocaleString('en', {
> maximumSignificantDigits: 21, useGrouping: false })
> > >
> > > and
> > >
> > > 13444999800..toLocaleString('en', {
> maximumSignificantDigits: 21, useGrouping: false })
> > >
> > > you actually get the same output in each case, which makes sense,
> because both numbers are represented by the same floating point behind the
> scenes.
> >
> > Right, the ES number serializer doesn't take these edge cases in
> consideration.
> >
> > >
> > > Now, it seems like the serialization logic in `toLocaleString` (or
> `toPrecision`) has two options.
> > >
> > > First, it could assume that the number it's serializing started life
> as a decimal and got converted to the nearest floating point, in which case
> the serialization code doesn't know the original intended number. In this
> case, its best bet is probably to output 0s in those places where the
> original decimal digits are unknown (i.e., for all digits beyond the
> precision that was stored). This is actually what toLocaleString does;
> i.e., all digits after the 17th are 0, because 64-bit floating points can
> only store 17 decimal digits of precision. This is where my original
> question came in, though: if a float can only encode 17 digits of
> precision, why would the maximumSignificantDigits be capped at 21? It seems
> like the values 18–21 are all just equivalent to 17.
> > >
> > > The other option is that the serialization code could assume that the
> number stored in the float is exactly the number the user intended (rather
> than a best approximation of some other decimal number). This is actually
> what `toPrecision` does. I.e., if you call `toPrecision(21)` on either of
> the numbers given above, you get 21 non-zero digits, matching the first 21
> digits of the underlying float value: `"1.344499984510e+26"`. But,
> again, the limit of 21 seems odd here too. Because, if you're going to
> assume the float represents exactly the intended number, why not be willing
> to output all 27 significant digits in the decimal above? Or more than 27
> digits for the decimal representation of bigger floats?
> >
> > Did you try:
> > (1.344499984510e+250).toLocaleString('en', {
> maximumSignificantDigits: 21, useGrouping: false })
> > In Chrome I actually got 250 digits!
> >
> > My conclusion is that the internationalization API wasn't designed for
> "scientific" work.
> >
> > It was probably created for displaying "normal" numbers whatever that
> means :-)
> >
> > Anders
> >
> > > In other words, it seems like `maximumSignificantDigits` should either
> be capped at 17 (the real precision of the underlying float) or at 309 (the
> length of the decimal representation of the largest float). But neither of
> those are 21, hence my original question...
> > >
> > > On Mon, Jan 21, 2019 at 2:32 AM Anders Rundgren <
> anders.rundgren@gmail.com >
> wrote:
> > >
> > > This limit seems a bit strange though:
> > >
> > > console.log(new Intl.NumberFormat('en', { maximumFractionDigits:
> 20 }).format(-0.03));
> > >
> > >

Re: Re: Proposal: Class Templates

2019-01-17 Thread Ranando King
It can still be made to work...

```js
const Abc = (function() {
const cache = new Map;
function readCache(c, arg, val=new Map) {
if (!c.has(a))
c.set(a, val);

return c.get(arg);
}
return (a, b, c) => {
// ...optionally do something with a, b, and c...
// Return a class
let retval = class Abc$ {
constructor(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}

// ...optionally do something with a, b, and c...
show() {
console.log(`a = ${a}, b = ${b}, c = ${c}`);
console.log(`x = ${this.x}, y = ${this.y}, z = ${this.z}`);
}
};

return readCache(readCache(readCache(cache, a), b), c, retval);
};
})();
const obj = new (Abc(4, 5, 6))(1, 2, 3);
obj.show();
```

Now `Abc(4, 5, 6) === Abc(4, 5, 6)`.

On Thu, Jan 17, 2019 at 10:25 AM ViliusCreator 
wrote:

> But then `Abc(4, 5, 6) !== Abc(4, 5, 6)`. Using `Abc.constructor = class
> Abc$ {}` and then returning `Abc.constructor` won’t make it work.
>
>
> 
>  Virus-free.
> www.avast.com
> 
> <#m_7417576083780660614_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
> ___
> 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: New Proposal: ES Call Stack

2019-01-14 Thread Ranando King
Isiah, that works when you're in full control of all the code. However,
when you're writing B, and A is 3rd party (or the reverse in DI cases) then
the API is out of your control. In cases like that, it's better if the data
itself knew the restrictions. That keeps dependencies low.

On Mon, Jan 14, 2019 at 3:57 PM Ranando King  wrote:

> We agree trying to learn about the caller should not affect how the caller
> works. That's why I was thinking more on the lines of an "id" carried
> around by every function object. As long as that "id" uniquely identified
> the function without providing any access to the function itself, it would
> satisfy my needs as well as TC39 and engine builder constraints.
>
> On Mon, Jan 14, 2019 at 1:31 AM Isiah Meadows 
> wrote:
>
>> You could substitute a function parameter accepting an object here or a
>> class instance for globals to dodge this. Doesn't change my point.
>>
>> Here's how you deal with permissions like that: have A know what data B
>> is allowed to access, then pass B an object with only that data. If
>> necessary, make the exposed methods form a closure over the relevant
>> private data.
>>
>> On Mon, Jan 14, 2019 at 00:50 Ranando King  wrote:
>>
>>> That's all fine and dandy until you're dealing with a project that has a
>>> "no globals" mandate. The problem that I'd want to be able to solve is one
>>> of gaining and losing control during a single function's execution.
>>> For example: say function A is privileged, but function B is not. Function
>>> A calls function B with some data that B should only partially be able to
>>> access. Right now, that's hardly possible. There's no way for the data
>>> being passed to know if it is ok for B to use those functions or
>>> properties. If it was possible for the data methods to peek at the stack
>>> and recognize that the current function isn't privileged, then the problem
>>> is solved.
>>>
>>> I know class-fields will make this a little easier, but it doesn't
>>> solve the problem, especially when there's a "no constructors" mandate.
>>>
>>> On Sun, Jan 13, 2019 at 9:08 PM Isiah Meadows 
>>> wrote:
>>>
>>>> As for security, scope control is usually the more important thing to
>>>> monitor. That's covered in realms for the most part, but also a few other
>>>> things. Stack traces don't play a major part here, and whenever untrusted
>>>> calls need made and tracked through the stack, it's not that hard to just
>>>> save and restore global data as needed.
>>>> On Sun, Jan 13, 2019 at 22:05 Isiah Meadows 
>>>> wrote:
>>>>
>>>>> You may be interested in this:
>>>>> https://github.com/tc39/proposal-error-stacks
>>>>> On Sun, Jan 13, 2019 at 22:02 Ranando King  wrote:
>>>>>
>>>>>> ES used to have Function.caller for traversing the call stack, but
>>>>>> apparently this was very problematic for engine development and prevented
>>>>>> various optimizations. So now it doesn't work in strict mode which makes 
>>>>>> it
>>>>>> useless for code involving `"use strict"` or `class`. One of the main use
>>>>>> cases for such functionality was being able to determine where a given
>>>>>> function was called from.
>>>>>>
>>>>>> I was thinking of a global static class that is able to uniquely
>>>>>> identify each execution context on the call stack without giving any 
>>>>>> access
>>>>>> to the context objects themselves. I was thinking of maybe something like
>>>>>> this:
>>>>>>
>>>>>> ```js
>>>>>> class CallStackEntry {
>>>>>>   #className;//Name of the class or null
>>>>>>   #functionName; //Name of the function or null
>>>>>>   #fileName; //Name of the source file or null
>>>>>>   #line; //Source line number
>>>>>>   #offset;   //Source character offset on the line
>>>>>>   #id;   //Symbol
>>>>>>   get fileName() { return this.#filename; }
>>>>>>   get line() { return this.#line; }
>>>>>>   get offset() { return this.#offset; }
>>>>>>   get id() { return this.#id; }
>>>>>>   constructor(_fileName, _line_, _offset, _id) {
>>>>>> this.#fileName = _fileName;
>>>>>> this.#line = _line;
>>>>>> this.#offset = _offset;
>>>>>> this.#id = _id;
>>>>>>   }
>>>>>> }
>>>>>>
>>>>>> class CallStack {
>>>>>>   static #callStack = []; //Internally managed
>>>>>>   static get stackLimit() {...}
>>>>>>   static set stackLimit(v) {...}
>>>>>>   static get stack() {
>>>>>> //return the call stack as an array of CallStackEntry objects
>>>>>>   }
>>>>>> }
>>>>>> ```
>>>>>>
>>>>>> With something like this, security-type software would be able to
>>>>>> clearly identify functions without granting any access rights to the
>>>>>> corresponding function.
>>>>>>
>>>>>>
>>>>>> ___
>>>>>> 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: New Proposal: ES Call Stack

2019-01-14 Thread Ranando King
We agree trying to learn about the caller should not affect how the caller
works. That's why I was thinking more on the lines of an "id" carried
around by every function object. As long as that "id" uniquely identified
the function without providing any access to the function itself, it would
satisfy my needs as well as TC39 and engine builder constraints.

On Mon, Jan 14, 2019 at 1:31 AM Isiah Meadows 
wrote:

> You could substitute a function parameter accepting an object here or a
> class instance for globals to dodge this. Doesn't change my point.
>
> Here's how you deal with permissions like that: have A know what data B is
> allowed to access, then pass B an object with only that data. If necessary,
> make the exposed methods form a closure over the relevant private data.
>
> On Mon, Jan 14, 2019 at 00:50 Ranando King  wrote:
>
>> That's all fine and dandy until you're dealing with a project that has a
>> "no globals" mandate. The problem that I'd want to be able to solve is one
>> of gaining and losing control during a single function's execution.
>> For example: say function A is privileged, but function B is not. Function
>> A calls function B with some data that B should only partially be able to
>> access. Right now, that's hardly possible. There's no way for the data
>> being passed to know if it is ok for B to use those functions or
>> properties. If it was possible for the data methods to peek at the stack
>> and recognize that the current function isn't privileged, then the problem
>> is solved.
>>
>> I know class-fields will make this a little easier, but it doesn't
>> solve the problem, especially when there's a "no constructors" mandate.
>>
>> On Sun, Jan 13, 2019 at 9:08 PM Isiah Meadows 
>> wrote:
>>
>>> As for security, scope control is usually the more important thing to
>>> monitor. That's covered in realms for the most part, but also a few other
>>> things. Stack traces don't play a major part here, and whenever untrusted
>>> calls need made and tracked through the stack, it's not that hard to just
>>> save and restore global data as needed.
>>> On Sun, Jan 13, 2019 at 22:05 Isiah Meadows 
>>> wrote:
>>>
>>>> You may be interested in this:
>>>> https://github.com/tc39/proposal-error-stacks
>>>> On Sun, Jan 13, 2019 at 22:02 Ranando King  wrote:
>>>>
>>>>> ES used to have Function.caller for traversing the call stack, but
>>>>> apparently this was very problematic for engine development and prevented
>>>>> various optimizations. So now it doesn't work in strict mode which makes 
>>>>> it
>>>>> useless for code involving `"use strict"` or `class`. One of the main use
>>>>> cases for such functionality was being able to determine where a given
>>>>> function was called from.
>>>>>
>>>>> I was thinking of a global static class that is able to uniquely
>>>>> identify each execution context on the call stack without giving any 
>>>>> access
>>>>> to the context objects themselves. I was thinking of maybe something like
>>>>> this:
>>>>>
>>>>> ```js
>>>>> class CallStackEntry {
>>>>>   #className;//Name of the class or null
>>>>>   #functionName; //Name of the function or null
>>>>>   #fileName; //Name of the source file or null
>>>>>   #line; //Source line number
>>>>>   #offset;   //Source character offset on the line
>>>>>   #id;   //Symbol
>>>>>   get fileName() { return this.#filename; }
>>>>>   get line() { return this.#line; }
>>>>>   get offset() { return this.#offset; }
>>>>>   get id() { return this.#id; }
>>>>>   constructor(_fileName, _line_, _offset, _id) {
>>>>> this.#fileName = _fileName;
>>>>> this.#line = _line;
>>>>> this.#offset = _offset;
>>>>> this.#id = _id;
>>>>>   }
>>>>> }
>>>>>
>>>>> class CallStack {
>>>>>   static #callStack = []; //Internally managed
>>>>>   static get stackLimit() {...}
>>>>>   static set stackLimit(v) {...}
>>>>>   static get stack() {
>>>>> //return the call stack as an array of CallStackEntry objects
>>>>>   }
>>>>> }
>>>>> ```
>>>>>
>>>>> With something like this, security-type software would be able to
>>>>> clearly identify functions without granting any access rights to the
>>>>> corresponding function.
>>>>>
>>>>>
>>>>> ___
>>>>> 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: Bind function without thisArg

2019-01-13 Thread Ranando King
oops forgot to return retval!

On Mon, Jan 14, 2019 at 12:01 AM Ranando King  wrote:

> Bind is just a wrapper function provided by the engine. You can always
> create your own:
>
> ```js
> function myBind(fn, ...args) {
>   let retval = Object.defineProperties(function(...a) {
> console.assert(typeof(fn) == "function");
> return fn(...args, ...a)
>   }, {
> name: {
>   configurable: true,
>   value: fn.name
> },
> length: {
>   configurable: true,
>   value: fn.length
> },
> prototype: {
>   configurable: true,
>   writable: true,
>   value: fn.prototype
> }
>   });
> }
> ```
>
> This should apply your bound arguments before any arguments supplied by
> the caller without affecting the context object.
>
> On Sun, Jan 13, 2019 at 11:39 PM Sultan  wrote:
>
>> Consider the following example:
>>
>> var foo = (function(a) { console.assert(this === obj) }).bind(undefined,
>> 1)
>> var obj = {foo: foo}
>>
>> Calling foo from obj:
>>
>> obj.foo(1)
>>
>> Would result in an assertion. How does one go about preserving the this
>> reference of the caller. That is i want to use .bind to only bind
>> "arguments" and not "thisArg".
>>
>>
>> ___
>> 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: Bind function without thisArg

2019-01-13 Thread Ranando King
Bind is just a wrapper function provided by the engine. You can always
create your own:

```js
function myBind(fn, ...args) {
  let retval = Object.defineProperties(function(...a) {
console.assert(typeof(fn) == "function");
return fn(...args, ...a)
  }, {
name: {
  configurable: true,
  value: fn.name
},
length: {
  configurable: true,
  value: fn.length
},
prototype: {
  configurable: true,
  writable: true,
  value: fn.prototype
}
  });
}
```

This should apply your bound arguments before any arguments supplied by the
caller without affecting the context object.

On Sun, Jan 13, 2019 at 11:39 PM Sultan  wrote:

> Consider the following example:
>
> var foo = (function(a) { console.assert(this === obj) }).bind(undefined, 1)
> var obj = {foo: foo}
>
> Calling foo from obj:
>
> obj.foo(1)
>
> Would result in an assertion. How does one go about preserving the this
> reference of the caller. That is i want to use .bind to only bind
> "arguments" and not "thisArg".
>
>
> ___
> 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: New Proposal: ES Call Stack

2019-01-13 Thread Ranando King
That's all fine and dandy until you're dealing with a project that has a
"no globals" mandate. The problem that I'd want to be able to solve is one
of gaining and losing control during a single function's execution.
For example: say function A is privileged, but function B is not. Function
A calls function B with some data that B should only partially be able to
access. Right now, that's hardly possible. There's no way for the data
being passed to know if it is ok for B to use those functions or
properties. If it was possible for the data methods to peek at the stack
and recognize that the current function isn't privileged, then the problem
is solved.

I know class-fields will make this a little easier, but it doesn't
solve the problem, especially when there's a "no constructors" mandate.

On Sun, Jan 13, 2019 at 9:08 PM Isiah Meadows 
wrote:

> As for security, scope control is usually the more important thing to
> monitor. That's covered in realms for the most part, but also a few other
> things. Stack traces don't play a major part here, and whenever untrusted
> calls need made and tracked through the stack, it's not that hard to just
> save and restore global data as needed.
> On Sun, Jan 13, 2019 at 22:05 Isiah Meadows 
> wrote:
>
>> You may be interested in this:
>> https://github.com/tc39/proposal-error-stacks
>> On Sun, Jan 13, 2019 at 22:02 Ranando King  wrote:
>>
>>> ES used to have Function.caller for traversing the call stack, but
>>> apparently this was very problematic for engine development and prevented
>>> various optimizations. So now it doesn't work in strict mode which makes it
>>> useless for code involving `"use strict"` or `class`. One of the main use
>>> cases for such functionality was being able to determine where a given
>>> function was called from.
>>>
>>> I was thinking of a global static class that is able to uniquely
>>> identify each execution context on the call stack without giving any access
>>> to the context objects themselves. I was thinking of maybe something like
>>> this:
>>>
>>> ```js
>>> class CallStackEntry {
>>>   #className;//Name of the class or null
>>>   #functionName; //Name of the function or null
>>>   #fileName; //Name of the source file or null
>>>   #line; //Source line number
>>>   #offset;   //Source character offset on the line
>>>   #id;   //Symbol
>>>   get fileName() { return this.#filename; }
>>>   get line() { return this.#line; }
>>>   get offset() { return this.#offset; }
>>>   get id() { return this.#id; }
>>>   constructor(_fileName, _line_, _offset, _id) {
>>> this.#fileName = _fileName;
>>> this.#line = _line;
>>> this.#offset = _offset;
>>> this.#id = _id;
>>>   }
>>> }
>>>
>>> class CallStack {
>>>   static #callStack = []; //Internally managed
>>>   static get stackLimit() {...}
>>>   static set stackLimit(v) {...}
>>>   static get stack() {
>>> //return the call stack as an array of CallStackEntry objects
>>>   }
>>> }
>>> ```
>>>
>>> With something like this, security-type software would be able to
>>> clearly identify functions without granting any access rights to the
>>> corresponding function.
>>>
>>>
>>> ___
>>> 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


New Proposal: ES Call Stack

2019-01-13 Thread Ranando King
ES used to have Function.caller for traversing the call stack, but
apparently this was very problematic for engine development and prevented
various optimizations. So now it doesn't work in strict mode which makes it
useless for code involving `"use strict"` or `class`. One of the main use
cases for such functionality was being able to determine where a given
function was called from.

I was thinking of a global static class that is able to uniquely identify
each execution context on the call stack without giving any access to the
context objects themselves. I was thinking of maybe something like this:

```js
class CallStackEntry {
  #className;//Name of the class or null
  #functionName; //Name of the function or null
  #fileName; //Name of the source file or null
  #line; //Source line number
  #offset;   //Source character offset on the line
  #id;   //Symbol
  get fileName() { return this.#filename; }
  get line() { return this.#line; }
  get offset() { return this.#offset; }
  get id() { return this.#id; }
  constructor(_fileName, _line_, _offset, _id) {
this.#fileName = _fileName;
this.#line = _line;
this.#offset = _offset;
this.#id = _id;
  }
}

class CallStack {
  static #callStack = []; //Internally managed
  static get stackLimit() {...}
  static set stackLimit(v) {...}
  static get stack() {
//return the call stack as an array of CallStackEntry objects
  }
}
```

With something like this, security-type software would be able to clearly
identify functions without granting any access rights to the corresponding
function.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: Array.prototype.count

2019-01-07 Thread Ranando King
Either way it goes, there's a lot of ways to do this that are all trivial.

On Mon, Jan 7, 2019 at 1:31 PM Pier Bover  wrote:

> If you need to find the length of a filtered array IMO it makes more sense
> and is more obvious to just use filter().
>
> On Mon, Jan 7, 2019 at 1:12 PM Засим Александр  wrote:
>
>> Hi everyone. This is proposal for Array.prototype.count (or countOf)
>> method which allow to count specific elements in an array.
>>
>> ```js
>>
>> const evenNumberCount = [1, 2, 3, 4, 5].count(num => num % 2 === 0);
>>
>> ```
>>
>> Instead of
>>
>> ```js
>>
>> const evenNumberCount = [1, 2, 3, 4, 5].filter(num => num % 2 ===
>> 0).length;
>>
>> ```
>> ___
>> 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: Array.prototype.count

2019-01-07 Thread Ranando King
Isn't that just a specific case of Array.prototype.reduce?

```js
const evenNumberCount = [1,2,3,4,5].reduce((acc, val) => { !(val % 2)
&& ++acc; });
```

On Mon, Jan 7, 2019 at 1:12 PM Засим Александр  wrote:

> Hi everyone. This is proposal for Array.prototype.count (or countOf)
> method which allow to count specific elements in an array.
>
> ```js
>
> const evenNumberCount = [1, 2, 3, 4, 5].count(num => num % 2 === 0);
>
> ```
>
> Instead of
>
> ```js
>
> const evenNumberCount = [1, 2, 3, 4, 5].filter(num => num % 2 ===
> 0).length;
>
> ```
> ___
> 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: Callable objects protocol

2018-12-05 Thread Ranando King
Andrea, if class-fields becomes the accepted standard for private then that
would work, but it's awfully redundant. A closure is the very definition of
"private" in ES. So what does it mean to have a `static #foo` lexically
declared? From inside the function, it would be no more private than `var
bar`. That would lead to confusion. See the problem?

On Wed, Dec 5, 2018 at 10:02 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> I don't think introducing `public` here has any value. We have `static #a
> = 1` eventually for private already, the default should follow the classes
> behavior, IMO
>
> On Wed, Dec 5, 2018 at 10:46 PM Ranando King  wrote:
>
>> That's the kind of thing I was shooting for with static lexical scope
>> variables. There's 2 problems with it given the way things are going
>> though. Take a look.
>>
>> ```js
>> function foo() {
>>   static a=1,
>>  b=2,
>>  c=3;
>> }
>> ```
>> By the way I'm thinking, this would create 3 static variables within foo
>> that are only initialized once and retain whatever value is set on them
>> across invocations. Basically, the object `foo` carries around a closure
>> containing those values. Problem is, this is private to foo. That conflicts
>> with class-fields and it's sigil-means-private model.
>>
>> Ignoring that, public static variables can also be done (but it'd be the
>> first ever introduction of `public` in ES.
>> ```js
>> function foo() {
>>   static public a=1,
>> b=2,
>> c=3;
>> }
>> ```
>> This would make `foo.a`, `foo.b`, & `foo.c` accessible as public
>> properties of `foo`.
>>
>> Think this needs to be a proposal?
>>
>>
>> On Wed, Dec 5, 2018 at 1:39 AM Isiah Meadows 
>> wrote:
>>
>>> Personally, I'd prefer something else: a means of a function object
>>> literal that's still callable, but I can tack other properties to it
>>> easily. Something like this, maybe:
>>>
>>> ```js
>>> {
>>> (...args) { ... },
>>> }
>>> ```
>>>
>>> In this, the `this` value is set to the callee itself, not the given
>>> `this` value.
>>>
>>> Not married to the syntax, but I want the functionality.
>>> On Wed, Dec 5, 2018 at 01:34 Andrea Giammarchi <
>>> andrea.giammar...@gmail.com> wrote:
>>>
>>>> > the apply hook needs objects anyway.
>>>>
>>>> I meant functions
>>>>
>>>> On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi <
>>>> andrea.giammar...@gmail.com> wrote:
>>>>
>>>>> I've actually replied to the op, I didn't mean to answer you directly,
>>>>> but the only reason I wrote that is because I could, no other reasons.
>>>>>
>>>>> However, people unaware of the handleEvent pattern for event listeners
>>>>> often hope to be able to pass objects as listeners, ignoring the fact they
>>>>> can do that already (but they need a handleEvent method, own or inherited,
>>>>> in that object).
>>>>>
>>>>> There is at least another use case I can't remember now, but I do
>>>>> remember doing the Proxy dance before ending up realizing that the apply
>>>>> hook needs objects anyway.
>>>>>
>>>>> But yeah, I don't think it's a must have, specially because we can
>>>>> have something similar already, as shown in my example.
>>>>>
>>>>>
>>>>> On Wed, Dec 5, 2018 at 1:25 PM Ranando King  wrote:
>>>>>
>>>>>> Maybe I asked it wrong.
>>>>>>
>>>>>> How is making an ordinary object callable at all useful for anything
>>>>>> that can't already be easily handled via objects and functions? (looking
>>>>>> for use cases here)
>>>>>> How does this make coding easier to do and understand? (for the AST
>>>>>> parser and for the human)
>>>>>>
>>>>>> On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi <
>>>>>> andrea.giammar...@gmail.com> wrote:
>>>>>>
>>>>>>> How about this:
>>>>>>>
>>>>>>> ```js
>>>>>>>
>>>>>>> // the poly
>>>>>>> if (!Symbol.callable)
>>>>>>>   Symbol.callable = Symbol('callable');
>>>>>>>

Re: Callable objects protocol

2018-12-05 Thread Ranando King
That's the kind of thing I was shooting for with static lexical scope
variables. There's 2 problems with it given the way things are going
though. Take a look.

```js
function foo() {
  static a=1,
 b=2,
 c=3;
}
```
By the way I'm thinking, this would create 3 static variables within foo
that are only initialized once and retain whatever value is set on them
across invocations. Basically, the object `foo` carries around a closure
containing those values. Problem is, this is private to foo. That conflicts
with class-fields and it's sigil-means-private model.

Ignoring that, public static variables can also be done (but it'd be the
first ever introduction of `public` in ES.
```js
function foo() {
  static public a=1,
b=2,
c=3;
}
```
This would make `foo.a`, `foo.b`, & `foo.c` accessible as public properties
of `foo`.

Think this needs to be a proposal?


On Wed, Dec 5, 2018 at 1:39 AM Isiah Meadows  wrote:

> Personally, I'd prefer something else: a means of a function object
> literal that's still callable, but I can tack other properties to it
> easily. Something like this, maybe:
>
> ```js
> {
> (...args) { ... },
> }
> ```
>
> In this, the `this` value is set to the callee itself, not the given
> `this` value.
>
> Not married to the syntax, but I want the functionality.
> On Wed, Dec 5, 2018 at 01:34 Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> > the apply hook needs objects anyway.
>>
>> I meant functions
>>
>> On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> I've actually replied to the op, I didn't mean to answer you directly,
>>> but the only reason I wrote that is because I could, no other reasons.
>>>
>>> However, people unaware of the handleEvent pattern for event listeners
>>> often hope to be able to pass objects as listeners, ignoring the fact they
>>> can do that already (but they need a handleEvent method, own or inherited,
>>> in that object).
>>>
>>> There is at least another use case I can't remember now, but I do
>>> remember doing the Proxy dance before ending up realizing that the apply
>>> hook needs objects anyway.
>>>
>>> But yeah, I don't think it's a must have, specially because we can have
>>> something similar already, as shown in my example.
>>>
>>>
>>> On Wed, Dec 5, 2018 at 1:25 PM Ranando King  wrote:
>>>
>>>> Maybe I asked it wrong.
>>>>
>>>> How is making an ordinary object callable at all useful for anything
>>>> that can't already be easily handled via objects and functions? (looking
>>>> for use cases here)
>>>> How does this make coding easier to do and understand? (for the AST
>>>> parser and for the human)
>>>>
>>>> On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi <
>>>> andrea.giammar...@gmail.com> wrote:
>>>>
>>>>> How about this:
>>>>>
>>>>> ```js
>>>>>
>>>>> // the poly
>>>>> if (!Symbol.callable)
>>>>>   Symbol.callable = Symbol('callable');
>>>>>
>>>>> // the setup
>>>>> class Callable extends Function {
>>>>>   constructor(object) {
>>>>> super('return arguments.callee[Symbol.callable](...arguments)');
>>>>> //sloppy mode FTW!
>>>>> Object.setPrototypeOf(this, object);
>>>>>   }
>>>>> }
>>>>>
>>>>>
>>>>> // the example
>>>>> const obj = new Callable({
>>>>>   [Symbol.callable](value) {
>>>>> return value + this.value;
>>>>>   },
>>>>>   value: 123
>>>>> });
>>>>>
>>>>> obj(7); // 130
>>>>>
>>>>>
>>>>> ```
>>>>>
>>>>> On Wed, Dec 5, 2018 at 12:02 AM Sultan  wrote:
>>>>>
>>>>>> Something along the lines of Symbol.iterator protocol for defining
>>>>>> callback objects i.e: Symbol.callable:
>>>>>>
>>>>>> const obj = {
>>>>>> [Symbol.callable]: function (...args) { return
>>>>>> this[Symbol.for('value')] },
>>>>>> [Symbol.for(''value')]: 'value',
>>>>>> }
>>>>>>
>>>>>> assert(obj() === 'value')
>>>>>> ___
>>>>>> es-discuss mailing list
>>>>>> es-discuss@mozilla.org
>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>
>>>>> ___
>>>>> es-discuss mailing list
>>>>> es-discuss@mozilla.org
>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>
>>>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Callable objects protocol

2018-12-04 Thread Ranando King
Maybe I asked it wrong.

How is making an ordinary object callable at all useful for anything that
can't already be easily handled via objects and functions? (looking for use
cases here)
How does this make coding easier to do and understand? (for the AST parser
and for the human)

On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> How about this:
>
> ```js
>
> // the poly
> if (!Symbol.callable)
>   Symbol.callable = Symbol('callable');
>
> // the setup
> class Callable extends Function {
>   constructor(object) {
> super('return arguments.callee[Symbol.callable](...arguments)');
> //sloppy mode FTW!
> Object.setPrototypeOf(this, object);
>   }
> }
>
>
> // the example
> const obj = new Callable({
>   [Symbol.callable](value) {
> return value + this.value;
>   },
>   value: 123
> });
>
> obj(7); // 130
>
>
> ```
>
> On Wed, Dec 5, 2018 at 12:02 AM Sultan  wrote:
>
>> Something along the lines of Symbol.iterator protocol for defining
>> callback objects i.e: Symbol.callable:
>>
>> const obj = {
>> [Symbol.callable]: function (...args) { return
>> this[Symbol.for('value')] },
>> [Symbol.for(''value')]: 'value',
>> }
>>
>> assert(obj() === 'value')
>> ___
>> 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: Callable objects protocol

2018-12-04 Thread Ranando King
Ok. I get what you're after. So what's to be gained by being able to make
an object directly callable over simply using functions? I remember that in
C++ there was the concept of a "functor" where overloading `operator()`
would allow you to treat instances as functions, and that had some limited
utility to it (like creating delegate functions). But those use cases are
already easily possible in ES by other means.

On Tue, Dec 4, 2018 at 7:25 PM Sultan  wrote:

> Yes function objects are already callable objects. This is meant to allow
> authors the ability to make callable non-function objects with this new
> protocol.
>
> typeof nonFunctionCallableObject === 'object'. As much as Symbol.iterator
> is used to determine if a non-native object is an iterator so too would
> Symbol.callable with regards to non-function callables.
>
> One of the utilities of this can be visualized in the getter/setter type
> callables: fn() gets the value, fn(a) sets the value, this is normally
> supplied with methods to allow an outsider the ability to be reactive to
> changes of the underlining value something akin to observables.
>
> One way to implement this is as T.J mentioned – using a closure:
>
> function closure () {
>   var value = 'value'
>   return function (a) { return arguments.length ? value = a : value }
> }
>
> Another would be to treat functions as the objects they truly are:
>
> function object () {
> function value (a) { return arguments.length ? this.value = a : this.value
> }
> value.value = null
> }
>
> Or as this proposal would allow;
>
> An idiomatic class-based implementation with a shared callable protocol
> that is extendable by other classes:
>
> class prototype {
> [Symbol.callable](...args) { return args.length ? this.value = args[0] :
> args[0] }
> }
>
> const a = new prototype()
>
> assert(a(1) === 1, a() === 1)
>
> On Wed, Dec 5, 2018 at 1:15 AM Ranando King  wrote:
>
>> Thinking again, this might be a request for static lexical scope
>> variables such that:
>>
>> ```js
>> function obj() {
>>   static value = { test: 42 };
>>   return obj.value;
>> }
>>
>> var a = obj();
>> assert(obj() === a);
>> ```
>>
>> On Tue, Dec 4, 2018 at 4:05 PM Ranando King  wrote:
>>
>>> Ok maybe I'm thinking a little to literally, but isn't a function
>>> already a callable object?
>>>
>>> ```js
>>> function obj() {
>>>   return obj.value;
>>> }
>>> obj.value = "value";
>>>
>>> assert(obj() === "value");
>>> ```
>>>
>>> On Tue, Dec 4, 2018 at 1:16 PM Isiah Meadows 
>>> wrote:
>>>
>>>> Edit: the wrapper needs to be a function, so ignore that last email.
>>>> It's wrong.
>>>>
>>>> -
>>>>
>>>> Isiah Meadows
>>>> cont...@isiahmeadows.com
>>>> www.isiahmeadows.com
>>>>
>>>> On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows 
>>>> wrote:
>>>> >
>>>> > BTW, there are proxies [1], and one of the proxy hooks is to intercept
>>>> > calls [2].
>>>> >
>>>> > [1]:
>>>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
>>>> > [2]:
>>>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply
>>>> >
>>>> > Your "callable object" proposal would be literally as simple as this
>>>> > to implement:
>>>> >
>>>> > ```js
>>>> > const callable = Symbol.for("callable")
>>>> > const handler = {
>>>> > apply(target, thisArg, argsList) {
>>>> > return Reflect.apply(target[callable], thisArg, argsList)
>>>> > },
>>>> > }
>>>> > function makeCallable(obj) { return new Proxy(obj, handler) }
>>>> >
>>>> > // Your example, ported
>>>> > const obj = makeCallable({
>>>> > [callable]: function (...args) { return this[Symbol.for('value')]
>>>> },
>>>> > [Symbol.for(''value')]: 'value',
>>>> > })
>>>> >
>>>> > assert(obj() === 'value')
>>>> > obj[callable] = () => 1
>>>> > assert(obj() === 1)
>>>> > ```
>>>> >
>>>> > -
>>>> >
>>>> > Isiah Meadows
>>>> > cont...@isiahmeadows.com
>>>> > www.isiahmeadows.com
>>>> > On Tue, Dec 4, 2018 at 12:02 PM Sultan  wrote:
>>>> > >
>>>> > > Something along the lines of Symbol.iterator protocol for defining
>>>> callback objects i.e: Symbol.callable:
>>>> > >
>>>> > > const obj = {
>>>> > > [Symbol.callable]: function (...args) { return
>>>> this[Symbol.for('value')] },
>>>> > > [Symbol.for(''value')]: 'value',
>>>> > > }
>>>> > >
>>>> > > assert(obj() === 'value')
>>>> > > ___
>>>> > > 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: Callable objects protocol

2018-12-04 Thread Ranando King
Thinking again, this might be a request for static lexical scope variables
such that:

```js
function obj() {
  static value = { test: 42 };
  return obj.value;
}

var a = obj();
assert(obj() === a);
```

On Tue, Dec 4, 2018 at 4:05 PM Ranando King  wrote:

> Ok maybe I'm thinking a little to literally, but isn't a function
> already a callable object?
>
> ```js
> function obj() {
>   return obj.value;
> }
> obj.value = "value";
>
> assert(obj() === "value");
> ```
>
> On Tue, Dec 4, 2018 at 1:16 PM Isiah Meadows 
> wrote:
>
>> Edit: the wrapper needs to be a function, so ignore that last email. It's
>> wrong.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows 
>> wrote:
>> >
>> > BTW, there are proxies [1], and one of the proxy hooks is to intercept
>> > calls [2].
>> >
>> > [1]:
>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
>> > [2]:
>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply
>> >
>> > Your "callable object" proposal would be literally as simple as this
>> > to implement:
>> >
>> > ```js
>> > const callable = Symbol.for("callable")
>> > const handler = {
>> > apply(target, thisArg, argsList) {
>> > return Reflect.apply(target[callable], thisArg, argsList)
>> > },
>> > }
>> > function makeCallable(obj) { return new Proxy(obj, handler) }
>> >
>> > // Your example, ported
>> > const obj = makeCallable({
>> > [callable]: function (...args) { return this[Symbol.for('value')] },
>> > [Symbol.for(''value')]: 'value',
>> > })
>> >
>> > assert(obj() === 'value')
>> > obj[callable] = () => 1
>> > assert(obj() === 1)
>> > ```
>> >
>> > -
>> >
>> > Isiah Meadows
>> > cont...@isiahmeadows.com
>> > www.isiahmeadows.com
>> > On Tue, Dec 4, 2018 at 12:02 PM Sultan  wrote:
>> > >
>> > > Something along the lines of Symbol.iterator protocol for defining
>> callback objects i.e: Symbol.callable:
>> > >
>> > > const obj = {
>> > > [Symbol.callable]: function (...args) { return
>> this[Symbol.for('value')] },
>> > > [Symbol.for(''value')]: 'value',
>> > > }
>> > >
>> > > assert(obj() === 'value')
>> > > ___
>> > > 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: Callable objects protocol

2018-12-04 Thread Ranando King
Ok maybe I'm thinking a little to literally, but isn't a function
already a callable object?

```js
function obj() {
  return obj.value;
}
obj.value = "value";

assert(obj() === "value");
```

On Tue, Dec 4, 2018 at 1:16 PM Isiah Meadows  wrote:

> Edit: the wrapper needs to be a function, so ignore that last email. It's
> wrong.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
> On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows 
> wrote:
> >
> > BTW, there are proxies [1], and one of the proxy hooks is to intercept
> > calls [2].
> >
> > [1]:
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
> > [2]:
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply
> >
> > Your "callable object" proposal would be literally as simple as this
> > to implement:
> >
> > ```js
> > const callable = Symbol.for("callable")
> > const handler = {
> > apply(target, thisArg, argsList) {
> > return Reflect.apply(target[callable], thisArg, argsList)
> > },
> > }
> > function makeCallable(obj) { return new Proxy(obj, handler) }
> >
> > // Your example, ported
> > const obj = makeCallable({
> > [callable]: function (...args) { return this[Symbol.for('value')] },
> > [Symbol.for(''value')]: 'value',
> > })
> >
> > assert(obj() === 'value')
> > obj[callable] = () => 1
> > assert(obj() === 1)
> > ```
> >
> > -
> >
> > Isiah Meadows
> > cont...@isiahmeadows.com
> > www.isiahmeadows.com
> > On Tue, Dec 4, 2018 at 12:02 PM Sultan  wrote:
> > >
> > > Something along the lines of Symbol.iterator protocol for defining
> callback objects i.e: Symbol.callable:
> > >
> > > const obj = {
> > > [Symbol.callable]: function (...args) { return
> this[Symbol.for('value')] },
> > > [Symbol.for(''value')]: 'value',
> > > }
> > >
> > > assert(obj() === 'value')
> > > ___
> > > 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: What is holding back Decorators ?

2018-12-04 Thread Ranando King
Thanks for the links T.J. I'm glad to see they're going forward with
decorators though I'm a bit confused as to why they'd want to do `@dec
export`. That makes it look like the `export` directive is the target of
the decorator. Weird.

There was something I saw that disturbed me deeply.

> DH: I think this is so zerosum that we can't progress. *I'd rather ship
the worst outcome than not ship.*

I could understand that position if it were a case of providing for
something that cannot be done currently. Then it would be like saying "I'd
rather feed them gruel than see them starve." However, whether it's private
fields or decorators, there are already sufficient means of providing for
these. In this situation, that statement seems to read more like "I know
they ordered electric screwdrivers, but ship these butterknives instead; it
takes too long to get the screwdrivers." While I know in my head that this
can't possibly be the case

On Tue, Dec 4, 2018 at 5:30 AM T.J. Crowder 
wrote:

> On Tue, Dec 4, 2018 at 6:21 AM 森建
>  wrote:
> > For understanding the current status, I think that the following
> > documents will be helpful.
>
> Thanks!
>
> > The slide for the 67th meeting of Ecma TC39
> >
> https://docs.google.com/presentation/d/12QtzhGvtA4bf7tznPzIeYH5aLEo40Kwfs3vpJxaSbHE/edit#slide=id.p
>
> For any who, like me, ran into a 404 following the "Improved Docs" link in
> those slides (which isn't a link to improved docs, it's to a discussion
> about improving docs), it's a minor typo in the URL. The correct one is:
>
> https://github.com/littledan/js-outreach-groups/blob/master/educators/notes-2018-10-11.md
>
> -- T.J. Crowder
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: What is holding back Decorators ?

2018-12-03 Thread Ranando King
I'm not from TC39, but I can hazard a guess.

Decorators are somewhat useless without data properties to modify.
Currently, class-fields is the proposal du jour, but even while in stage 3,
it has issues, requiring trade-offs that many have voiced an unwillingness
to accept. The awful syntax is forgivable given the approach they've taken,
so that's not the issue. There are alternatives, but for one reason or
another that TC39 is somehow unable to concisely articulate beyond stating
it to be a matter of preference in their consensus, the alternatives are
not able to gain traction in the committee. Yet, the discussion continues
with a slowly increasing number of dissenting opinions in the discussion
board.

In either case, decorators will probably see an advancement once some
version of data properties lands in ES. In fact, it will likely happen
quickly since few if any have any real issue with the concept.

...but that's just my guess.

On Mon, Dec 3, 2018 at 11:18 PM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> Supposed to land in ES2016, decorators haven't moved from Stage 2 for more
> than a year now.
>
> In various other discussions everyone has the easy "use decorators" answer
> for any problem, and yet no browser ships decorators, and no stage 3 is
> happening neither.
>
> Is there already a better replacement or we're not convinced already that
> decorators are needed, when these are the first answer to any language
> extension proposed in this list?
>
> Thanks in advance for any sort of clarification.
>
> Regards
> ___
> 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: New: proposal-class-modifiers

2018-12-02 Thread Ranando King
structor is called without its abstract
> methods implemented
> >> - Throw a type error if a subclass fails to implement all remaining
> abstract methods and is not itself abstract
> >>
> >> Each of these could be reasonably tacked on at the end.
> >>
> >> For `final`, you'll need to create a way to block all means of
> `Object.create`, with class constructors being the sole exception. That
> complicates the mechanism tremendously, since prototype-based inheritance
> alone can't enforce this unless you make `Object.setPrototypeOf(obj,
> parent)` no longer directly equivalent to `obj.[[Prototype]] = parent`.
> >> On Sun, Dec 2, 2018 at 16:28 Ranando King  wrote:
> >>>
> >>> Object.create and Object.setPrototypeOf operate on a different level
> than what I'm targeting. I can conceive of a means to make even these
> functions respect these tokens. However, if I were going to do that, I'd
> want these tokens to be applicable to objects and functions directly.
> Reflect.construct is essentially part of the process for `new` and would be
> required to respect these tokens. I'm still open on how far the effect of
> these tokens should extend.
> >>>
> >>> On Sun, Dec 2, 2018 at 3:20 PM Isiah Meadows 
> wrote:
> >>>>
> >>>> How would this interop with `Object.create`, `Reflect.construct`, and
> `Object.setPrototypeOf`?
> >>>> On Sun, Dec 2, 2018 at 16:16 Ranando King  wrote:
> >>>>>
> >>>>> This proposal is intended to add `abstract` and `final` to `class`
> definitions so as to modify the inheritability of a class.
> >>>>>
> >>>>> https://github.com/rdking/proposal-class-modifiers
> >>>>> ___
> >>>>> 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: New: proposal-class-modifiers

2018-12-02 Thread Ranando King
Object.create and Object.setPrototypeOf operate on a different level than
what I'm targeting. I can conceive of a means to make even these functions
respect these tokens. However, if I were going to do that, I'd want these
tokens to be applicable to objects and functions directly.
Reflect.construct is essentially part of the process for `new` and would be
required to respect these tokens. I'm still open on how far the effect of
these tokens should extend.

On Sun, Dec 2, 2018 at 3:20 PM Isiah Meadows  wrote:

> How would this interop with `Object.create`, `Reflect.construct`, and
> `Object.setPrototypeOf`?
> On Sun, Dec 2, 2018 at 16:16 Ranando King  wrote:
>
>> This proposal is intended to add `abstract` and `final` to `class`
>> definitions so as to modify the inheritability of a class.
>>
>> https://github.com/rdking/proposal-class-modifiers
>> ___
>> 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: New: proposal-common-member-modifiers

2018-12-02 Thread Ranando King
I also agree that the community should have a hand in the process. I don't,
however, agree that waiting for the community to come to a consensus by
providing definitions that exist in the wild is a good idea. TC39 tends
toward not accepting proposals that break what already exists in the wild.
I'm submitting this proposal with the intent of having the community decide
on these important features **before** they're out in the wild so as to
prevent the natural confusion that will ensue as people release their own
spin on how these things should be defined. I'd even be happy with a set of
well-defined decorators, as long as they are a standard part of the
language. Whether or not the `@` is in front of them is of little merit to
me.

The point of the proposal is to make the standard parts of a property
descriptor also expressible in a `class` definition. This is something that
will be immediately desirable with any implementation of declarative data
members in a `class`.

On Sun, Dec 2, 2018 at 3:05 PM Augusto Moura 
wrote:

> Extracted from the proposal [1]:
> > Instead of waiting for the community to define and agree upon decorators
> for these purposes, why not define them now?
>
> In my opinion this is not how things should be done, in my opinion we
> actually should follow user-land patterns and help modifying/extending
> the language in this patterns pain points. We saw that in almost every
> new feature in the language since Harmony (not a coincidence, it's was
> actually decided to be this way), community agreement is a important
> factor in the process (I really don't know why it's not in the TC39
> process document [2], maybe is implied?). A lot of problems in
> Javascript ~and probably all other languages in existence~ arose from
> expected usefulness, just to be tagged as a foot gun or bad design by
> the community, and not used at all.
>
> That being said, I think decorators already provide all the need for
> this "runtime-modifiers" keywords, and new keyword-like modifiers will
> only add complexity to the language, as we would have 2 declarative
> ways of doing the same thing (or worse, the community decide in a
> different behavior for the analogue decorators, and probably one of
> the ways would be discouraged and become spec garbage).
>
> PS.: Sure there are cases were the community is really divided and
> things don't move because of that, and some of this cases are merged
> in the spec without total agreement at the end. But in my opinion this
> slow process and discussion is a good thing, we cannot merge something
> just to because it seems like a good feature. Also I'm not a TC39
> member, it's my opinion based in similar discussions in the past,
> maybe some real member can clarify it better or correct me if I'm
> wrong.
>
> [1] https://github.com/rdking/proposal-common-member-modifiers#motivation
> [2] https://tc39.github.io/process-document/
> Em dom, 2 de dez de 2018 às 04:49, Ranando King 
> escreveu:
> >
> > Since some form of data is going to land in ES class syntax, it would be
> a good idea if the capabilities of a property descriptor were also exposed
> for all public properties.
> >
> > https://github.com/rdking/proposal-common-member-modifiers
> > ___
> > es-discuss mailing list
> > es-discuss@mozilla.org
> > https://mail.mozilla.org/listinfo/es-discuss
>
>
>
> --
> Atenciosamente,
>
> Augusto Borges de Moura
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


New: proposal-class-modifiers

2018-12-02 Thread Ranando King
This proposal is intended to add `abstract` and `final` to `class`
definitions so as to modify the inheritability of a class.

https://github.com/rdking/proposal-class-modifiers
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New: proposal-common-member-modifiers

2018-12-02 Thread Ranando King
I get that decorators "can" perform the same task, but these are features
that are standard in the language today. Once we start defining data
properties on classes, there will be an immediate need to define the
attributes of those properties. Yes, decorators can fill the need, but
unless a standard library is provided to perform these tasks, there will
certainly be multiple different takes on how such decorators should work.
By defining them directly into the language like this, not only do we get a
well defined approach to declaring properties with the desired attributes,
but we avoid the additional complexity of decorator implementation for an
otherwise trivial task.

...at least, that's how I'm thinking of it. I'm also working on 1 last
proposal, proposal-class-modifiers with the intent of adding `abstract` and
`final` to class declarations where `abstract class` would prevent
instantiation of the class and `final` class would prevent inheritance of
the class.

On Sun, Dec 2, 2018 at 2:31 AM Isiah Meadows  wrote:

> For one token (+ an import) more, you could use decorators instead.
> And BTW, it's been suggested already that a standard decorator library
> should exist, just IIUC (I'm not part of TC39) it's not yet determined
> what should be in it.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
> On Sun, Dec 2, 2018 at 2:25 AM Jacob Pratt  wrote:
> >
> > I'm of the opinion this is what decorators are for.
> >
> > On Sun, Dec 2, 2018, 01:49 Ranando King  >>
> >> Since some form of data is going to land in ES class syntax, it would
> be a good idea if the capabilities of a property descriptor were also
> exposed for all public properties.
> >>
> >> https://github.com/rdking/proposal-common-member-modifiers
> >> ___
> >> 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


New: proposal-common-member-modifiers

2018-12-01 Thread Ranando King
Since some form of data is going to land in ES class syntax, it would be a
good idea if the capabilities of a property descriptor were also exposed
for all public properties.

https://github.com/rdking/proposal-common-member-modifiers
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New: proposal-safe-prototype

2018-11-28 Thread Ranando King
> Should the last line trigger copy-on-write around `a.__proto__`?

Yes. I get that you think of this as "dreadful action-at-a-distance", but
that kind of thing already happens any time the primitive value (including
root-level object references) of a property on the prototype changes. The
intent of this proposal is to treat the whole of the object that exists on
a property of `__proto__` as if it were a primitive. Any attempt to change
it in part or whole forces it to become an instance-specific value first.
The technique used in the example of this proposal ensures that object
reference in `b` isn't invalidated in the process.

The net result is that you don't get to **accidentally** mutate a
prototype. If you want to change some value in a prototype, get access to
it directly first. Using your example, do this:
```js
var a = { __proto__: { foo: { bar: 2 } } } with safe-prototype;
var b = Object.getPrototypeOf(a).foo;
b.bar = 3;
```
This would skip the new behavior, causing the prototype to be modified
directly.

> Unless you have deep knowledge of the internal state and/or the
implementation of the modified object (which you don’t have in case of a
user-implementated one), you cannot reliably detect when an object is
mutated.

I accounted for that with Symbol.UnsafeProto. All prototypes of native
functions will have this flag on them, preventing any attempt at the new
behavior. Further, any behavior that cannot be caught by a Membrane is
beyond the scope of this effort. Given the insanely flexible nature of ES,
it's unrealistic to thing that 100% of all possible implementation details
can be tracked. However, what this proposal seeks to provide is elimination
of the foot-gun for the most common cases. Even in non-interpreted
languages, some objects are impossible to clone completely due to the use
of external resources. This can't be helped.

For objects having such complicated implementations, the developer will
always be able to add Symbol.UnsafeProto to ensure that no attempt to
duplicate it ever occurs. Proper use of the 2 symbols will ensure that
whenever reasonable, the foot-gun cannot appear.

On Wed, Nov 28, 2018 at 3:36 PM Claude Pache  wrote:

> Sorry, I didn’t read the thread thoroughly (so maybe I’ll repeat someone).
> But here are some serious  issues with your proposal:
>
> --
>
> 1. Assignment of properties deep in the object hierarchy split in two
> instructions:
>
> ```js
> var a = { __proto__: { foo: { bar: 2 } } } with safe-prototype;
> var b = a.foo;
> b.bar = 3;
> ```
> Should the last line trigger copy-on-write around `a.__proto__`?
>
> If you say ”no”, it means that the meaning of the code is changed
> unexpectedly with an apparent innocuous code refactoring.
>
> If you say ”yes”, it is dreadful action-at-distance, because the two last
> lines of code may be very distant, indeed even in two distinct files. — It
> would be less an issue if prototypes were, say, just abstract templates.
> But they are not, they are concrete objects, so:
>
> ```js
> var proto = { foo: { bar: 2 } };
> var a1 = { __proto__: proto } with safe-prototype;
> var a2 = { __proto__: proto } with safe-prototype;
> var b1 = a1.foo;
> var b2 = a2.foo
> b1 === b2; // true
> b1.bar = 3;
> b1 === b2; // ???
> ```
>
> --
>
> 2. Object mutations unrelated to the value of its properties:
>
> ```js
> var a = { __proto__: { foo: new Map([ [ 'bar', 2 ] ]) } } with
> safe-prototype;
> a.foo.set('bar', 3);
> ```
>
> Unless you have deep knowledge of the internal state and/or the
> implementation of the modified object (which you don’t have in case of a
> user-implementated one), you cannot reliably detect when an object is
> mutated.
>
> Note the subtle difference between:
> *  `[].push(1)` — You will detect object mutation, because it will add a
> concrete property on the Array object.
> * `(new Set).add(1)` — You won’t detect mutation, because only internal
> state of the Set object is modified.
> * `(new RandomUserDefinedCollection).put(1)` — That depends on the
> implementation of the `RandomUserDefinedCollection` class.
>
>
>
> —Claude
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal for faster this assignments in constructor functions

2018-11-28 Thread Ranando King
Arguments is only deprecated in strict mode.

```js
F(arg) {
let {par1, par2, ..., parN} = arg;
Object.assign(this, arg);
}
```

This version works in strict mode, but it's less clear what parameters
should be passed. I used `Object.assign` because I assumed that `F` was
called with `new`, providing a valid `this` object. Otherwise, your
original example would either throw in strict mode, or add your parameters
to "global", unless it was called with `Function.prototype.call`.

On Wed, Nov 28, 2018 at 3:36 PM Simo Costa  wrote:

> Ops I saw the now ahahah sorry. But anyway there is a function call and an
> object creation and you are forced to pass arguments using an object (not
> so bad but...another object creation).
> To avoid the function call I would do:
> ```js
> F({par1, par2, ..., parN}) {
> this = {...arguments[0]};
> }
> ```
> Another thing...`arguments` is deprecated, right?
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal for faster this assignments in constructor functions

2018-11-28 Thread Ranando King
No. It has to be arguments[0]. Notice the braces around the argument list?
This is meant to use destructured arguments. The argument list in this case
has only 1 element, hence the `[0]`.

On Wed, Nov 28, 2018 at 3:26 PM Simo Costa  wrote:

> @Ranando
>
> I think you meant:
> ```js
> F({par1, par2, ..., parN}) {
> Object.assign(this, arguments);
> }
> ```
> This is briefly explained on github, anyway you'll get an undesired
> 'length' property.
>
> Il giorno mer 28 nov 2018 alle ore 22:20 Ranando King 
> ha scritto:
>
>> What about this:
>>
>> ```js
>> F({par1, par2, ..., parN}) {
>> Object.assign(this, arguments[0]);
>> }
>> ```
>>
>> On Wed, Nov 28, 2018 at 2:20 PM Simo Costa 
>> wrote:
>>
>>> @Claude
>>>
>>> Your suggestion is still too much verbose/ripetitive in my opinion
>>> because you repeat the `this`keyword. I agree with the "limited use cases"
>>> of my proposal but not with your concerns about the syntax, but I am open
>>> for improvements on it.
>>> I do not think that it could bring more mistuderstading than the
>>> introduction of the rest/spread syntax has brought.
>>>
>>> And about the Object.assign solution, there are always (theoretically)
>>> an object creation and a function call, as well as the repetition of the
>>> parameters.
>>> `Object.assign(this, {x, y});`
>>>
>>>
>>>
>>>
>>>
>>>
>>> ___
>>> 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 for faster this assignments in constructor functions

2018-11-28 Thread Ranando King
What about this:

```js
F({par1, par2, ..., parN}) {
Object.assign(this, arguments[0]);
}
```

On Wed, Nov 28, 2018 at 2:20 PM Simo Costa  wrote:

> @Claude
>
> Your suggestion is still too much verbose/ripetitive in my opinion because
> you repeat the `this`keyword. I agree with the "limited use cases" of my
> proposal but not with your concerns about the syntax, but I am open for
> improvements on it.
> I do not think that it could bring more mistuderstading than the
> introduction of the rest/spread syntax has brought.
>
> And about the Object.assign solution, there are always (theoretically) an
> object creation and a function call, as well as the repetition of the
> parameters.
> `Object.assign(this, {x, y});`
>
>
>
>
>
>
> ___
> 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: New: proposal-safe-prototype

2018-11-27 Thread Ranando King
Ok. I just updated the proposal.
Since T.J. felt so strongly about the use of the word "template", I removed
it from the proposal. No need to raise unnecessary ire.
Since using `new` to trigger the behavior is a no-go just like pragmas, I
introduced 2 new well known Symbols.
* `Symbol.SafeProto = Symbol("SafeProto")` to mark objects that should
exhibit the new behavior.
* `Symbol.UnsafeProto = Symbol("UnsafeProto")` to mark objects that **must
not** exhibit the new behavior.

On Tue, Nov 27, 2018 at 1:13 PM Jordan Harband  wrote:

> Correct, existing code *used with* existing code can't break. It's totally
> fine for existing code that works with objects produced by new code to
> break.
>
> On Tue, Nov 27, 2018 at 11:05 AM Ranando King  wrote:
>
>> Is this to say that no new feature is allowed to introduce breaking
>> changes in existing code?
>>
>> On Tue, Nov 27, 2018 at 1:00 PM Jordan Harband  wrote:
>>
>>> What I meant by "preserve existing behavior" is that *all current code*
>>> must retain the footgun. Any chance must only apply to new code that
>>> explicitly opts in to it.
>>>
>>> On Tue, Nov 27, 2018 at 10:55 AM Ranando King  wrote:
>>>
>>>> > Not something you'd want to do often...
>>>>
>>>> Or ever. This is the foot-gun behavior. The same result can be achieved
>>>> with a simple factory class.
>>>> ```js
>>>> class Example {
>>>>   //Don't use "this". It was flagged to use the updated prototype
>>>> behavior.
>>>>   return Object.create(Example.prototype);
>>>> }
>>>> Example.prototype.sharedObject = {
>>>> counter: 0
>>>> };
>>>> const e1 = new Example();
>>>> const e2 = new Example();
>>>> console.log(e2.sharedObject.counter); // 0
>>>> ++e1.sharedObject.counter;
>>>> console.log(e2.sharedObject.counter); // 1
>>>> ```
>>>> This is what I meant when I said that the existing behavior isn't lost.
>>>> There are still plenty of ways to achieve the foot-gun behavior if that is
>>>> what's desired. What this proposal seeks is a means of making the most
>>>> common path foot-gun free.
>>>>
>>>> Besides, a cleaner result can be achieved by using a static property.
>>>> ```js
>>>> class Example {
>>>> }
>>>> Example.counter = 0;
>>>>
>>>> const e1 = new Example();
>>>> const e2 = new Example();
>>>> console.log(e2.constructor.counter); // 0
>>>> ++e1.constructor.counter;
>>>> console.log(e2.constructor.counter); // 1
>>>> ```
>>>>
>>>>
>>>> On Tue, Nov 27, 2018 at 10:30 AM T.J. Crowder <
>>>> tj.crow...@farsightsoftware.com> wrote:
>>>>
>>>>> On Tue, Nov 27, 2018 at 3:34 PM Ranando King
>>>>>  wrote:
>>>>> > The fact that the prototype is a 1st class, (usually) mutable
>>>>> > object doesn't change the fact that it is a template.
>>>>>
>>>>> It fundamentally does, calling prototypes templates rather
>>>>> short-changes them. Again, they're live objects:
>>>>>
>>>>> ```js
>>>>> class Example {
>>>>> }
>>>>> const e = new Example();
>>>>> console.log(e.foo); // undefined
>>>>> Example.prototype.foo = "bar";
>>>>> console.log(e.foo); // "bar"
>>>>> ```
>>>>>
>>>>> (http://jsfiddle.net/pot8cdq6/) A *template* wouldn't demonstrate
>>>>> that sort of behavior. Perhaps it's just a semantic point, though.
>>>>>
>>>>> > As for changing `new` in an incompatible way, doesn't represent a
>>>>> > significant or incompatible change in the behavior of `new`.
>>>>>
>>>>> Of course it does. If it didn't, it wouldn't solve the problem you
>>>>> describe wanting to solve. Or was there some opt-in (other than the 
>>>>> pragma)
>>>>> that I missed? The problem you describe is perfectly valid current code:
>>>>>
>>>>> ```js
>>>>> class Example {
>>>>> }
>>>>> Example.prototype.sharedObject = {
>>>>> counter: 0
>>>>> };
>>>>> const e1 = new Example();
>>>>> const e2 = new Example();
>>>>> console

Re: New: proposal-safe-prototype

2018-11-27 Thread Ranando King
What if, instead of having `new` introduce a flag on an internal slot, we
define a new "well known" Symbol:

Symbol.SafeProto = new Symbol("SafeProto");

such that if this Symbol is a property of an object being used as a
prototype (regardless of its value), then that prototype object exhibits
the new behavior. Will that suffice?

On Tue, Nov 27, 2018 at 1:05 PM Ranando King  wrote:

> Is this to say that no new feature is allowed to introduce breaking
> changes in existing code?
>
> On Tue, Nov 27, 2018 at 1:00 PM Jordan Harband  wrote:
>
>> What I meant by "preserve existing behavior" is that *all current code*
>> must retain the footgun. Any chance must only apply to new code that
>> explicitly opts in to it.
>>
>> On Tue, Nov 27, 2018 at 10:55 AM Ranando King  wrote:
>>
>>> > Not something you'd want to do often...
>>>
>>> Or ever. This is the foot-gun behavior. The same result can be achieved
>>> with a simple factory class.
>>> ```js
>>> class Example {
>>>   //Don't use "this". It was flagged to use the updated prototype
>>> behavior.
>>>   return Object.create(Example.prototype);
>>> }
>>> Example.prototype.sharedObject = {
>>> counter: 0
>>> };
>>> const e1 = new Example();
>>> const e2 = new Example();
>>> console.log(e2.sharedObject.counter); // 0
>>> ++e1.sharedObject.counter;
>>> console.log(e2.sharedObject.counter); // 1
>>> ```
>>> This is what I meant when I said that the existing behavior isn't lost.
>>> There are still plenty of ways to achieve the foot-gun behavior if that is
>>> what's desired. What this proposal seeks is a means of making the most
>>> common path foot-gun free.
>>>
>>> Besides, a cleaner result can be achieved by using a static property.
>>> ```js
>>> class Example {
>>> }
>>> Example.counter = 0;
>>>
>>> const e1 = new Example();
>>> const e2 = new Example();
>>> console.log(e2.constructor.counter); // 0
>>> ++e1.constructor.counter;
>>> console.log(e2.constructor.counter); // 1
>>> ```
>>>
>>>
>>> On Tue, Nov 27, 2018 at 10:30 AM T.J. Crowder <
>>> tj.crow...@farsightsoftware.com> wrote:
>>>
>>>> On Tue, Nov 27, 2018 at 3:34 PM Ranando King
>>>>  wrote:
>>>> > The fact that the prototype is a 1st class, (usually) mutable
>>>> > object doesn't change the fact that it is a template.
>>>>
>>>> It fundamentally does, calling prototypes templates rather
>>>> short-changes them. Again, they're live objects:
>>>>
>>>> ```js
>>>> class Example {
>>>> }
>>>> const e = new Example();
>>>> console.log(e.foo); // undefined
>>>> Example.prototype.foo = "bar";
>>>> console.log(e.foo); // "bar"
>>>> ```
>>>>
>>>> (http://jsfiddle.net/pot8cdq6/) A *template* wouldn't demonstrate that
>>>> sort of behavior. Perhaps it's just a semantic point, though.
>>>>
>>>> > As for changing `new` in an incompatible way, doesn't represent a
>>>> > significant or incompatible change in the behavior of `new`.
>>>>
>>>> Of course it does. If it didn't, it wouldn't solve the problem you
>>>> describe wanting to solve. Or was there some opt-in (other than the pragma)
>>>> that I missed? The problem you describe is perfectly valid current code:
>>>>
>>>> ```js
>>>> class Example {
>>>> }
>>>> Example.prototype.sharedObject = {
>>>> counter: 0
>>>> };
>>>> const e1 = new Example();
>>>> const e2 = new Example();
>>>> console.log(e2.sharedObject.counter); // 0
>>>> ++e1.sharedObject.counter;
>>>> console.log(e2.sharedObject.counter); // 1
>>>> ```
>>>>
>>>> (http://jsfiddle.net/m49jsxof/) Not something you'd want to do often,
>>>> but perfectly valid and I expect there are use cases for it, which changing
>>>> it would break.
>>>>
>>>> Re the rest: Yes, it's complicated to solve for nested properties. But
>>>> again, you just repeat the pattern, and/or use a Proxy; you can certainly
>>>> preserve prototypes as needed. The way in which you do so will vary
>>>> dramatically depending on what your use case is and how much you want to
>>>> copy, etc.
>>>>
>>>> I certainly don't see adding new semantics to `new`. I could see a
>>>> library function setting things up for you, but I think the patterns would
>>>> be so project-specific that it's unlikely to go into the standard library.
>>>>
>>>> I'll step back at this point.
>>>>
>>>> Best,
>>>>
>>>> -- 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: New: proposal-safe-prototype

2018-11-27 Thread Ranando King
Is this to say that no new feature is allowed to introduce breaking changes
in existing code?

On Tue, Nov 27, 2018 at 1:00 PM Jordan Harband  wrote:

> What I meant by "preserve existing behavior" is that *all current code*
> must retain the footgun. Any chance must only apply to new code that
> explicitly opts in to it.
>
> On Tue, Nov 27, 2018 at 10:55 AM Ranando King  wrote:
>
>> > Not something you'd want to do often...
>>
>> Or ever. This is the foot-gun behavior. The same result can be achieved
>> with a simple factory class.
>> ```js
>> class Example {
>>   //Don't use "this". It was flagged to use the updated prototype
>> behavior.
>>   return Object.create(Example.prototype);
>> }
>> Example.prototype.sharedObject = {
>> counter: 0
>> };
>> const e1 = new Example();
>> const e2 = new Example();
>> console.log(e2.sharedObject.counter); // 0
>> ++e1.sharedObject.counter;
>> console.log(e2.sharedObject.counter); // 1
>> ```
>> This is what I meant when I said that the existing behavior isn't lost.
>> There are still plenty of ways to achieve the foot-gun behavior if that is
>> what's desired. What this proposal seeks is a means of making the most
>> common path foot-gun free.
>>
>> Besides, a cleaner result can be achieved by using a static property.
>> ```js
>> class Example {
>> }
>> Example.counter = 0;
>>
>> const e1 = new Example();
>> const e2 = new Example();
>> console.log(e2.constructor.counter); // 0
>> ++e1.constructor.counter;
>> console.log(e2.constructor.counter); // 1
>> ```
>>
>>
>> On Tue, Nov 27, 2018 at 10:30 AM T.J. Crowder <
>> tj.crow...@farsightsoftware.com> wrote:
>>
>>> On Tue, Nov 27, 2018 at 3:34 PM Ranando King
>>>  wrote:
>>> > The fact that the prototype is a 1st class, (usually) mutable
>>> > object doesn't change the fact that it is a template.
>>>
>>> It fundamentally does, calling prototypes templates rather short-changes
>>> them. Again, they're live objects:
>>>
>>> ```js
>>> class Example {
>>> }
>>> const e = new Example();
>>> console.log(e.foo); // undefined
>>> Example.prototype.foo = "bar";
>>> console.log(e.foo); // "bar"
>>> ```
>>>
>>> (http://jsfiddle.net/pot8cdq6/) A *template* wouldn't demonstrate that
>>> sort of behavior. Perhaps it's just a semantic point, though.
>>>
>>> > As for changing `new` in an incompatible way, doesn't represent a
>>> > significant or incompatible change in the behavior of `new`.
>>>
>>> Of course it does. If it didn't, it wouldn't solve the problem you
>>> describe wanting to solve. Or was there some opt-in (other than the pragma)
>>> that I missed? The problem you describe is perfectly valid current code:
>>>
>>> ```js
>>> class Example {
>>> }
>>> Example.prototype.sharedObject = {
>>> counter: 0
>>> };
>>> const e1 = new Example();
>>> const e2 = new Example();
>>> console.log(e2.sharedObject.counter); // 0
>>> ++e1.sharedObject.counter;
>>> console.log(e2.sharedObject.counter); // 1
>>> ```
>>>
>>> (http://jsfiddle.net/m49jsxof/) Not something you'd want to do often,
>>> but perfectly valid and I expect there are use cases for it, which changing
>>> it would break.
>>>
>>> Re the rest: Yes, it's complicated to solve for nested properties. But
>>> again, you just repeat the pattern, and/or use a Proxy; you can certainly
>>> preserve prototypes as needed. The way in which you do so will vary
>>> dramatically depending on what your use case is and how much you want to
>>> copy, etc.
>>>
>>> I certainly don't see adding new semantics to `new`. I could see a
>>> library function setting things up for you, but I think the patterns would
>>> be so project-specific that it's unlikely to go into the standard library.
>>>
>>> I'll step back at this point.
>>>
>>> Best,
>>>
>>> -- 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: New: proposal-safe-prototype

2018-11-27 Thread Ranando King
> Not something you'd want to do often...

Or ever. This is the foot-gun behavior. The same result can be achieved
with a simple factory class.
```js
class Example {
  //Don't use "this". It was flagged to use the updated prototype behavior.
  return Object.create(Example.prototype);
}
Example.prototype.sharedObject = {
counter: 0
};
const e1 = new Example();
const e2 = new Example();
console.log(e2.sharedObject.counter); // 0
++e1.sharedObject.counter;
console.log(e2.sharedObject.counter); // 1
```
This is what I meant when I said that the existing behavior isn't lost.
There are still plenty of ways to achieve the foot-gun behavior if that is
what's desired. What this proposal seeks is a means of making the most
common path foot-gun free.

Besides, a cleaner result can be achieved by using a static property.
```js
class Example {
}
Example.counter = 0;

const e1 = new Example();
const e2 = new Example();
console.log(e2.constructor.counter); // 0
++e1.constructor.counter;
console.log(e2.constructor.counter); // 1
```


On Tue, Nov 27, 2018 at 10:30 AM T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Tue, Nov 27, 2018 at 3:34 PM Ranando King
>  wrote:
> > The fact that the prototype is a 1st class, (usually) mutable
> > object doesn't change the fact that it is a template.
>
> It fundamentally does, calling prototypes templates rather short-changes
> them. Again, they're live objects:
>
> ```js
> class Example {
> }
> const e = new Example();
> console.log(e.foo); // undefined
> Example.prototype.foo = "bar";
> console.log(e.foo); // "bar"
> ```
>
> (http://jsfiddle.net/pot8cdq6/) A *template* wouldn't demonstrate that
> sort of behavior. Perhaps it's just a semantic point, though.
>
> > As for changing `new` in an incompatible way, doesn't represent a
> > significant or incompatible change in the behavior of `new`.
>
> Of course it does. If it didn't, it wouldn't solve the problem you
> describe wanting to solve. Or was there some opt-in (other than the pragma)
> that I missed? The problem you describe is perfectly valid current code:
>
> ```js
> class Example {
> }
> Example.prototype.sharedObject = {
> counter: 0
> };
> const e1 = new Example();
> const e2 = new Example();
> console.log(e2.sharedObject.counter); // 0
> ++e1.sharedObject.counter;
> console.log(e2.sharedObject.counter); // 1
> ```
>
> (http://jsfiddle.net/m49jsxof/) Not something you'd want to do often, but
> perfectly valid and I expect there are use cases for it, which changing it
> would break.
>
> Re the rest: Yes, it's complicated to solve for nested properties. But
> again, you just repeat the pattern, and/or use a Proxy; you can certainly
> preserve prototypes as needed. The way in which you do so will vary
> dramatically depending on what your use case is and how much you want to
> copy, etc.
>
> I certainly don't see adding new semantics to `new`. I could see a library
> function setting things up for you, but I think the patterns would be so
> project-specific that it's unlikely to go into the standard library.
>
> I'll step back at this point.
>
> Best,
>
> -- T.J. Crowder
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New: proposal-known-keys

2018-11-27 Thread Ranando King
> However, it might end up like
Object.assign(Object.assignInherited(target, source), source) so that maybe
it's better if inherited copies also own properties.

Andrea, that's why I'm using "known". Basically, `if (prop in obj)` and
`prop` is enumerable, then it will appear in `Object.knownKeys(obj)`. These
modified versions take into account all "known" enumerable keys. I could
also see a set of "inherited" functions, but I can't see where they'd have
the same utility as "own" and "known".

>  I haven't seen an issue with people making odd design decisions "just"
to make properties own properties.

T.J., The limitations of the existing functions are a current and (even in
my book) valid argument in favor of the public-fields proposal. But the
public-fields proposal introduces a lesser-of-2-evils type problem into the
language:
* choose [[Set]] semantics and risk losing some future potential for
language expansion
* choose [[Define]] semantics and break inheritance involving accessor
properties
* choose both and increase the complexity of the engine, leaving the
decision to the developer as per current ES
* choose neither and deal with either the objects-on-prototype foot-gun or
developers being too sloppy with `super`

Currently, public-fields is attempting to push through the 2nd option here,
despite the damage it will cause. That's an odd design decision, especially
considering the 3rd option is superior to the first 2, and the 4th option
is even more viable still if the foot-gun is surgically fixed. As you
already know, I've got a proposal for that .

On Tue, Nov 27, 2018 at 3:59 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> FWIW I'd change the name to inherited:
>
>  * assignInherited
>  * inheritedKeys
>  * ...
>
> and I'd probably skip own, at least it's clear the method does something
> else.
>
> However, it might end up like Object.assign(Object.assignInherited(target,
> source), source) so that maybe it's better if inherited copies also own
> properties.
>
>
>
> On Tue, Nov 27, 2018 at 8:36 AM T.J. Crowder <
> tj.crow...@farsightsoftware.com> wrote:
>
>> On Tue, Nov 27, 2018 at 5:14 AM Ranando King
>>  wrote:
>>
>> Do you have any evidence to back up the assertions in the Motivation
>> section? I haven't seen an issue with people making odd design
>> decisions "just" to make properties own properties.
>>
>> -- 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: New: proposal-safe-prototype

2018-11-27 Thread Ranando King
> Not in a prototypical language. Again, prototypes are living objects
(even though lots of code doesn't make use of that fact).

The fact that the prototype is a 1st class, (usually) mutable object
doesn't change the fact that it is a template. Templates come in many
forms, not all of which are of the "rubber stamp" variety. The design of ES
is such that for any given object, all properties of its prototype behave
as though they are own properties (`var a = {__proto__: {b: 42}};` -> `a.b
=== 42;), even though they're not (`Object.keys(a).length === 0`). Further,
any attempt to change the top level value of any prototype property through
the object causes an own property to be created on the object instead of
modifying the prototype. It is this behavior that I'm referencing when I
say that a prototype serves the role of a template for classes in a
prototype-oriented language. When you want a property to exist in every
instance of the class, you can either manually create the property in the
constructor, or you can put it on the prototype and rest assured that every
new instance will behave as though it has its own copy (unless the value is
an object).

As for changing `new` in an incompatible way, doesn't represent a
significant or incompatible change in the behavior of `new`. The only thing
different `new` will do is mark an internal slot on the newly created
object, flagging it to use the new behavior when accessing `__proto__`.
There is no other behavioral change for `new`. The real behavior of this
proposal happens when accessing an object data property from the flagged
object's prototype.

> Depending on the use case, you just repeat the pattern, or use a Proxy,
or...

Let's say you've got some heavily nested structure on a prototype property.
Repeating this process for every nested object in the structure could be
excessively time consuming and certainly an exercise in tedium to write.
What if the language did it for you?
* On one extreme, you get the public-fields proposal. That just introduces
new foot guns for very little gain.
* In the middle, you've got values applied to the prototype, and then
applied again to the instance in the constructor. That blows the point of
having mutable prototypes.
* On the other extreme, you put properties on the prototype only. Then have
the language treat changes to the object property's structure or data as a
cue to copy.

This proposal is essentially what you're describing, except carried out by
language itself using data and structure mutations as the trigger. In all
honesty, I would really like to use your `Object.create` approach instead
of `Object.assign`, but since the object property may have a structure
including needed prototypes, and the original cannot be modified, that idea
won't work. The problem with your approach is that it doesn't account for
cases where the sub-property is on a prototype of a sub-object.

On Tue, Nov 27, 2018 at 1:32 AM T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Tue, Nov 27, 2018 at 3:24 AM Ranando King
>  wrote:
> > ...and from a class POV, the prototype serves the role of the
> > class template...
>
> Not in a prototypical language. Again, prototypes are living objects
> (even though lots of code doesn't make use of that fact). Code that
> *does* isn't uncommon, and can't just suddenly work differently.
>
> As Jordan said, `new` can't be changed in an incompatible way.
>
> > As for your suggestion, that doesn't work when the element being
> > changed is on a sub-property of the object.
>
> Depending on the use case, you just repeat the pattern, or use a Proxy,
> or...
>
> -- T.J. Crowder
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New: proposal-known-keys

2018-11-26 Thread Ranando King
Forgot to addd the link

https://github.com/rdking/proposal-known-keys

On Mon, Nov 26, 2018 at 11:11 PM Ranando King  wrote:

> This proposal adds 7 new static methods to `Object` that add support for
> dealing with all of the enumerable properties of objects with prototypes.
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


New: proposal-known-keys

2018-11-26 Thread Ranando King
This proposal adds 7 new static methods to `Object` that add support for
dealing with all of the enumerable properties of objects with prototypes.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New: proposal-safe-prototype

2018-11-26 Thread Ranando King
I've always understood the purpose of a prototype to be a means of
including pre-defined data and behavior in an object. Classes are just a
convenient means of defining those things in a prototype-oriented language,
and from a class POV, the prototype serves the role of the class template.
You did just make me think of something though. In the interest of not
adding another pragma, this feature could, and probably should be limited
to just the prototypes of objects created with the `new` keyword. This
would leave objects created manually alone, preserving the old behavior for
object literals and factory functions.

As for your suggestion, that doesn't work when the element being changed is
on a sub-property of the object.

```js
class Example {
  constructor() {
this.x = Object.create(this.x);
  }
}
Example.prototype.x = {
  y: {
a: 0,
b: 1,
c: 2
  }
};
const e1 = new Example();
const e2 = new Example();
console.log(e1.x === e2.x);// false
console.log(e1.x.hasOwnProperty("y")); // false
console.log(e2.x.hasOwnProperty("y")); // false
console.log(e1.x.y.c); // 2
console.log(e2.x.y.c); // 2
e1.x.y.c = 4;
console.log(e1.x.hasOwnProperty("y")); // false
console.log(e2.x.hasOwnProperty("y")); // false
console.log(e1.x.y);   // 4
console.log(e2.x.y);   // 4
```

On Mon, Nov 26, 2018 at 5:21 PM T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> From the proposal:
>
> > .,..some of which attempt to obviate the use of the prototype for
> > its intended purpose as the template for an instantiation by new...
>
> I wouldn't say that's "the intended purpose" of a prototype at all. That's
> more a class-centric view of prototypes. Prototypical inheritance is
> *different* from class-based inheritance. Prototypes aren't templates,
> they're living objects.
>
> If you want every instance of a class to have an object property that you
> can modify in a per-instance way, make that object property an object
> backed by a prototype:
>
> ```js
> class Example {
> constructor() {
> this.x = Object.create(this.x);
> }
> }
> Example.prototype.x = {
> y: 0
> };
> const e1 = new Example();
> const e2 = new Example();
> console.log(e1.x === e2.x);// false
> console.log(e1.x.hasOwnProperty("y")); // false
> console.log(e2.x.hasOwnProperty("y")); // false
> console.log(e1.x.y);   // 0
> console.log(e2.x.y);   // 0
> e1.x.y = 1;
> console.log(e1.x.hasOwnProperty("y")); // true
> console.log(e2.x.hasOwnProperty("y")); // false
> console.log(e1.x.y);   // 1
> console.log(e2.x.y);   // 0
> ```
>
> Once decorators are up and running, doing this could be a decorator,
> though I submit it's an edge case.
>
> -- T.J. Crowder
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


New: proposal-safe-prototype

2018-11-26 Thread Ranando King
The general idea is to eliminate the foot-gun of objects on a prototype by
providing copy on write semantics to properties on the prototype that
contain an object. The property must be a data property. Accessors and
functions are ignored.

https://github.com/rdking/proposal-safe-prototype
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Destructuring instances with private fields

2018-09-07 Thread Ranando King
I can make it work work under my proposal-object-members by making '#' a
postfix unary operator, but then it would have to be a syntax error to use
it that way unless we're dealing with a destructuring operation. That just
opens up too many ways to abuse it and leak the private container. So
that's a no-go as well.

On Thu, Sep 6, 2018 at 10:45 AM Isiah Meadows 
wrote:

> BTW, this just falls out of the grid with my private symbols suggestion
> https://github.com/tc39/proposal-class-fields/issues/115
>
> On Thu, Sep 6, 2018 at 10:14 Ranando King  wrote:
>
>> I can understand why this would be wanted. It would save some excess
>> typing. However, doesn't it also lead to the potential foot-gun of
>> forgetting to assign any modifications back to the original private field?
>> Also, since private fields aren't actually own properties of the instance,
>> how could they possibly be destructured? There's no programmatically
>> exposed listing of the private fields. Further, under proposal-class-fields
>> private fields are restricted to just `class` instances, so the
>> destructuring syntax doesn't make sense for that scenario. Basically it
>> would imply that the following is true:
>>
>> ```js
>> let bar1 = "bar", bar2;
>> ({ #fubar: bar2}) = { #fubar: bar1 };
>> bar1 === bar2;
>> ```
>>
>> Even if proposal-class-fields allowed for private fields on objects, it
>> wouldn't work. There's no way to reify the left side's `#fubar` as a
>> private name of the object on the right side before processing the object
>> on the right side. Put another way, without `obj.` in front of it, `#field`
>> cannot be lexically resolved as a private name while parsing unless the
>> parser, upon finding the object on the right side of the `=`, re-evaluates
>> the left side. Since destructuring can be arbitrarily complex, this becomes
>> a mess very nearly as complex as trying to accurately deep clone an
>> arbitrary object.
>>
>> On Wed, Sep 5, 2018 at 3:12 PM kdex  wrote:
>>
>>> Often times, when I use a class field a lot, I create a local binding
>>> for it,
>>> so that I don't have to prefix every appearance with `this.`:
>>>
>>> ```js
>>> class Foo {
>>> bar = 1;
>>> method() {
>>> const { bar } = this;
>>> /* … */
>>> }
>>> }
>>> ```
>>>
>>> The same approach would currently be illegal syntax if `bar` is declared
>>> to be
>>> private:
>>>
>>> ```js
>>> class Foo {
>>> #bar = 1;
>>> method() {
>>> const { #bar } = this;
>>> /* … */
>>> }
>>> }
>>> ```
>>>
>>> How is the destructuring assignment supposed to behave anyway? Introduce
>>> a
>>> local `bar` binding, just like above?
>>>
>>> Whatever it should do, even defining an explicit name for the binding is
>>> currently illegal:
>>>
>>> ```js
>>> class Foo {
>>> #bar = 1;
>>> method() {
>>> const { #bar: bar } = this;
>>> /* … */
>>> }
>>> }
>>> ```
>>>
>>> This feels really asymmetric to public fields and has come up in the
>>> class
>>> fields proposal[1] before, though it was suggested to defer it to a
>>> separate
>>> proposal.
>>>
>>> Is someone currently working on said proposal?
>>>
>>> [1] https://github.com/tc39/proposal-class-fields/issues/4
>>> ___
>>> 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: Destructuring instances with private fields

2018-09-06 Thread Ranando King
I can understand why this would be wanted. It would save some excess
typing. However, doesn't it also lead to the potential foot-gun of
forgetting to assign any modifications back to the original private field?
Also, since private fields aren't actually own properties of the instance,
how could they possibly be destructured? There's no programmatically
exposed listing of the private fields. Further, under proposal-class-fields
private fields are restricted to just `class` instances, so the
destructuring syntax doesn't make sense for that scenario. Basically it
would imply that the following is true:

```js
let bar1 = "bar", bar2;
({ #fubar: bar2}) = { #fubar: bar1 };
bar1 === bar2;
```

Even if proposal-class-fields allowed for private fields on objects, it
wouldn't work. There's no way to reify the left side's `#fubar` as a
private name of the object on the right side before processing the object
on the right side. Put another way, without `obj.` in front of it, `#field`
cannot be lexically resolved as a private name while parsing unless the
parser, upon finding the object on the right side of the `=`, re-evaluates
the left side. Since destructuring can be arbitrarily complex, this becomes
a mess very nearly as complex as trying to accurately deep clone an
arbitrary object.

On Wed, Sep 5, 2018 at 3:12 PM kdex  wrote:

> Often times, when I use a class field a lot, I create a local binding for
> it,
> so that I don't have to prefix every appearance with `this.`:
>
> ```js
> class Foo {
> bar = 1;
> method() {
> const { bar } = this;
> /* … */
> }
> }
> ```
>
> The same approach would currently be illegal syntax if `bar` is declared
> to be
> private:
>
> ```js
> class Foo {
> #bar = 1;
> method() {
> const { #bar } = this;
> /* … */
> }
> }
> ```
>
> How is the destructuring assignment supposed to behave anyway? Introduce a
> local `bar` binding, just like above?
>
> Whatever it should do, even defining an explicit name for the binding is
> currently illegal:
>
> ```js
> class Foo {
> #bar = 1;
> method() {
> const { #bar: bar } = this;
> /* … */
> }
> }
> ```
>
> This feels really asymmetric to public fields and has come up in the class
> fields proposal[1] before, though it was suggested to defer it to a
> separate
> proposal.
>
> Is someone currently working on said proposal?
>
> [1] https://github.com/tc39/proposal-class-fields/issues/4
> ___
> 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: constructor, super, and data members issue

2018-09-04 Thread Ranando King
With that line of thinking, the user "should **always** know what they've
done", meaning there's no need to avoid functionality in favor of avoiding
foot-guns. Yet...
As far as assigning a class definition directly to a field, developers
coming to JS/ES from other languages (especially Java) may not think so as
it is fairly common practice in some languages to define one class
completely inside another, but not inside any method of the outer class.
The exposure of such inner classes varies with the need for which it was
written. I wouldn't be so quick to discount this kind of assignment as
"niche". In either case, even if it does turn out to be niche and we ignore
that little restriction, that has little bearing on the potential solution
I've offered. This approach allows the value initializer to live in a
getter for the property on the prototype. The first access to the property
puts the value uniquely onto the instance. The example code isn't perfect,
but it does cover the basic idea. It might be better written like this:

```js
class Example {
  //classField = class{}; //Error
  otherField=[ "foo", "bar"];
}

class ES6Example {
  //classField ignored for this example since it was an error.
  get otherField() {
let _otherField_InitialValue_ = [ "foo", "bar" ];
if ((this instanceof ES6Example) &&
  !this.hasOwnProperty("otherField") &&
  Object.isExtensible(this) &&
  Object.getOwnPropertyDefinition(this.__proto__,
"otherField").configurable) {
  this.otherField = _otherField_InitialValue_;
}
return _otherField_InitialValue_;
  }
}
```


On Tue, Sep 4, 2018 at 12:39 AM Jordan Harband  wrote:

> I'd say that defining a class directly in a class field is extremely
> niche, and by doing that, the user "should know what they've done" too.
>
> On Mon, Sep 3, 2018 at 3:44 PM, Ranando King  wrote:
>
>> That scenario is intentional. I see no need to ban it. I would only want
>> to ban the confusing case of direct assignment in the outer class
>> declaration. For cases where the user intentionally defines a class as you
>> have done, they should know that what they've done will create a class that
>> is persistently re-defined with each instance. As has been said many times
>> before, it's good to reduce the number of foot-guns, but at some point, you
>> have to expect some level of responsibility from the programmer. Consider
>> that rule as little more than a safety switch.
>>
>> On Mon, Sep 3, 2018 at 3:52 PM Jordan Harband  wrote:
>>
>>> `field = (function () { return class { }; }())` - how exactly would you
>>> propose banning creating a class inside class fields?
>>>
>>> On Mon, Sep 3, 2018 at 12:05 PM, Ranando King  wrote:
>>>
>>>> I've been thinking about the problems around this some more. At first I
>>>> couldn't get past the dissenting arguments from issue #123, but I've since
>>>> come up with a solution that might work. What if:
>>>>
>>>> * Make it illegal to define a class directly on a class field in a
>>>> class declaration.
>>>> * Move the assignment portion of a class field declaration into a
>>>> getter on the prototype such that the getter sets an own property on the
>>>> instance if it doesn't exist, then returns that value
>>>>
>>>> What I mean is this:
>>>>
>>>> ```js
>>>> class Example {
>>>>   //classField = class{}; //Error
>>>>   otherField=[ "foo", "bar"];
>>>> }
>>>>
>>>> class ES6Example {
>>>>   //classField ignored for this example since it was an error.
>>>>   get otherField() {
>>>> if ((this instanceof ES6Example) &&
>>>> !this.hasOwnProperty("otherField"))
>>>>   this.otherField = [ "foo", "bar" ];
>>>> return this.otherField;
>>>>   }
>>>> }
>>>> ```
>>>>
>>>> Done this way, any code expecting early assignment of a field being
>>>> used as though it were "abstract" will still work as expected.
>>>>
>>>> On Thu, Aug 30, 2018 at 4:38 PM doodad-js Admin 
>>>> wrote:
>>>>
>>>>> I'm late to the party, but I've found a solution for my non-loved
>>>>> framework : have another constructor called before "super", which fills a
>>>>> faked "this" and a faked "args" then replicated values to "this" after
>>>>> doing "super(

Re: constructor, super, and data members issue

2018-09-03 Thread Ranando King
That scenario is intentional. I see no need to ban it. I would only want to
ban the confusing case of direct assignment in the outer class declaration.
For cases where the user intentionally defines a class as you have done,
they should know that what they've done will create a class that is
persistently re-defined with each instance. As has been said many times
before, it's good to reduce the number of foot-guns, but at some point, you
have to expect some level of responsibility from the programmer. Consider
that rule as little more than a safety switch.

On Mon, Sep 3, 2018 at 3:52 PM Jordan Harband  wrote:

> `field = (function () { return class { }; }())` - how exactly would you
> propose banning creating a class inside class fields?
>
> On Mon, Sep 3, 2018 at 12:05 PM, Ranando King  wrote:
>
>> I've been thinking about the problems around this some more. At first I
>> couldn't get past the dissenting arguments from issue #123, but I've since
>> come up with a solution that might work. What if:
>>
>> * Make it illegal to define a class directly on a class field in a class
>> declaration.
>> * Move the assignment portion of a class field declaration into a getter
>> on the prototype such that the getter sets an own property on the instance
>> if it doesn't exist, then returns that value
>>
>> What I mean is this:
>>
>> ```js
>> class Example {
>>   //classField = class{}; //Error
>>   otherField=[ "foo", "bar"];
>> }
>>
>> class ES6Example {
>>   //classField ignored for this example since it was an error.
>>   get otherField() {
>> if ((this instanceof ES6Example) &&
>> !this.hasOwnProperty("otherField"))
>>   this.otherField = [ "foo", "bar" ];
>> return this.otherField;
>>   }
>> }
>> ```
>>
>> Done this way, any code expecting early assignment of a field being used
>> as though it were "abstract" will still work as expected.
>>
>> On Thu, Aug 30, 2018 at 4:38 PM doodad-js Admin 
>> wrote:
>>
>>> I'm late to the party, but I've found a solution for my non-loved
>>> framework : have another constructor called before "super", which fills a
>>> faked "this" and a faked "args" then replicated values to "this" after
>>> doing "super(...fakedArgs)".
>>>
>>>
>>> https://github.com/doodadjs/doodad-js/blob/v9.1.3/src/common/Bootstrap.js#L5320-L5330
>>>
>>> -Original Message-
>>> From: Isiah Meadows 
>>> Sent: Sunday, August 26, 2018 3:29 PM
>>> To: Logan Smyth 
>>> Cc: Ben Wiley ; es-discuss <
>>> es-discuss@mozilla.org>
>>> Subject: Re: constructor, super, and data members issue
>>>
>>> Yeah, I was more focused on the static class side of things, because I
>>> thought they were referring to that. Class instance fields are different,
>>> and so of course, those are never set on the prototype unless for whatever
>>> reason, the parent constructor returns `Object.getPrototypeOf(this)`
>>> instead of letting it default to the normal `this`.
>>>
>>> My bad, and you are correct.
>>>
>>> -
>>>
>>> Isiah Meadows
>>> cont...@isiahmeadows.com
>>> www.isiahmeadows.com
>>>
>>> On Sun, Aug 26, 2018 at 12:20 PM Logan Smyth 
>>> wrote:
>>> >
>>> > Static class fields run their initializers and define the properties
>>> > at declaration time, and class constructors have the parent class as
>>> > the `[[Prototype]]`, so static field values are inherited. I think
>>> this is adding to confusion though, because while that's absolutely true,
>>> that is not applicable in the same way to non-static class fields, which is
>>> what this original email is focused on. You could indeed also address this
>>> with static properties in a proper ES6 environment as ``` class Base {
>>> >   static idAttribute = "id";
>>> >
>>> >   constructor() {
>>> >this.idAttribute = new.target.idAttribute;
>>> >   }
>>> > }
>>> > class Derived extends Base {
>>> >   static idAttribute = "_id";
>>> >
>>> >   constructor() {
>>> >super();
>>> >   }
>>> > }
>>> > ```
>>> >
>>> > On Sun, Aug 26, 2018 at 10:35 AM Isiah Meadows 
>>> wrote:
>>> >>
>>> >> Every obj

Re: constructor, super, and data members issue

2018-09-03 Thread Ranando King
Even with the suggestion I've made, I would still recommend keeping the
post-super() initialization function. It would simply get all of the class
fields from the prototype. Those that haven't already been initialized
would be, guaranteeing that all fields that need to be initialized would be
by the time they are needed in the code.

On Mon, Sep 3, 2018 at 2:05 PM Ranando King  wrote:

> I've been thinking about the problems around this some more. At first I
> couldn't get past the dissenting arguments from issue #123, but I've since
> come up with a solution that might work. What if:
>
> * Make it illegal to define a class directly on a class field in a class
> declaration.
> * Move the assignment portion of a class field declaration into a getter
> on the prototype such that the getter sets an own property on the instance
> if it doesn't exist, then returns that value
>
> What I mean is this:
>
> ```js
> class Example {
>   //classField = class{}; //Error
>   otherField=[ "foo", "bar"];
> }
>
> class ES6Example {
>   //classField ignored for this example since it was an error.
>   get otherField() {
> if ((this instanceof ES6Example) && !this.hasOwnProperty("otherField"))
>   this.otherField = [ "foo", "bar" ];
> return this.otherField;
>   }
> }
> ```
>
> Done this way, any code expecting early assignment of a field being used
> as though it were "abstract" will still work as expected.
>
> On Thu, Aug 30, 2018 at 4:38 PM doodad-js Admin 
> wrote:
>
>> I'm late to the party, but I've found a solution for my non-loved
>> framework : have another constructor called before "super", which fills a
>> faked "this" and a faked "args" then replicated values to "this" after
>> doing "super(...fakedArgs)".
>>
>>
>> https://github.com/doodadjs/doodad-js/blob/v9.1.3/src/common/Bootstrap.js#L5320-L5330
>>
>> -Original Message-
>> From: Isiah Meadows 
>> Sent: Sunday, August 26, 2018 3:29 PM
>> To: Logan Smyth 
>> Cc: Ben Wiley ; es-discuss <
>> es-discuss@mozilla.org>
>> Subject: Re: constructor, super, and data members issue
>>
>> Yeah, I was more focused on the static class side of things, because I
>> thought they were referring to that. Class instance fields are different,
>> and so of course, those are never set on the prototype unless for whatever
>> reason, the parent constructor returns `Object.getPrototypeOf(this)`
>> instead of letting it default to the normal `this`.
>>
>> My bad, and you are correct.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Sun, Aug 26, 2018 at 12:20 PM Logan Smyth 
>> wrote:
>> >
>> > Static class fields run their initializers and define the properties
>> > at declaration time, and class constructors have the parent class as
>> > the `[[Prototype]]`, so static field values are inherited. I think this
>> is adding to confusion though, because while that's absolutely true, that
>> is not applicable in the same way to non-static class fields, which is what
>> this original email is focused on. You could indeed also address this with
>> static properties in a proper ES6 environment as ``` class Base {
>> >   static idAttribute = "id";
>> >
>> >   constructor() {
>> >this.idAttribute = new.target.idAttribute;
>> >   }
>> > }
>> > class Derived extends Base {
>> >   static idAttribute = "_id";
>> >
>> >   constructor() {
>> >super();
>> >   }
>> > }
>> > ```
>> >
>> > On Sun, Aug 26, 2018 at 10:35 AM Isiah Meadows 
>> wrote:
>> >>
>> >> Every object, including functions, have an internal prototype.
>> Functions normally have one set to `Function.prototype`, and objects
>> normally inherit from `Object.prototype` at least indirectly. But because
>> of how prototypes work, the only requirement for something to be used as a
>> prototype is that it must be an object. So you can do
>> `Object.create(someFunction)` and although you can't call it (it's not a
>> callable object), that object inherits all the properties and methods from
>> that function. `class` in JavaScript is just sugar over a common pattern
>> (really complex sugar requiring `new.target` to emulate, but still sugar),
>> not an entirely new concept, and it all builds off of prototypes.
>> Specifically, the instance prototyp

Re: constructor, super, and data members issue

2018-09-03 Thread Ranando King
I've been thinking about the problems around this some more. At first I
couldn't get past the dissenting arguments from issue #123, but I've since
come up with a solution that might work. What if:

* Make it illegal to define a class directly on a class field in a class
declaration.
* Move the assignment portion of a class field declaration into a getter on
the prototype such that the getter sets an own property on the instance if
it doesn't exist, then returns that value

What I mean is this:

```js
class Example {
  //classField = class{}; //Error
  otherField=[ "foo", "bar"];
}

class ES6Example {
  //classField ignored for this example since it was an error.
  get otherField() {
if ((this instanceof ES6Example) && !this.hasOwnProperty("otherField"))
  this.otherField = [ "foo", "bar" ];
return this.otherField;
  }
}
```

Done this way, any code expecting early assignment of a field being used as
though it were "abstract" will still work as expected.

On Thu, Aug 30, 2018 at 4:38 PM doodad-js Admin  wrote:

> I'm late to the party, but I've found a solution for my non-loved
> framework : have another constructor called before "super", which fills a
> faked "this" and a faked "args" then replicated values to "this" after
> doing "super(...fakedArgs)".
>
>
> https://github.com/doodadjs/doodad-js/blob/v9.1.3/src/common/Bootstrap.js#L5320-L5330
>
> -Original Message-
> From: Isiah Meadows 
> Sent: Sunday, August 26, 2018 3:29 PM
> To: Logan Smyth 
> Cc: Ben Wiley ; es-discuss <
> es-discuss@mozilla.org>
> Subject: Re: constructor, super, and data members issue
>
> Yeah, I was more focused on the static class side of things, because I
> thought they were referring to that. Class instance fields are different,
> and so of course, those are never set on the prototype unless for whatever
> reason, the parent constructor returns `Object.getPrototypeOf(this)`
> instead of letting it default to the normal `this`.
>
> My bad, and you are correct.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
> On Sun, Aug 26, 2018 at 12:20 PM Logan Smyth 
> wrote:
> >
> > Static class fields run their initializers and define the properties
> > at declaration time, and class constructors have the parent class as
> > the `[[Prototype]]`, so static field values are inherited. I think this
> is adding to confusion though, because while that's absolutely true, that
> is not applicable in the same way to non-static class fields, which is what
> this original email is focused on. You could indeed also address this with
> static properties in a proper ES6 environment as ``` class Base {
> >   static idAttribute = "id";
> >
> >   constructor() {
> >this.idAttribute = new.target.idAttribute;
> >   }
> > }
> > class Derived extends Base {
> >   static idAttribute = "_id";
> >
> >   constructor() {
> >super();
> >   }
> > }
> > ```
> >
> > On Sun, Aug 26, 2018 at 10:35 AM Isiah Meadows 
> wrote:
> >>
> >> Every object, including functions, have an internal prototype.
> Functions normally have one set to `Function.prototype`, and objects
> normally inherit from `Object.prototype` at least indirectly. But because
> of how prototypes work, the only requirement for something to be used as a
> prototype is that it must be an object. So you can do
> `Object.create(someFunction)` and although you can't call it (it's not a
> callable object), that object inherits all the properties and methods from
> that function. `class` in JavaScript is just sugar over a common pattern
> (really complex sugar requiring `new.target` to emulate, but still sugar),
> not an entirely new concept, and it all builds off of prototypes.
> Specifically, the instance prototype inherits from the parent prototype,
> and the class constructor itself inherits from the parent constructor.
> That's why if you declare a static `call` method on a parent class, you can
> still access and use it in the subclass.
> >> On Sat, Aug 25, 2018 at 19:58 Ben Wiley 
> wrote:
> >>>
> >>> How can they be prototypically inherited if they don't live on the
> prototype? I feel like I'm missing something.
> >>>
> >>> Le sam. 25 août 2018 19 h 53, Isiah Meadows 
> a écrit :
> 
>  Class fields are prototypically inherited just like via `Object
> create`. This is more useful than you might think, and it's the main reason
> anyone actually cares about static fields beyond namespacing.
>  On Sat, Aug 25, 2018 at 14:36 Ben Wiley 
> wrote:
> >
> > All this just reminds me of *my opinion* that class fields is a
> borrowed concept from statically typed languages that is misplaced in a
> dynamically typed languages like JavaScript.
> >
> > In C++ I use class fields to declare what properties will be
> allocated and instantiated when a new class member is constructed.
> >
> > In the ES proposal for class fields we mimic this type of behavior
> by instantiating properties on the object when it's 

Re: __line_number__ and __filename__

2018-08-24 Thread Ranando King
Realistically, the engine would give back file name and line number (and
hopefully character offset) of the code from the fully translated, fully
minified, actual logic that the engine loaded. Source maps could be used to
convert that obscure value back into actual original source code locations.
It would also be nice if there were a way to perform a lookup at runtime, a
function that takes a function and returns the internal Location object for
that function.

On Fri, Aug 24, 2018 at 3:16 PM Aaron Gray 
wrote:

> Ideally at some point we won't be using transpilers anymore ;)
>
>
> On Fri, 24 Aug 2018 at 19:37, Bob Myers  wrote:
>
>> What does line number, or filename for that matter, mean when a file has
>> gone through one or more transpilation and/or minification passes?
>> Is the notion that the first processor that touches the file would
>> substitute those values?
>>
>> Bob
>>
>>
>> On Fri, Aug 24, 2018 at 11:34 PM Claude Pache 
>> wrote:
>>
>>>
>>>
>>> Le 24 août 2018 à 05:55, J Decker  a écrit :
>>>
>>> On Thu, Aug 23, 2018 at 5:26 PM Aaron Gray 
>>> wrote:
>>>
 I am debugging existing code that I have modularized, and am
 class'izing that has unittests and it just would have been very useful to
 have this facility.

>>> In a  browser, console.log is usually associated with the file and line
>>> number anyway; which includes using devtools with node but it would be
>>> handy for logging.  with V8 there is console.trace; which spits out the
>>> stack trace too... before I discovered that I did a logging function
>>> like...
>>>
>>> (from
>>> https://stackoverflow.com/questions/591857/how-can-i-get-a-javascript-stack-trace-when-i-throw-an-exception
>>> )
>>> function stackTrace() { var err = new Error(); return err.stack; }  //
>>> parse stack to get frame-1 online
>>>
>>> // or maybe just frame-1...
>>> function stackTrace() { var err = new Error(); return err.stack.split(
>>> "\n" )[1]; }
>>>
>>> ---
>>> function stacktrace() {
>>>   function st2(f) {
>>> return !f ? [] :
>>> st2(f.caller).concat([f.toString().split('(')[0].substring(9) +
>>> '(' + f.arguments.join(',') + ')']);
>>>   }
>>>   return st2(arguments.callee.caller);
>>> }
>>>
>>>  EDIT 2 (2017) :
>>>
>>> In all modern browsers you can simply call: console.trace(); (MDN
>>> Reference)
>>> ---
>>>
>>> Although I do still miss just being able to get __FILE__ and __LINE__
>>>
>>>
>>>
>>> See also:
>>>
>>> https://github.com/tc39/proposal-error-stacks
>>>
>>> If/when that proposal is implemented, you'll have a simple way to get a
>>> *structured* representation of the trace:
>>>
>>> ```js
>>> System.getTrace(new Error)
>>> ```
>>>
>>> from which you can much more easily extract line number, filename, etc.
>>>
>>> —Claude
>>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>
> --
> Aaron Gray
>
> Independent Open Source Software Engineer, Computer Language Researcher,
> Information Theorist, and amateur computer scientist.
> ___
> 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: constructor, super, and data members issue

2018-08-24 Thread Ranando King
Aaron, congratulations! You just tripped over a new reason for me to revive
issue #123. The only way to get that to work is to have the default values
on the prototype. The problem comes because `this` doesn't even have a
value until the last call to `super()` returns. If a `class` doesn't have a
base `class` it essentially has Object as a base `class` and `super` is
implicitly called. So unless the default public field values are on the
prototype, there's literally no way to have them initialized before the
base classes are initialized.

On Fri, Aug 24, 2018 at 3:15 PM Aaron Gray 
wrote:

> I am having an issue with order semantics regarding
> https://github.com/tc39/proposal-class-fields with derived classes
> defining or overriding data member values that are used in the base class
> constructor for initialization of properties of the class.
>
> This means the Super Class / Base Class'es constructor does not yet have
> access to the default field values of the derived class it is initiating.
>
> class Base {
> constructor() {
>  
>  .. idAttribute ..
>  
> }
> idAttribute = 'id';
> }
>class Derived extends Base {
> constructor() {
>  super();
>  
> }
> idAttribute = '_id';
>}
>
> All would mean having a separate initialize() function, but even this
> solution is flawed when there is a third level in the hierarchy. And as
> super() is required it means there seems to be no way round this issue. The
> only way I can see is some form of override keyword ?
>
>
> Has anyone got any solutions to this issue or work arounds ?
> --
> Aaron Gray
>
> Independent Open Source Software Engineer, Computer Language Researcher,
> Information Theorist, and amateur computer scientist.
> ___
> 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-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: Class data member declarations proposal idea

2018-08-08 Thread Ranando King
Did you see any similarity with my proposal-object-members
? It doesn't have type
annotation either. However, that's probably something best left to a
separate proposal since it would affect private and public members alike.

On Wed, Aug 8, 2018 at 7:50 AM Aaron Gray 
wrote:

> On Tue, 7 Aug 2018 at 22:34, Waldemar Horwat  wrote:
>
>> See this proposal, currently at stage 3:
>> https://github.com/tc39/proposal-class-fields
>>
>>
> Yes I did reference the proposal my mail.
>
> --
> Aaron Gray
>
> Independent Open Source Software Engineer, Computer Language Researcher,
> Information Theorist, and amateur computer scientist.
> ___
> 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-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 littl

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

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 broug

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

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

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 no

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

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

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

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

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 Ranando King
r 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, 

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 wa

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 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 Ranando King
t; >> >> >> > 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
>> >> >>

Re: !Re: proposal: Object Members

2018-07-29 Thread Ranando King
at was used to create that instance.
>
> Because I’m looking at this in terms of slots, I’d first point out that
> prototypes don’t determine slottedness, the execution of some specific
> constructor does. It’s during this process that slots are associated with
> the newly minted object by its identity. But even the current private
> fields proposal tracks this behavior closely, and I’m not sure how else it
> could work. The [[Prototype]] slot of an object is typically mutable
> (`R|O.setPrototypeOf`, `__proto__`) and forgeable (Proxy’s `getPrototypeOf`
> trap). Why/how would its value matter when it comes to accessing private
> state?
>
> ```js
> const pattern = /foo/;
> Reflect.setPrototypeOf(pattern, Date.prototype);
> pattern instanceof Date; // true
> pattern instanceof RegExp; // false
> pattern.getMinutes(); // throws TypeError because [[DateValue]] slot is
> missing
> RegExp.prototype.exec.call(pattern, 'foo'); // works; object has RegExp
> private slots
> ```
>
> > If I removed that requirement, it would work. However, there'd be no way
> to keep the private data from being leaked. Sadly, it's all or nothing with
> this approach. Hard private or soft private, those are the only choices.
>
> In the context of what you’ve described here this may be true, but no such
> limitation presently exists. We can already do all this — hard, leak-free
> privacy, brandedness, “friends” etc — with scopes and WeakMaps, but for the
> fact that the `WeakMap` intrinsics may be forged. So what’s baffled me is
> this: why are all the proposals exploring this space not addressing that
> relatively simple existing problem, and instead starting off from a place
> of significant new complexity? You said “maybe after the private fields
> problem has been resolved, someone will figure out a better way to handle
> your use cases,” but I’d have hoped for the opposite — I want the primitive
> building blocks which things like class field syntax could be built over,
> if it is found that they are still necessary once the root issue is solved
> for.
>
> > The main reason the privacy is set on a declaration level is because
> scope-level inheritance isn't very good for class-oriented inheritance.
>
> Can you explain this more? I’m not sure what’s meant by “scope-level
> inheritance” here.
>
> > I don't intend to stop [...]
>
> I very much admire your dedication! I’m also digging the discussion. I
> think we may be representing viewpoints at opposite extremes here, so it’s
> an interesting contrast, but it also probably means we may be lacking some
> context for understanding one another’s angles. I’d be curious to hear more
> about what you see as the problems with the current fields proposal + how
> your members proposal would solve them; the repo readme didn’t seem to
> include a rationale section.
>
> On Sat, Jul 28, 2018 at 10:30 PM Ranando King  wrote:
>
>> 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 = {
>&g

Re: !Re: proposal: Object Members

2018-07-28 Thread Ranando King
ust 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 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
>

Re: JSON support for BigInt in Chrome/V8

2018-07-28 Thread Ranando King
What I meant by complete is that if the value isn't an ES Number, isn't a
boolean, and isn't null, it will have a string representation, or a binary
representation that can be encoded as a string using base64. By using a
dataUri for those cases, we can create a consistent library to handle those
issues automatically, and without guesswork (no magic). If such a utility
API became a standard in ES, other languages would be far more likely to
adopt the standardized notation that would be provided.

On Sat, Jul 28, 2018 at 12:03 PM Michael Theriot <
michael.lee.ther...@gmail.com> wrote:

> I think we should move away from guessing and automagically parsing our
> JSON. The fact is a JSON number != JS number. Perhaps in userland (or a
> proposal...) JSON.parse could return with a JSONNumber object which the
> developer decides to convert to BigInt or Number.
>
> On Saturday, July 28, 2018, J Decker  wrote:
>
>>
>>
>> On Sat, Jul 28, 2018 at 6:57 AM Michael Theriot <
>> michael.lee.ther...@gmail.com> wrote:
>>
>>> In a language with arbitrary integer precision, Python 3 for example,
>>> the way to parse a "BigInt" would just be a plain, human readable number
>>> without quotes. The way to serialize it is the same. Any other kind of
>>> representation is out of spec, a workaround, and belongs in userland.
>>
>>
>> The problem with this, 'guessing' whether is't a Number() or a BigInt()
>> is that numbers and bigint's don't interop.
>>
>> {a:123, b:123n}
>> " { "a":123, "b":123 }"  any expressions that expect B to be a BigInt()
>> will fail, becasue it will be in an expression of other bigints.
>>
>> bigInts aren't just a better Number type, but, rather require other
>> bigints for their expressions.
>>
>>
>>
>>>
>>> I think BigInt should serialize the same, not as strings or anything
>>> that is not a number. JSON.parse being unable to parse back into BigInt is
>>> a separate issue. It is solvable by using better parsing methods, not the
>>> convenient built-in one which has other issues. E.g. a streaming JSON
>>> parser that lets you inspect the key name and string being parsed can
>>> handle this. Case solved and you can also redesign your code so you are not
>>> creating a temporary object every single parse that you most likely copy
>>> into actual objects later.
>>>
>>> Not serializing BigInt is questionable to me but even that can be solved
>>> in userland.
>>>
>>> On Saturday, July 14, 2018, Anders Rundgren <
>>> anders.rundgren@gmail.com> wrote:
>>>
 var small = BigInt("5");
 var big = BigInt("553");
 JSON.stringify([big,small]);
 VM330:1 Uncaught TypeError: Do not know how to serialize a BigInt
 at JSON.stringify ()
 at :1:6

 JSON Number serialization has apparently reached a new level (of
 confusion).

 Personally I don't see the problem.  XML did just fine without
 hard-coded data types.

 The JSON type system is basically a relic from JavaScript.  As such it
 has proved to be quite useful.
 However, when you are outside of that scope, the point with the JSON
 type system gets pretty much zero since you anyway need to map extended
 types.

 Oracle's JSON-B solution which serializes small values as Number and
 large values as String rather than having a unified serialization based on
 the underlying data type seems like a pretty broken concept although indeed
 fully conforming to the JSON specification. "Like the Devil reads the
 Bible" as we say in Scandinavia :-)

 Adding a couple of double quotes is a major problem?  If so, it seems
 like a way more useful project making quotes optional for keys (named in a
 specific way), like they already are in JavaScript.

 Yeah, and of course adding support for comments.

 Anders

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

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


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: JSON support for BigInt in Chrome/V8

2018-07-28 Thread Ranando King
Don't get me wrong. I didn't suggest a means of extending JSON. I suggested
a means of consistently and easily reversibly serializing anything that is
not natively handled by JSON already. I think JSON is a fairly complete
syntax for most purposes. I wish it had a reference type so that recursive
structures could be encoded as well, but the suggestion I've just made can
even be used to encode that.

On Sat, Jul 28, 2018 at 10:52 AM Anders Rundgren <
anders.rundgren@gmail.com> wrote:

> On 2018-07-28 16:52, Ranando King wrote:
> > Why not just use DataURL syntax, something like this:
> >
> > ```js
> > {
> >"field1":
> "data:json/bigint,12345678901234567890123456789012345678901234567890123456789012345678901234567890",
> >...
> > }
> > ```
> > This way, even as other objects pop up to be serialized, all that would
> be needed is another mime type in the format "json/". I could
> even see letting the "" portion hold the non-lowercased, original
> class name to make it even faster to deserialize such fields without
> knowing all possible mime types in advance. Still 100% compatible with
> existing JSON. Still 100% human readable/writable. Very easy to implement,
> and self consistent.
> >
>
> I think the issue is rather: What problem do we want to solve?
>
> It is pretty obvious that there is no "perfect" solution.
>
> XML proves that there is no need for explicit type information in an
> information exchange format. Most sophisticated systems map keys in some
> way making explicit type information redundant.  That JSON do have a set of
> distinct data types is great, but extending that type scheme outside of the
> original JavaScript core, IMO only creates problems.  Nobody (in their
> right mind) would even think of designing a typed format where everything
> from a byte to BigDecimal would be represented as a single type.
>
> Anders
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: JSON support for BigInt in Chrome/V8

2018-07-28 Thread Ranando King
Why not just use DataURL syntax, something like this:

```js
{
  "field1":
"data:json/bigint,12345678901234567890123456789012345678901234567890123456789012345678901234567890",
  ...
}
```
This way, even as other objects pop up to be serialized, all that would be
needed is another mime type in the format "json/". I could even
see letting the "" portion hold the non-lowercased, original
class name to make it even faster to deserialize such fields without
knowing all possible mime types in advance. Still 100% compatible with
existing JSON. Still 100% human readable/writable. Very easy to implement,
and self consistent.

On Sat, Jul 28, 2018 at 9:11 AM Isiah Meadows 
wrote:

> > Not serializing BigInt is questionable to me but even that can be solved
> in userland.
>
> This is pretty easy for `JSON.stringify`, at least: you specify a
> reviver that coerces them to numbers:
>
> ```js
> JSON.stringify(object, null, (k, v) => typeof v === "bigint" ? Number(v) :
> v)
> ```
>
> The deserialization of that is trickier, but it's easy worked around.
>
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
> On Sat, Jul 28, 2018 at 9:56 AM, Michael Theriot
>  wrote:
> >
> > In a language with arbitrary integer precision, Python 3 for example,
> the way to parse a "BigInt" would just be a plain, human readable number
> without quotes. The way to serialize it is the same. Any other kind of
> representation is out of spec, a workaround, and belongs in userland.
> >
> > I think BigInt should serialize the same, not as strings or anything
> that is not a number. JSON.parse being unable to parse back into BigInt is
> a separate issue. It is solvable by using better parsing methods, not the
> convenient built-in one which has other issues. E.g. a streaming JSON
> parser that lets you inspect the key name and string being parsed can
> handle this. Case solved and you can also redesign your code so you are not
> creating a temporary object every single parse that you most likely copy
> into actual objects later.
> >
> > Not serializing BigInt is questionable to me but even that can be solved
> in userland.
> >
> > On Saturday, July 14, 2018, Anders Rundgren <
> anders.rundgren@gmail.com> wrote:
> >>
> >> var small = BigInt("5");
> >> var big = BigInt("553");
> >> JSON.stringify([big,small]);
> >> VM330:1 Uncaught TypeError: Do not know how to serialize a BigInt
> >> at JSON.stringify ()
> >> at :1:6
> >>
> >> JSON Number serialization has apparently reached a new level (of
> confusion).
> >>
> >> Personally I don't see the problem.  XML did just fine without
> hard-coded data types.
> >>
> >> The JSON type system is basically a relic from JavaScript.  As such it
> has proved to be quite useful.
> >> However, when you are outside of that scope, the point with the JSON
> type system gets pretty much zero since you anyway need to map extended
> types.
> >>
> >> Oracle's JSON-B solution which serializes small values as Number and
> large values as String rather than having a unified serialization based on
> the underlying data type seems like a pretty broken concept although indeed
> fully conforming to the JSON specification. "Like the Devil reads the
> Bible" as we say in Scandinavia :-)
> >>
> >> Adding a couple of double quotes is a major problem?  If so, it seems
> like a way more useful project making quotes optional for keys (named in a
> specific way), like they already are in JavaScript.
> >>
> >> Yeah, and of course adding support for comments.
> >>
> >> Anders
> >>
> >> ___
> >> es-discuss mailing list
> >> es-discuss@mozilla.org
> >> https://mail.mozilla.org/listinfo/es-discuss
> >
> >
> > ___
> > es-discuss mailing list
> > es-discuss@mozilla.org
> > https://mail.mozilla.org/listinfo/es-discuss
> >
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


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

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-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: javascript vision thing

2018-07-26 Thread Ranando King
Here's the funny part:

JSON = JavaScript Object Notation

If the OP wants to see improvements in JSON, why not just submit a proposal
to alter what ES can do with JSON? If it makes it to stage 4, there's a
pretty good chance that the standard for JSON will also change as a result.
Sitting around complaining about what's wrong means nothing if you're not
even willing to think about a solution and take action accordingly.

On Thu, Jul 26, 2018 at 9:55 AM Luan Nico 
wrote:

> Another lurker, and I agree with both points:
>
>  * I think JS *is* useful for way more than just the Web. It might not be
> my favorite language of all times, but sure is near the top and my language
> of choice for several non-web projects, specially bash scripts (I have
> simple bash utility in JS that I use daily, for instance).
>  * I think the new additions were a almost a panacea for a lot of
> drawbacks I had with the language while developing for the web (and not),
> including basic frontend websites, especially things like; async/await,
> destructors, spread operator and default values for parameters. I sincerely
> cannot believe one could not see the usefulness and benefit of the latter,
> for instance, in any project of any type whatsoever, in a language without
> method overloading.
>
> IMHO these additions shed a light on JS that made it stand on the top with
> the others as a completely valid, useful, powerful, easy to write and read,
> pretty, delightful language to code tiny or massive web apps or other
> projects. I like most of the discussions here, that's why I follow the list
> (I really like the recent Object.pick, for instance, and would personally
> really like to see my proposed (and many other before me of whom I was
> unaware) array.flatten), but this particularly topic doesn't seem very
> productive. Changes have been made, and I love them, but they are optional,
> backwards compatibility is the absolute goal.
>
> If one has specific and well defined proposals, independent of the
> philosophy behind them, I'd love to see them made in other topics,
> specially if they come from someone who doesn't quite like what we have so
> far. This broad and vague rambling, OTOH, doesn't seem to be adding much.
> But those are just my couple cents, and in no way I incentivize banning a
> topic or conversation or nothing of the sort (one can just ignore it if he
> doesn't like to read). I have to add, if you allow me to, it's actually
> quite funny to skim through when you have some spare time, and can be very
> instructive too (some good points on both sides).
>
> On Wed, Jul 25, 2018 at 4:05 PM Isiah Meadows 
> wrote:
>
>> In my experience, Electron is great for prototyping, but it's a mild pain
>> to scale, and creating packaged binaries required building a massive
>> toolkit just to get something that worked for most cases. Bundling scripts
>> for Node itself is still a minor pain, enough that most projects don't
>> bother, and testing support with bundled projects is also a bit sucky.
>> Electron doesn't really help much in this area, since it's more Node than
>> browser, absorbing all the testing and building warts it has. Oh, and don't
>> forget that you *have* to (at least pre-N-API) recompile native extensions
>> to work with it, which is incredibly inconvenient to set up.
>>
>> Not like this isn't solvable by more tooling, but eventually, it's going
>> to feel like the typical Java + Maven + Ant monstrosity, just replaced with
>> a mess of CLI apps instead. This isn't an issue for prototyping or larger
>> apps where this might affect your workflow minimally, but it's certainly an
>> issue when trying to scale initially. It's not really impossible, just
>> annoying and full of potholes while you hook up all the boilerplate.
>>
>> On Wed, Jul 25, 2018, 13:42 Pier Bover  wrote:
>>
>>> Lurker here, I also agree with most points expressed by T.J. Crowder.
>>>
>>> JavaScript is a scripting language that can serve many purposes. I think
>>> the addition of class and async/await only make the language better, and if
>>> optional static types were included (a la TypeScript or ES4) it would
>>> probably make JavaScript the best scripting language.
>>>
>>> I also think the Node ecosystem is a mess, and that Electron is a
>>> plague, but those points are completely unrelated to the language itself.
>>> There are projects such as https://nodekit.io/ that aim to provide a
>>> bloat-free universal Electron / Cordova replacement.
>>>
>>> On Wed, Jul 25, 2018 at 12:00 PM, Jacob Pratt 
>>> wrote:
>>>
 Mostly a lurker here. I fully agree with your points, and also use JS
 for non-web projects.

 On Wed, Jul 25, 2018, 07:34 T.J. Crowder <
 tj.crow...@farsightsoftware.com> wrote:

> Lurkers: If I'm alone in this, please say so. If I'm **not** alone,
> please say so (publicly this time). Either way, I'm done as of this 
> message
> other than linking back to it.
>
> On Wed, Jul 25, 2018 

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] Persistent variables in functions/methods

2018-07-26 Thread Ranando King
Even if we don't get do expressions, the proposal I've recently submitted
includes this ability as a side effect.

https://github.com/rdking/proposal-object-members/blob/master/README.md

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

> On Wed, Jul 25, 2018 at 12:02 PM, Herbert Vojčík
>  wrote:
> > If we get do expressions, we can, afaict, simply do...
>
> Very good point. It's nicely concise, too.
>
> -- 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-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


  1   2   >