Re: Beforeunload for PWA

2021-03-30 Thread Jordan Harband
PWAs and events aren't part of the JS language; see
https://html.spec.whatwg.org

On Tue, Mar 30, 2021 at 5:39 AM Adam Eisenreich  wrote:

> I think that PWA should have the ability to override the default
> beforeunloadEvent message.
>
> Since returning string is already deprecated and removed from all
> browsers, it would be safe to change how the returned value is handeled.
>
> *All proposed changes should only apply to installed PWAs!*
>
> If the return value is:
>
>1. HTMLFormElement - display the element in front of everything with a
>backdrop disabling every other interaction.
>* CSS of the page should apply to this element.
>* Browser listens to the "submit" event of the form; based on the
>truthiness of the return value from the form submit event either close
>window or hide message while keeping window open
>* Closing the window via system buttons a second time (while dialog is
>open) will force the closing of the page.
>2. String - Display the standard beforeunload dialog that used to have
>the custom message.
>
> What are your thoughts? Should PWA have the exception and have elevated
> possibilities?
> ___
> 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: Since JSDoc seems cerebrally dead...

2020-11-11 Thread Jordan Harband
\([\S\s]*?\))\s*?\{\n?(\s*?\/\*[\S\s]*?\*\/)/
>> >> > ), function (ignore, signature, comment) {
>> >> >     html += "function " + name + " " + signature.trim()
>> + "\n";
>> >> > html += "\n" + comment + "\n\n";
>> >> > html += "\n";
>> >> > });
>> >> > }
>> >> > });
>> >> > html += "\n";
>> >> > console.log(html);
>> >> > ```
>> >> >
>> >> > output
>> >> > ```html
>> >> > 
>> >> >
>> >> > function foo1 (aa, bb)
>> >> > 
>> >> > /*
>> >> >  * this function will blah blah blah
>> >> >  */
>> >> > 
>> >> >
>> >> > function foo2 (cc, dd)
>> >> > 
>> >> > /*
>> >> >  * this function will yada yada yada
>> >> >  */
>> >> > 
>> >> >
>> >> > 
>> >> > ```
>> >> >
>> >> >
>> >> > On Wed, Oct 14, 2020 at 5:25 AM Michaël Rouges <
>> michael.rou...@gmail.com> wrote:
>> >> >>
>> >> >> Sorry but my question isn't about providing a tool to generate our
>> documentations but to have a standard syntax to describe our code
>> (signatures). ;)
>> >> >>
>> >> >>
>> >> >> Michaël Rouges - https://github.com/Lcfvs - @Lcfvs
>> >> >>
>> >> >>
>> >> >> Le mar. 13 oct. 2020 à 01:29, Jordan Harband  a
>> écrit :
>> >> >>>
>> >> >>> Hopefully (imo) people are hand-writing more docs now, rather than
>> relying on autogenerated prose.
>> >> >>>
>> >> >>> On Mon, Oct 12, 2020 at 1:23 PM #!/JoePea  wrote:
>> >> >>>>
>> >> >>>> Why not? People are generating less docs now? That doesn't sound
>> good!
>> >> >>>>
>> >> >>>> #!/JoePea
>> >> >>>>
>> >> >>>> On Mon, Aug 17, 2020 at 4:15 PM Isiah Meadows <
>> cont...@isiahmeadows.com> wrote:
>> >> >>>> >
>> >> >>>> > JSDoc is not dead (far from it), people just don't frequently
>> use
>> >> >>>> > automated docs generation tooling in the JS community. Most the
>> actual
>> >> >>>> > use JSDoc provides nowadays is editor autocomplete hints and
>> >> >>>> > integrating with TypeScript (in cases where changing the
>> extension
>> >> >>>> > isn't possible for whatever reason), so while it's still
>> useful, it's
>> >> >>>> > just not used in the same places it was used previously.
>> >> >>>> >
>> >> >>>> > -
>> >> >>>> >
>> >> >>>> > Isiah Meadows
>> >> >>>> > cont...@isiahmeadows.com
>> >> >>>> > www.isiahmeadows.com
>> >> >>>> >
>> >> >>>> > On Sun, Aug 16, 2020 at 6:39 PM Michaël Rouges <
>> michael.rou...@gmail.com> wrote:
>> >> >>>> > >
>> >> >>>> > > Hi all,
>> >> >>>> > >
>> >> >>>> > > Since JSDoc seems cerebrally dead, why the TC39 doesn't make
>> a real documentation standard, evolving with the langage?
>> >> >>>> > >
>> >> >>>> > > Actually, a part of  the JS community are exiling to TS to
>> type anything and the rest are just despited by the very outdated version
>> of JSDoc but don't want to add TS to their stack.
>> >> >>>> > >
>> >> >>>> > > IMHO, it's really urgent to have something formal to solve
>> that missing point of my favorite language.
>> >> >>>> > >
>> >> >>>> > > What would it take to make this dream come true, please?
>> >> >>>> > >
>> >> >>>> > >
>> >> >>>> > > Michaël Rouges - https://github.com/Lcfvs - @Lcfvs
>> >> >>>> > > ___
>> >> >>>> > > 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
>> >> >
>> >> > ___
>> >> > 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: Why does Object.keys return an Array instead of a Set?

2020-10-18 Thread Jordan Harband
`new Set(Object.keys(obj))` seems pretty straightforward - I doubt it's
worth adding something to the language just to make that shorter.

Separately, if you're looking for a deduped O(1) lookup of key presence,
you already have _an object_ - `Object.prototype.hasOwnProperty.call(obj,
key)`.

On Sun, Oct 18, 2020 at 8:28 AM Ehab Alsharif 
wrote:

> Other than the fact that Object.keys existed really before Sets, you are
> comparing apples and oranges here in your benchmarks.
> the include method has to scan the array in order to find elements, but
> sets are objects which are just hash tables.
> Also you typically don't get the keys array to check that a key is there,
> you can do that directly using the object you have.
> Another thing is that the typical use case for Object.keys is to get an
> iterator over the keys, returning a set for that purpose does not serve
> that purpose directly.
>
> On Sat, Oct 17, 2020 at 4:51 AM #!/JoePea  wrote:
>
>> Sets are faster, even for tiny lists of four items. See the perf tests
>> (tested in Chrome):
>>
>> https://twitter.com/trusktr/status/1315848017535098880
>>
>> https://twitter.com/trusktr/status/1317281652540731392
>>
>> #!/JoePea
>> ___
>> 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: Why does Object.keys return an Array instead of a Set?

2020-10-17 Thread Jordan Harband
Because Object.keys was standardized in 2009, 6 years before Set existed.

On Fri, Oct 16, 2020 at 6:51 PM #!/JoePea  wrote:

> Sets are faster, even for tiny lists of four items. See the perf tests
> (tested in Chrome):
>
> https://twitter.com/trusktr/status/1315848017535098880
>
> https://twitter.com/trusktr/status/1317281652540731392
>
> #!/JoePea
> ___
> 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: Since JSDoc seems cerebrally dead...

2020-10-12 Thread Jordan Harband
Hopefully (imo) people are hand-writing more docs now, rather than relying
on autogenerated prose.

On Mon, Oct 12, 2020 at 1:23 PM #!/JoePea  wrote:

> Why not? People are generating less docs now? That doesn't sound good!
>
> #!/JoePea
>
> On Mon, Aug 17, 2020 at 4:15 PM Isiah Meadows 
> wrote:
> >
> > JSDoc is not dead (far from it), people just don't frequently use
> > automated docs generation tooling in the JS community. Most the actual
> > use JSDoc provides nowadays is editor autocomplete hints and
> > integrating with TypeScript (in cases where changing the extension
> > isn't possible for whatever reason), so while it's still useful, it's
> > just not used in the same places it was used previously.
> >
> > -
> >
> > Isiah Meadows
> > cont...@isiahmeadows.com
> > www.isiahmeadows.com
> >
> > On Sun, Aug 16, 2020 at 6:39 PM Michaël Rouges 
> wrote:
> > >
> > > Hi all,
> > >
> > > Since JSDoc seems cerebrally dead, why the TC39 doesn't make a real
> documentation standard, evolving with the langage?
> > >
> > > Actually, a part of  the JS community are exiling to TS to type
> anything and the rest are just despited by the very outdated version of
> JSDoc but don't want to add TS to their stack.
> > >
> > > IMHO, it's really urgent to have something formal to solve that
> missing point of my favorite language.
> > >
> > > What would it take to make this dream come true, please?
> > >
> > >
> > > Michaël Rouges - https://github.com/Lcfvs - @Lcfvs
> > > ___
> > > 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] Provide a way to enforce integrity check on module imports

2020-08-01 Thread Jordan Harband
That seems like something that could possibly be achieved via
https://github.com/tc39/proposal-import-assertions

On Sat, Aug 1, 2020 at 1:15 AM Michaël Rouges 
wrote:

> Hi all,
>
> As proposed a year ago on an old repository (thanks to ljharb, noticed me
> that fact), on the browser side, the integrity check should be controllable
> **for each imported module**. Actually, it's just impossible to do it
> without bundling.
>
>
> https://github.com/tc39/proposal-dynamic-import/issues/76#issuecomment-494686580
>
> What's your opinion on this, please?
>
> Michaël Rouges - https://github.com/Lcfvs - @Lcfvs
> ___
> 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: Why does a JavaScript class getter for a private field fail using a Proxy?

2020-07-27 Thread Jordan Harband
oh oops, i meant `if (o !== this)` not `if (o.foo !== this)` :-)

On Mon, Jul 27, 2020 at 3:06 PM #!/JoePea  wrote:

> > `o.foo(); // works`
>
> I think there is something missing from that example as that line
> throws before it can get to the `new Proxy` line.
>
> #!/JoePea
>
> On Wed, Jul 15, 2020 at 10:47 PM Jordan Harband  wrote:
> >
> > So can:
> > ```jsx
> > const o = { foo() { if (o.foo !== this) { throw 'detected'; } } };
> > o.foo(); // works
> > new Proxy(o, {}).foo(); // throws
> > ```
> >
> > (as would a class that used a closed-over WeakMap for each "private
> field")
> >
> > Private fields do not introduce any new hazards here.
> >
> > On Tue, Jul 14, 2020 at 8:18 PM #!/JoePea  wrote:
> >>
> >> >  private members (safely) allow classes with internal slots.
> >>
> >> I'd say that they aren't safe, if they can break 3rd-party code on the
> >> external public side.
> >>
> >> #!/JoePea
> >>
> >> On Sun, Jul 12, 2020 at 3:09 PM Michael Theriot
> >>  wrote:
> >> >
> >> > I assume OP wants to use proxies and private members together. They
> are not designed to be compatible.
> >> >
> >> > Proxies and private members are a UX goal primarily for developers.
> Proxies easily allow observation of another object or creation of exotic
> objects (e.g. Array), and private members (safely) allow classes with
> internal slots. Since they cannot be used together the issue exists, and
> the hack circumvents this by reimplementing private in a way that does not
> require private fields.
> >> >
> >> > On Sun, Jul 12, 2020 at 4:45 PM kai zhu  wrote:
> >> >>
> >> >> as product-developer, can i ask what ux-objective you ultimately
> want achieved?
> >> >>
> >> >> ```js
> >> >> const sub = new Sub()
> >> >>
> >> >> // i'm a noob on proxies. what is this thing (with
> proxied-private-fields) ultimately used for?
> >> >> const proxy = new Proxy(sub, ...)
> >> >> ```
> >> >>
> >> >> On Sun, Jul 12, 2020 at 4:34 PM Michael Theriot <
> michael.lee.ther...@gmail.com> wrote:
> >> >>>
> >> >>> This does require you to have both the key and the weakmap though,
> so it actually does succeed in hiding the data so long as the weakmap is
> out of scope. I guess the issue I can foresee is that the key could be
> modified after the object is created.
> >> >>>
> >> >>> e.g.
> >> >>> ```js
> >> >>> var a = new A();
> >> >>> var key = Object.getOwnPropertySymbols(a)[0];
> >> >>> delete a[key];
> >> >>> a.hidden; // throws
> >> >>> ```
> >> >>>
> >> >>> That itself can be guarded by just making the key undeletable. So,
> I guess this solution could work depending what your goals are?
> >> >>>
> >> >>> On Sun, Jul 12, 2020 at 4:21 PM Michael Theriot <
> michael.lee.ther...@gmail.com> wrote:
> >> >>>>
> >> >>>> It nearly works, but the issue is that the key will be leaked by
> `Object.getOwnPropertySymbols(new A())`, so it's not truly private.
> >> >>>>
> >> >>>> There have been ideas proposing "private symbols" but I am not
> familiar with their issues, and I would guess with Class Fields they are
> unlikely to materialize anyway.
> >> >>>>
> >> >>>> On Sun, Jul 12, 2020 at 2:19 PM François REMY <
> francois.remy@outlook.com> wrote:
> >> >>>>>
> >> >>>>> At the risk of pointing out the obvious:
> >> >>>>>
> >> >>>>>
> >> >>>>>
> >> >>>>> ```js
> >> >>>>>
> >> >>>>> const privkey = Symbol();
> >> >>>>>
> >> >>>>> const stores = new WeakMap();
> >> >>>>>
> >> >>>>>
> >> >>>>>
> >> >>>>> class A {
> >> >>>>>
> >> >>>>>   [privkey] = {};
> >> >>>>>
> >> >>>>>   constructor() {
> >> >>>>>
> >> >>>>> const priv = {};
> >> >>>>>
> >> 

Re: Why does a JavaScript class getter for a private field fail using a Proxy?

2020-07-15 Thread Jordan Harband
So can:
```jsx
const o = { foo() { if (o.foo !== this) { throw 'detected'; } } };
o.foo(); // works
new Proxy(o, {}).foo(); // throws
```

(as would a class that used a closed-over WeakMap for each "private field")

Private fields do not introduce any new hazards here.

On Tue, Jul 14, 2020 at 8:18 PM #!/JoePea  wrote:

> >  private members (safely) allow classes with internal slots.
>
> I'd say that they aren't safe, if they can break 3rd-party code on the
> external public side.
>
> #!/JoePea
>
> On Sun, Jul 12, 2020 at 3:09 PM Michael Theriot
>  wrote:
> >
> > I assume OP wants to use proxies and private members together. They are
> not designed to be compatible.
> >
> > Proxies and private members are a UX goal primarily for developers.
> Proxies easily allow observation of another object or creation of exotic
> objects (e.g. Array), and private members (safely) allow classes with
> internal slots. Since they cannot be used together the issue exists, and
> the hack circumvents this by reimplementing private in a way that does not
> require private fields.
> >
> > On Sun, Jul 12, 2020 at 4:45 PM kai zhu  wrote:
> >>
> >> as product-developer, can i ask what ux-objective you ultimately want
> achieved?
> >>
> >> ```js
> >> const sub = new Sub()
> >>
> >> // i'm a noob on proxies. what is this thing (with
> proxied-private-fields) ultimately used for?
> >> const proxy = new Proxy(sub, ...)
> >> ```
> >>
> >> On Sun, Jul 12, 2020 at 4:34 PM Michael Theriot <
> michael.lee.ther...@gmail.com> wrote:
> >>>
> >>> This does require you to have both the key and the weakmap though, so
> it actually does succeed in hiding the data so long as the weakmap is out
> of scope. I guess the issue I can foresee is that the key could be modified
> after the object is created.
> >>>
> >>> e.g.
> >>> ```js
> >>> var a = new A();
> >>> var key = Object.getOwnPropertySymbols(a)[0];
> >>> delete a[key];
> >>> a.hidden; // throws
> >>> ```
> >>>
> >>> That itself can be guarded by just making the key undeletable. So, I
> guess this solution could work depending what your goals are?
> >>>
> >>> On Sun, Jul 12, 2020 at 4:21 PM Michael Theriot <
> michael.lee.ther...@gmail.com> wrote:
> 
>  It nearly works, but the issue is that the key will be leaked by
> `Object.getOwnPropertySymbols(new A())`, so it's not truly private.
> 
>  There have been ideas proposing "private symbols" but I am not
> familiar with their issues, and I would guess with Class Fields they are
> unlikely to materialize anyway.
> 
>  On Sun, Jul 12, 2020 at 2:19 PM François REMY <
> francois.remy@outlook.com> wrote:
> >
> > At the risk of pointing out the obvious:
> >
> >
> >
> > ```js
> >
> > const privkey = Symbol();
> >
> > const stores = new WeakMap();
> >
> >
> >
> > class A {
> >
> >   [privkey] = {};
> >
> >   constructor() {
> >
> > const priv = {};
> >
> > priv.hidden = Math.random();
> >
> > stores.set(this[privkey], priv);
> >
> >   }
> >
> >
> >
> >   get hidden() {
> >
> > const priv = stores.get(this[privkey]);
> >
> > return priv.hidden;
> >
> >   }
> >
> > }
> >
> >
> >
> > var as = [
> >
> > new A(),
> >
> > new Proxy(new A(),{}),
> >
> > new Proxy(new A(),{}),
> >
> > ];
> >
> > console.log(as.map(a=>a.hidden));
> >
> > ```
> >
> >
> >
> >
> >
> >
> >
> > From: Michael Theriot
> > Sent: Sunday, July 12, 2020 20:59
> > To: Michael Haufe
> > Cc: es-discuss@mozilla.org
> > Subject: Re: Why does a JavaScript class getter for a private field
> fail using a Proxy?
> >
> >
> >
> > I experienced this issue prior to this proposal, using weakmaps for
> private access.
> >
> >
> >
> > e.g.
> >
> > ```js
> >
> > const stores = new WeakMap();
> >
> > class A {
> >   constructor() {
> > const priv = {};
> > priv.hidden = 0;
> > stores.set(this, priv);
> >   }
> >
> >   get hidden() {
> > const priv = stores.get(this);
> > return priv.hidden;
> >   }
> > }
> >
> > const a = new A();
> > console.log(a.hidden); // 0
> >
> > const p = new Proxy(a, {});
> > console.log(p.hidden); // throws!
> >
> > ```
> >
> >
> >
> > I found a workaround:
> >
> >
> >
> > ```js
> > const stores = new WeakMap();
> >
> > class A {
> >   constructor() {
> > const priv = {};
> > priv.hidden = 0;
> > stores.set(this, priv);
> >
> > const p = new Proxy(this, {});
> > stores.set(p, priv); // set proxy to map to the same private
> store
> >
> > return p;
> >   }
> >
> >  

Re: Allow for async/await to use global.Promise and not builtin Promise

2020-05-06 Thread Jordan Harband
You already do have that right; you can use any Promise implementation you
choose, or none at all. You do *not*, however, typically have the "right"
to alter what syntax does, and `async`/`await` explicitly chose that
philosophy.

On Tue, May 5, 2020 at 11:37 PM medikoo 
wrote:

> Jordan Harband wrote
> > Anything "more efficient" would likely not be spec compliant
>
> Promises (also those specified in ES) are quite opinionated, and I believe
> we should have right to practice our own opinions in our own apps.
>
> On these grounds thenable objects (so not necessarily promise instances)
> are
> supported, and work seamlessly in promise chains.
>
> Unfortunately async/await breaks that support, it'll be great if we can
> recover from that.
>
>
>
> --
> Sent from:
> http://mozilla.6506.n7.nabble.com/Mozilla-ECMAScript-4-discussion-f89340.html
> ___
> 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: Allow for async/await to use global.Promise and not builtin Promise

2020-05-06 Thread Jordan Harband
Anything "more efficient" would likely not be spec compliant, which would
break code relying on those guarantees. Overriding any builtin is a bad
practice for well over a decade, and I'm not sure why doing so would be
desirable. "Fast" doesn't matter if correctness is not assured.

On Tue, May 5, 2020 at 11:25 PM medikoo 
wrote:

> +1
>
> This would allow injecting more efficient promise alternatives without
> transpilation of async/await
>
>
>
> --
> Sent from:
> http://mozilla.6506.n7.nabble.com/Mozilla-ECMAScript-4-discussion-f89340.html
> ___
> 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: Object.safeAssign

2020-05-01 Thread Jordan Harband
I'm confused about that as well; there were a spate of CVEs about it a year
or two ago (2 or 3 of my libraries were "affected"), but just like the
minimist/mkdirp ones, they were only actually vulnerabilities for a
minority of the use cases. Have there been any recent vulnerabilities
you're aware of?

On Fri, May 1, 2020 at 9:22 AM Bob Myers  wrote:

> Can you explain or support your assertion of "increased prevalence"?
>
> On Fri, May 1, 2020, 05:51 Mike Sherov  wrote:
>
>> Given the increased prevalence of prototype pollution vulnerabilities in
>> many popular javascript libraries, is it time to reconsider the fact that
>> Object.assign allows for prototype pollution by default?
>>
>> I see two options:
>> 1. Change Object.assign to disallow PP by default. Look at real world
>> usages and see what would break if prototype pollution was disabled? Almost
>> certainly this is not a viable option, but wanted to raise it here just in
>> case there was appetite to do so.
>> 2. Introduce something like Object.safeAssign (bikeshedding aside), that
>> is the same as Object.assign except is safe from prototype pollution.
>>
>> The reason I think this is important is that the common advice of
>> freezing Object.prototype is something only the end user can do, and not
>> something a library can do.
>>
>> Yes, a library can also know to do its own PP fixes, but having a reified
>> way to avoid PP allows us to have a secure-by-default method in the
>> language.
>>
>> Thoughts?
>>
>> Mike Sherov
>> ___
>> 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: Why can't the left-hand side of an assignment expression use optional chaining?

2020-04-30 Thread Jordan Harband
See https://github.com/tc39/proposal-optional-chaining/issues/18

On Thu, Apr 30, 2020 at 1:08 PM #!/JoePea  wrote:

> I was hoping to avoid things like
>
> ```js
> const baz = this.foo?.bar?.baz
> if (baz) baz.lorem = 123
> ```
>
> #!/JoePea
>
> On Thu, Apr 30, 2020 at 1:04 PM #!/JoePea  wrote:
> >
> > This is perfectly fine:
> >
> > ```js
> > this.foo?.bar?.setBaz(123)
> > ```
> >
> > but this is not:
> >
> > ```js
> > this.foo?.bar?.baz = 123
> > ```
> >
> > Why is that not allowed, but function calls are?
> >
> > I find myself often wanting to do assignments like that. When I am
> > auto-completing things in VS Code (TypeScript), it automatically and
> > awesomely inserts the `?` characters, only to fail once I write the
> > assignment part.
> >
> > #!/JoePea
> ___
> 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: Promise.allSettled() - why string?

2020-04-17 Thread Jordan Harband
The iteration protocol has a boolean data property `.done` - I don't know
if anyone ever suggested some kind of `isDone()` method for that, and I
think the iteration protocol sets a precedent of the "tag" on the object
being a primitive.

On Fri, Apr 17, 2020 at 7:25 PM Felipe Gasper 
wrote:

> Hello,
>
> If it’s not too awkward of a question to ask: were object methods
> rather than string comparison considered for Promise.allSettled()?
>
> For example, if I write this:
>
> -
> Promise.allSettled(promises).then( results => {
> results.forEach( r => {
> if (r.status === "rejectd") {
> // Failure …
> }
> else {
> // Success!
> }
> } );
> } );
> -
>
> … the code won’t complain about the typo but instead just “do the wrong
> thing”.
>
> But, if the way to parse allSettled()’s resolution were object methods
> instead, it could be this:
>
> -
> Promise.allSettled(promises).then( results => {
> results.forEach( r => {
> if (r.isRejectd()) {
> // Failure …
> }
> else {
> // Success!
> }
> } );
> } );
> -
>
> … which will usefully cause an exception/rejection that pinpoints the
> problem in my code.
>
> Was this pattern perhaps considered and rejected? Or is there some
> liability to the object methods relative to the string comparison that I’m
> not seeing? If so, what was/is the rationale there?
>
> Thank you for your time!
>
> cheers,
> -Felipe Gasper
> ___
> 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: Conditional assign operator

2020-04-13 Thread Jordan Harband
Are you familiar with https://github.com/tc39/proposal-logical-assignment/ ?

On Mon, Apr 13, 2020 at 2:17 AM Sultan  wrote:

> The following would assign to the address foo in obj if and only if it has
> not already been assigned.
>
> var obj = {}
> var foo = Math.random()
> obj[foo] ?= 1
>
> The same can be said for:
>
> var undef
> undef ?= 1
>
> Which could both be transpired to
>
> type obj[foo] === 'undefined' && obj[foo] = 1
>
> or
>
> type a === 'undefined' && undef = 1
>
> respectively.
> ___
> 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: Promises: unhandled rejections and finally()

2020-03-28 Thread Jordan Harband
It does pass through the fulfillment status - but it does that by adding
both an onFulfilled and an onRejected handler, so it does affect the
"unhandled rejection" hook.

On Sat, Mar 28, 2020 at 7:23 PM Felipe Gasper 
wrote:

> Hi Logan,
>
> Thank you .. that makes sense. I’m not sure why now but I had in mind that
> finally() creates a “passthrough” promise that doesn’t affect its parent
> promise’s resolved/rejected status.
>
> Cheers,
> -Felipe
>
> On Mar 28, 2020, at 21:40, Logan Smyth  wrote:
>
> 
> > Could someone point me to something that would help me to understand the
> logic here? It looks like the first finally() is getting a “free pass”
> while only the 2nd and subsequent ones trigger their own
> unhandled-rejection warnings.
>
> I think the best place to start in understanding this would be to step
> back and make sure you understand what it is that triggers these errors.
> Node triggers these errors when a promise object has been rejected but has
> no handlers to do respond to the rejection. I forget exactly what point
> Node checks for handlers these days, if that point is at the end of the job
> execution or on GC of promises now or what but that's not important for
> this case.
>
> Let's look at your example. I'm also simplifying it to
> ```
> var p = Promise.reject(789);
> var one = p.finally(() => {});
> var two = p.finally(() => {});
> var three = p.finally(() => {});
> ```
>
> 1)
> ```
> var p = Promise.reject(789);
> ```
> There is only one promise here, `p`, and it has no handlers ever attached
> to it so there is nothing to handle the rejection error, hence the single
> uncaught rejection error.
>
> 2)
> ```
> var p = Promise.reject(789);
> var one = p.finally(() => {});
> ```
> There are 2 promises here, `p`, which has one handler (the `finally` that
> will take the rejection of `p` and in turn reject `one`) and `one`, which
> has no handlers attached, so you again get a single uncaught rejection. It
> as not that the first "finally" gets a "free pass", it is that rejections
> from `p` are no longer uncaught, but you have added a new promise that is
> uncaught, so the overall number of uncaught rejections does not change.
>
> 3)
> ```
> var p = Promise.reject(789);
> var one = p.finally(() => {});
> var two = p.finally(() => {});
> ```
> Hopefully you can see where this is going. `p` now has 2 handlers attached
> so its rejection isn't uncaught, but now both `one` and `two` have no
> handlers, so _both_ will trigger an uncaught rejection error.
>
> 4)
> ```
> var p = Promise.reject(789);
> var one = p.finally(() => {});
> var two = p.finally(() => {});
> var three = p.finally(() => {});
> ```
> And finally now we have `one`, `two` and `three` all with no handlers
> attached, so you will get three uncaught rejection errors.
>
> Hope that helps!
>
>
> On Sun, Mar 29, 2020 at 9:03 AM Felipe Gasper 
> wrote:
>
>> Hello,
>>
>> In node 12 as well as the latest Chrome and FF (all on macOS) I see the
>> following:
>>
>> -
>> var y,n; var p = new Promise( (yy,nn) => { y=yy; n=nn } ); n(789);
>> ==> produces 1 unhandled-rejection warning
>>
>> var y,n; var p = new Promise( (yy,nn) => { y=yy; n=nn } ); p.finally( ()
>> => {} ); n(789);
>> ==> produces 1 unhandled-rejection warning
>>
>> var y,n; var p = new Promise( (yy,nn) => { y=yy; n=nn } ); p.finally( ()
>> => {} ); p.finally( () => {} ); n(789);
>> ==> produces 2 unhandled-rejection warnings
>>
>> var y,n; var p = new Promise( (yy,nn) => { y=yy; n=nn } ); p.finally( ()
>> => {} ); p.finally( () => {} ); p.finally( () => {} ); n(789);
>> ==> produces 3 unhandled-rejection warnings
>>
>> -
>>
>> Could someone point me to something that would help me to understand the
>> logic here? It looks like the first finally() is getting a “free pass”
>> while only the 2nd and subsequent ones trigger their own
>> unhandled-rejection warnings.
>>
>> Thank you!
>>
>> cheers,
>> -Felipe Gasper
>> ___
>> 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: syntax for case ranges

2020-02-19 Thread Jordan Harband
@kdex (sorry i missed this; your message was in my spam folder) if you find
a way that Annex E is non-exhaustive, please file an issue on the spec - I
would like it to be exhaustive.

On Mon, Feb 3, 2020 at 11:16 AM Naveen Chawla  wrote:

> Thanks! Although I think it is a value judgement about how much risk is
> worth how much reward, and which reward, so I wouldn't classify it as
> necessarily a complete set of criteria yet, but it is certainly in the
> right direction. And very interesting to me. Thank you.
>
> On Tue, 4 Feb 2020 at 00:40, Mark S. Miller  wrote:
>
>> While correct, each case asked the browser makers to make a risky and
>> costly bet. When the risk was low and the payoff high, they've been great
>> at doing so. This one does not fall into the viable risk vs reward
>> territory.
>>
>>
>> On Mon, Feb 3, 2020 at 7:58 AM kdex  wrote:
>>
>>> Yes, there have been numerous backwards-incompatible changes to the
>>> language
>>> over the years.
>>>
>>> You can find a list of them in section E of the ECMAScript language
>>> standard.
>>> IIRC, that list is non-exhaustive.
>>>
>>> On Monday, February 3, 2020 6:35:12 PM CET Naveen Chawla wrote:
>>> > Thank you Claude! I did miss the point.
>>> >
>>> > Have there ever been "BC" breaks introduced into the language before?
>>> If
>>> > so, is there a sustainable standard for an "acceptable" one?
>>> >
>>> > On Mon, 3 Feb 2020 at 22:47, Claude Pache 
>>> wrote:
>>> > > Try typing `3 < 2 < 1` in the web console of your favourite browser,
>>> and
>>> > > see the result: it will evaluate to `true`. No, your browser isn’t
>>> buggy,
>>> > > it is just following blindly the semantics of `<`.
>>> > >
>>> > > Modifying the meaning of `3 < 2 < 1` in order to make it evaluating
>>> to
>>> > > `false` is a BC break. Is it acceptable? Dunno.
>>> > >
>>> > > —Claude
>>> > >
>>> > > Le 3 févr. 2020 à 15:23, Naveen Chawla  a
>>> écrit :
>>> > >
>>> > > Hi!
>>> > >
>>> > > I didn't understand your reply.
>>> > >
>>> > > I think currently it would raise an error, because 1 < 2 < 3 is
>>> currently
>>> > > saying (probably) true < 3.
>>> > >
>>> > > But a "new" syntax could possibly parse that as a "chain" of
>>> comparisons.
>>> > >
>>> > > Would this be acceptable to introduce into JavaScript (just curious)?
>>> > >
>>> > > I've probably missed your point entirely, because I saw a short
>>> message "3
>>> > > < 2 < 1 //true", and I've assumed you meant it in reverse.
>>> > >
>>> > > On Sat, 1 Feb 2020 at 23:12, Mark S. Miller 
>>> wrote:
>>> > >> 3 < 2 < 1;  // true
>>> > >>
>>> > >>
>>> > >> On Sat, Feb 1, 2020 at 3:03 AM Naveen Chawla >> >
>>> > >>
>>> > >> wrote:
>>> > >>> Certain languages allow the expression 0>> this
>>> > >>> would be syntactically possible in JavaScript? Of course this
>>> would only
>>> > >>> apply for "if"/"while" statements.
>>> > >>>
>>> > >>> On Fri, 31 Jan 2020 at 22:41, Isiah Meadows <
>>> cont...@isiahmeadows.com>
>>> > >>>
>>> > >>> wrote:
>>> >  Still better to discuss it there - it's highly related to your
>>> >  suggestion. And I'm pretty sure an issue already exists related to
>>> >  that.
>>> > 
>>> >  On Fri, Jan 31, 2020 at 09:06 Sultan  wrote:
>>> > > The pattern matching proposal does not handles the mentioned
>>> case:
>>> > >
>>> > > switch(type) { case 0...5: } being the equivalent of
>>> switch(type) {
>>> > > case 0: case 1: case 2: case 3: case 4: case 5: }
>>> > >
>>> > > On Fri, Jan 31, 2020 at 7:36 PM Bruno Macabeus <
>>> > >
>>> > > bruno.macab...@gmail.com> wrote:
>>> > >> I agree with Oriol.
>>> > >> We already have the proposal pattern matching, that has a very
>>> > >> similar effect.
>>> > >> I think that is better to improve pattern matching proposal in
>>> order
>>> > >> to be able to match using ranges (or at least check if it's
>>> good to
>>> > >> do)
>>> > >> instead of create a new proposal.
>>> > >>
>>> > >> On Fri, 31 Jan 2020 at 14:08, Oriol _ <
>>> oriol-bugzi...@hotmail.com>
>>> > >>
>>> > >> wrote:
>>> > >>> This sounds like
>>> https://github.com/tc39/proposal-pattern-matching
>>> > >>>
>>> > >>> El 31/1/20 a les 10:57, Sultan ha escrit:
>>> > >>>
>>> > >>> For example, the following:
>>> > >>>
>>> > >>> switch (value) {
>>> > >>>
>>> > >>> case 0...9: break
>>> > >>> case 'a'...'z': break
>>> > >>>
>>> > >>> }
>>> > >>>
>>> > >>>
>>> > >>> ___
>>> > >>> es-discuss mailing
>>> > >>> listes-discuss@mozilla.orghttps://
>>> mail.mozilla.org/listinfo/es-disc
>>> > >>> uss
>>> > >>>
>>> > >>>
>>> > >>> ___
>>> > >>> es-discuss mailing list
>>> > >>> es-discuss@mozilla.org
>>> > >>> https://mail.mozilla.org/listinfo/es-discuss
>>> > >>
>>> > >> ___
>>> > >> 

Re: [Proposal] Optional spreading

2020-02-15 Thread Jordan Harband
No, it wouldn't - see https://github.com/tc39/ecma262/pull/1069.

On Sat, Feb 15, 2020 at 11:54 AM Bob Myers  wrote:

> Wouldn't simply making array spreading ignore nullish values be backward
> compatible?
> Unless one imagines that people are depending on this being an error
> somehow.
>
> On Sat, Feb 15, 2020 at 10:05 AM Jordan Harband  wrote:
>
>> Since object spread already ignores nullish values, a syntax change would
>> only be needed for array spread. Then, the two kinds of spread would
>> support different syntactic features, which seems inconsistent.
>>
>> On Sat, Feb 15, 2020 at 7:56 AM Beknar Askarov 
>> wrote:
>>
>>> Thank you, everyone, for feedback. Sorry for not getting back for a
>>> while. I had some time to think and concluded that nullish noop in
>>> spreading is a good feature to be added to the language without
>>> complicating it too much.
>>> So please take a look at the explainer
>>> <https://gist.github.com/askbeka/8bb17508ec250a789ea9bff683a50e38> and
>>> lets discuss in es-discourse proposal
>>> <https://es.discourse.group/t/optional-spreading-proposal/224>, if you
>>> have further feedback, please share
>>>
>>> On Fri, Aug 23, 2019 at 7:18 PM Herby Vojčík  wrote:
>>>
>>>> On 23. 8. 2019 16:24, Beknar Askarov wrote:
>>>> > @Scott Rudiger After thinking more about it.
>>>> > I would not like to conflict with semantics of optional chaining and
>>>> > null coalescing operator.
>>>> > So in order to not confuse people, maybe introduce two types of
>>>> optional
>>>> > spread operators
>>>> >
>>>> >
>>>> > 1. `?...` - Do not spread if nullish. Note nullish. Else try to
>>>> spread.
>>>> > Signature Array: [?...(nullish | Iterable)];
>>>> > Signature Object: {?...(nullish | object)};
>>>> >
>>>> > 2. `!...` - Do not spread if false. Note FALSE not falsy. Else try to
>>>> > spread.
>>>>
>>>> I read
>>>>
>>>>!...foo
>>>>
>>>> as
>>>>
>>>>!(...foo)
>>>>
>>>> that is, logical not. I'd tip it already works that way. In which case
>>>> no go, break compat.
>>>>
>>>> Herby
>>>>
>>>> > Signature Array: [!...(false | Iterable)];
>>>> > Signature Object: {!...(false | object)};
>>>> >
>>>> > I think this can be an option to avoid consfusion
>>>>
>>>> Or add a new one. :-(
>>>>
>>> ___
>> 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] Optional spreading

2020-02-15 Thread Jordan Harband
Since object spread already ignores nullish values, a syntax change would
only be needed for array spread. Then, the two kinds of spread would
support different syntactic features, which seems inconsistent.

On Sat, Feb 15, 2020 at 7:56 AM Beknar Askarov 
wrote:

> Thank you, everyone, for feedback. Sorry for not getting back for a while.
> I had some time to think and concluded that nullish noop in spreading is a
> good feature to be added to the language without complicating it too much.
> So please take a look at the explainer
>  and
> lets discuss in es-discourse proposal
> , if you
> have further feedback, please share
>
> On Fri, Aug 23, 2019 at 7:18 PM Herby Vojčík  wrote:
>
>> On 23. 8. 2019 16:24, Beknar Askarov wrote:
>> > @Scott Rudiger After thinking more about it.
>> > I would not like to conflict with semantics of optional chaining and
>> > null coalescing operator.
>> > So in order to not confuse people, maybe introduce two types of
>> optional
>> > spread operators
>> >
>> >
>> > 1. `?...` - Do not spread if nullish. Note nullish. Else try to spread.
>> > Signature Array: [?...(nullish | Iterable)];
>> > Signature Object: {?...(nullish | object)};
>> >
>> > 2. `!...` - Do not spread if false. Note FALSE not falsy. Else try to
>> > spread.
>>
>> I read
>>
>>!...foo
>>
>> as
>>
>>!(...foo)
>>
>> that is, logical not. I'd tip it already works that way. In which case
>> no go, break compat.
>>
>> Herby
>>
>> > Signature Array: [!...(false | Iterable)];
>> > Signature Object: {!...(false | object)};
>> >
>> > I think this can be an option to avoid consfusion
>>
>> Or add a new one. :-(
>>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Double wildcard "re-exports"... off-limits forever?

2020-02-13 Thread Jordan Harband
Wouldn't the solution be, don't use `import * as`, but instead, explicitly
import and re-export what you want?

On Thu, Feb 13, 2020 at 8:02 PM Ben Wiley  wrote:

> Apologies if this has already been talked about at length at some point. I
> was unable to find much in the way of relevant discussions.
>
> I found a compelling use case for something which seems to be off-limits
> in the JavaScript language, that is wildcard re-exporting where the same
> export name appears in multiple of the export-forwarded imports.
>
> e.g.
> ```
> // a.js
> export const a = 1;
>
> // b.js
> export const b = 2;
>
> // c.js
> export * from './a.js';
> export * from './b.js';
> ```
>
> The ideal use case would be shipping an "override library" that ships all
> the default exports of an upstream library, except it replaces some of them
> with its own overrides. The object-oriented folks might think of it like a
> derived class. This can of course be accomplished alternatively by
> exporting an object which merges all the named exports from each library,
> but the major disadvantage I see is that we would no longer have access to
> tree-shaking, since that object contains *all* of the exports. For a really
> big upstream library, that could make a large difference in kilobytes
> shipped to the browser. So preserving the named exports is desirable.
>
> The protections against double-re-exporting vary. In Chrome and Firefox,
> there are no runtime errors but the duplicated exports will be stripped and
> unavailable. If you try Babel or Typescript, the compiler will throw an
> error.
>
> I understand *not* protecting against this could lead to very weird
> debugging situations for unwitting users who didn't realize their wanted
> import was being overwritten, however I'd love if there were a way to say
> "I know what I'm doing, don't stop me." As far as I can immediately tell
> nothing about ES imports would prevent the compiler from being able to know
> the order of precedence for overridden exports, and the "ambiguity" would
> be mainly from the perspective of an unwitting user. I recognize that
> import trees may be processed in parallel, however since code execution is
> delayed until the import tree is complete I would think we could resolve
> any ambiguities by that time. However it's possible I missed something -
> maybe there's a case related to circular imports which ruins this?
>
> Anyway, I wrote up some more detailed thoughts on this problem, and some
> demo code, here:
> https://github.com/benwiley4000/wildcard-export-override-example
>
> Ben
> ___
> 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: Any chance for an `Object.assignProperties` ?

2020-02-13 Thread Jordan Harband
It seems like it’s the exact implementation you want, just for 1 object
instead of N.

Object.assign was added because versions of it were all over the web, used
very frequently. How frequent is the pattern where people want to copy
descriptors, such that it would deserve reification in the language?

On Thu, Feb 13, 2020 at 10:23 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> That has nothing to do with this, right?
>
> ```js
> const {assign, defineProperties, getOwnPropertyDescriptors} = Object;
> const assignProperties = (base, ...mixins) => defineProperties(
>   base,
>   mixins.reduce(
> (descriptors, mixin) => assign(
>   descriptors,
>   getOwnPropertyDescriptors(mixin)
> ),
> {}
>   )
> );
> ```
>
> On Thu, Feb 13, 2020 at 6:51 PM Jordan Harband  wrote:
>
>> `Object.defineProperties(target,
>> Object.getOwnPropertyDescriptors(source))`?
>>
>> On Thu, Feb 13, 2020 at 2:24 AM Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> Both `Object.assign` and `{...extend}` suffer a tiny gotcha: properties
>>> are never assigned, neither retrieved, as accessors, with side-effects too.
>>>
>>> Example:
>>> ```js
>>> const Counter = {
>>>   _count: 0,
>>>   get count() {
>>> return this._count++;
>>>   }
>>> };
>>>
>>> const incr1 = Object.assign({}, Counter);
>>> const incr2 = {...Counter};
>>>
>>> console.log(
>>>   incr1.count,// 0
>>>   incr2.count,// 1
>>>   Counter._count  // 2
>>> );
>>>
>>> // functionality also compromised
>>> console.log(incr1.count === incr1.count);
>>> ```
>>>
>>> Not only most of the time this is unexpected, but there's literally no
>>> way to pass along accessors with a similar `Object.assign` ease, even if
>>> that's what most developers would expect (at least up to the first time
>>> they encounter above issue).
>>>
>>> How about we introduce `Object.assignProperties` instead?
>>>
>>> A polyfill example:
>>>
>>> ```js
>>> const {assign, defineProperties, getOwnPropertyDescriptors} = Object;
>>> const assignProperties = (base, ...mixins) => defineProperties(
>>>   base,
>>>   mixins.reduce(
>>> (descriptors, mixin) => assign(
>>>   descriptors,
>>>   getOwnPropertyDescriptors(mixin)
>>> ),
>>> {}
>>>   )
>>> );
>>> ```
>>>
>>> We can now use objects and mixins without side-effecting sources used to
>>> extend, and preserving accessors in the process.
>>>
>>> ```js
>>> const Counter = {
>>>   _count: 0,
>>>   get count() {
>>> return this._count++;
>>>   }
>>> };
>>>
>>> const incr1 = Object.assignProperties({}, Counter);
>>> const incr2 = Object.assignProperties({}, Counter);
>>>
>>> console.log(
>>>   incr1.count,// 0
>>>   incr2.count,// 0
>>>   Counter._count  // 0
>>> );
>>>
>>> // always false: preserved functionality
>>> console.log(incr1.count === incr1.count);
>>> ```
>>>
>>> Thoughts ?
>>> ___
>>> 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: Any chance for an `Object.assignProperties` ?

2020-02-13 Thread Jordan Harband
`Object.defineProperties(target, Object.getOwnPropertyDescriptors(source))`?

On Thu, Feb 13, 2020 at 2:24 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> Both `Object.assign` and `{...extend}` suffer a tiny gotcha: properties
> are never assigned, neither retrieved, as accessors, with side-effects too.
>
> Example:
> ```js
> const Counter = {
>   _count: 0,
>   get count() {
> return this._count++;
>   }
> };
>
> const incr1 = Object.assign({}, Counter);
> const incr2 = {...Counter};
>
> console.log(
>   incr1.count,// 0
>   incr2.count,// 1
>   Counter._count  // 2
> );
>
> // functionality also compromised
> console.log(incr1.count === incr1.count);
> ```
>
> Not only most of the time this is unexpected, but there's literally no way
> to pass along accessors with a similar `Object.assign` ease, even if that's
> what most developers would expect (at least up to the first time they
> encounter above issue).
>
> How about we introduce `Object.assignProperties` instead?
>
> A polyfill example:
>
> ```js
> const {assign, defineProperties, getOwnPropertyDescriptors} = Object;
> const assignProperties = (base, ...mixins) => defineProperties(
>   base,
>   mixins.reduce(
> (descriptors, mixin) => assign(
>   descriptors,
>   getOwnPropertyDescriptors(mixin)
> ),
> {}
>   )
> );
> ```
>
> We can now use objects and mixins without side-effecting sources used to
> extend, and preserving accessors in the process.
>
> ```js
> const Counter = {
>   _count: 0,
>   get count() {
> return this._count++;
>   }
> };
>
> const incr1 = Object.assignProperties({}, Counter);
> const incr2 = Object.assignProperties({}, Counter);
>
> console.log(
>   incr1.count,// 0
>   incr2.count,// 0
>   Counter._count  // 0
> );
>
> // always false: preserved functionality
> console.log(incr1.count === incr1.count);
> ```
>
> Thoughts ?
> ___
> 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: Yet another attempt at typed JS data

2020-02-11 Thread Jordan Harband
No, `Array.from` never produces a holey array whatsoever; only ever a dense
array.

On Sun, Feb 9, 2020 at 11:08 PM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> Unfortunately, `Array.from({ length: 4 }, () => whatever)` produces a
> holey array, so that the `.repeat(...)` idea, if capable of packing
> elements in a better way, wouldn't be so terrible, as simplification.
>
> Although, the intent of this proposal was to also grant "shapes" or
> kindness of each entry, same way typed Arrays do, but maybe that would
> require some better primitive, as in `const Shape =
> Object.defineShape(...)` and `Object.createShape(Shape)` or similar.
>
> On Sun, Feb 9, 2020 at 10:01 PM Jordan Harband  wrote:
>
>> That already exists - `Array.from({ length: 4 }, () => whatever)` - I
>> assume that the hope is to have an array where it is *impossible* for it to
>> have the wrong "kind" of data, and a userland factory function wouldn't
>> provide that.
>>
>> On Sun, Feb 9, 2020 at 10:39 AM kai zhu  wrote:
>>
>>> > It's a bit of a mess to create an Array that is not holed and gets
>>> best optimizations [1], and this proposal would like to address that exact
>>> case.
>>>
>>> could the performance issue be resolved more easily with a simple
>>> static-function `Array.repeat(, )`?
>>>
>>> ```js
>>> let structuredList;
>>> structuredList = Array.repeat(4, function (ii) {
>>> return {
>>> index: 2 * ii + 1,
>>> tags: []
>>> });
>>> /*
>>> structuredList = [
>>> { index: 1, tags: [] },
>>> { index: 3, tags: [] },
>>> { index: 5, tags: [] },
>>> { index: 7, tags: [] }
>>> ];
>>>  */
>>> ```
>>>
>>> the only time i can practically enforce the shape of a "StructuredArray"
>>> is during element-insertion,
>>> and a userland insertion/creation function would be just as effective as
>>> a StructuredArray constructor.
>>>
>>> enforcing shapes during element deletions and updates are going to be
>>> hard
>>> and likely just as confusing with StructuredArray as they are with
>>> regular Array.
>>>
>>> also note that most javascript arrays need to be easily JSON-serialized
>>> for message-passing
>>> over-the-wire (commonly http) to external systems.
>>>
>>> -kai
>>>
>>> On Sat, Feb 8, 2020 at 3:46 AM Andrea Giammarchi <
>>> andrea.giammar...@gmail.com> wrote:
>>>
>>>> > having to retroactively add checks like...
>>>>
>>>> we already have typed arrays in JS so I don't think this would be any
>>>> different
>>>>
>>>> > I _think_ that moderns virtual machines already did these
>>>> optimisations despite there isn't a TypedArray like that.
>>>>
>>>> It's a bit of a mess to create an Array that is not holed and gets best
>>>> optimizations [1], and this proposal would like to address that exact case.
>>>>
>>>> [1] https://v8.dev/blog/elements-kinds
>>>>
>>>>
>>>>
>>>>
>>>> ___
>>>> 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: Yet another attempt at typed JS data

2020-02-09 Thread Jordan Harband
That already exists - `Array.from({ length: 4 }, () => whatever)` - I
assume that the hope is to have an array where it is *impossible* for it to
have the wrong "kind" of data, and a userland factory function wouldn't
provide that.

On Sun, Feb 9, 2020 at 10:39 AM kai zhu  wrote:

> > It's a bit of a mess to create an Array that is not holed and gets best
> optimizations [1], and this proposal would like to address that exact case.
>
> could the performance issue be resolved more easily with a simple
> static-function `Array.repeat(, )`?
>
> ```js
> let structuredList;
> structuredList = Array.repeat(4, function (ii) {
> return {
> index: 2 * ii + 1,
> tags: []
> });
> /*
> structuredList = [
> { index: 1, tags: [] },
> { index: 3, tags: [] },
> { index: 5, tags: [] },
> { index: 7, tags: [] }
> ];
>  */
> ```
>
> the only time i can practically enforce the shape of a "StructuredArray"
> is during element-insertion,
> and a userland insertion/creation function would be just as effective as a
> StructuredArray constructor.
>
> enforcing shapes during element deletions and updates are going to be hard
> and likely just as confusing with StructuredArray as they are with regular
> Array.
>
> also note that most javascript arrays need to be easily JSON-serialized
> for message-passing
> over-the-wire (commonly http) to external systems.
>
> -kai
>
> On Sat, Feb 8, 2020 at 3:46 AM Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> > having to retroactively add checks like...
>>
>> we already have typed arrays in JS so I don't think this would be any
>> different
>>
>> > I _think_ that moderns virtual machines already did these optimisations
>> despite there isn't a TypedArray like that.
>>
>> It's a bit of a mess to create an Array that is not holed and gets best
>> optimizations [1], and this proposal would like to address that exact case.
>>
>> [1] https://v8.dev/blog/elements-kinds
>>
>>
>>
>>
>> ___
>> 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: Array.prototype.toggle

2020-02-07 Thread Jordan Harband
I would not be interested in adding any more mutating methods to
Array.prototype, ever. I'd suggest using `.filter` for this.

On Fri, Feb 7, 2020 at 5:29 AM manuelbarzi  wrote:

> many things that already provide array could be polyfilled, and probably
> many were polyfills before. it's not about to discuss that, but the chance
> to integrate it in array as a useful feature if most agree it could be so.
>
> On Fri, Feb 7, 2020 at 3:34 PM Augusto Moura 
> wrote:
>
>> To me this is more a use case for using Set instead of arrays, the
>> support is already great and it can be polyfilled. Set is the right data
>> structure to verify if some element is or is not in a collection
>>
>> Em sex., 7 de fev. de 2020 às 08:49, manuelbarzi 
>> escreveu:
>>
>>> just a proposal to provide this functionality into array, allowing to
>>> add / remove items in a toggling mechanism shortcut, avoiding the need to
>>> do traversing to locate the indexes and remove them next (i.e. by means of
>>> a polyfill or any other approach).
>>>
>>> ```js
>>> [1, 2, 3, 2, 1].toggle(1) // mutates the original array removing 1,
>>> resulting in [2, 3, 2]
>>> ```
>>> ___
>>> 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Yet another attempt at typed JS data

2020-02-07 Thread Jordan Harband
the "type" in Typed Arrays refers to the bit size in memory; being able to
pass an arbitrary value seems like it would require implementations to
calculate the precise (not just the maximum) memory size a single item
requires.

On Fri, Feb 7, 2020 at 6:33 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> As more and more often devs are shifting into TS, or would like to have
> dynamic typed arrays without a fixed length, and as v8 and likely other
> engines too optimize a lot for same-kind arrays, I wonder what people here
> think about this `TypedArray` rough proposal:
>
> # Signature:
>
> ```js
> new TypedArray(
>   type,   // either a "type" to infer, or a shape, or a Class
>   length  // optional: if defined it's fixed size
> );
> ```
>
>
> ## About the `type`
>
>   * if the inferred type is `object`:
> * if the object is `null`, throw new InvalidType
> * if the object is a literal, or its `__proto__` is either `null` or
> `Object.prototype, enforce own properties and respective types
> * if the object is not literal, fallback to object Class (`/./` is
> `RegExp`, `() => {}` is `Function`, etc)
>   * if the inferred `type` is `function`, fallback to Class
>   * if the inferred `type` is `Class`, ensure each entry is an instance of
> such class, or throw InvalidType
>   * in every other case, make a _typed_ collection of `number`, `string`,
> `boolean`, or `symbol`
>
>
> ## About the `length`
>
>   * if provided, the collection has a fixed, immutable, length, and each
> initial entry a default value
>
>
> # Use Cases:
>
> ```js
> const numbers = new TypedArray(0, 5);
> // creates [0, 0, 0, 0, 0]
> // numbers length is immutable
> // numbers accepts only typeof number
> // out of bound entries throw
>
> let numbers = new TypedArray(0);
> // numbers length is dynamic
> // numbers accepts only typeof number
> // out of bound entries throw
>
> const shapes = new TypedArray({name: '', age: 0}, 3);
> // creates [{name: '', age: 0}, {name: '', age: 0}, {name: '', age: 0}]
> // shapes length is immutable
> // shapes accepts only objects with `name` and `age` and respective types
> // out of bound entries throw
>
> let shapes = new TypedArray({lat: 0, long: 0});
> // shapes length is dynamic
> // shapes accepts only objects with `lat` and `long` and respective types
> // out of bound entries throw
>
> const classes = new TypedArray(HTMLElement, 2);
> // creates [Object.create(HTMLElement.prototype),
> Object.create(HTMLElement.prototype)]
> // classes length is immutable
> // classes accepts only instances of HTMLElement
> // out of bound entries throw
>
> let classes = new TypedArray(HTMLElement);
> // classes length is dynamic
> // classes accepts only instances of HTMLElement
> // out of bound entries throw
>
> // more options
> let strings = new TypedArray('');
> let booleans = new TypedArray(true);
> let functions = new TypedArray(Function);
> let coords = new TypedArray({lat: 0, long: 0});
> ```
>
> Thanks in advance for eventual thoughts on this 
> ___
> 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: `await.all {...}` for parallelism

2019-11-19 Thread Jordan Harband
If we have `await.all`, what about `await.race`, `await.allSettled`,
`await.any`?

On Tue, Nov 19, 2019 at 7:45 PM Jacob Bloom 
wrote:

> To simplify the problem of working with promises in parallel, I
> propose this new syntax:
>
> ```javascript
> async function initialize() {
>   let foo, bar, baz;
>   await.all {
> foo = (await request('foo.json')).data;
> bar = (await request('bar.json')).data;
> baz = (await request('baz.json')).data;
>   }
>   render(foo, bar, baz);
> }
> ```
>
> Each child statement of the curly braces is evaluated in parallel and
> execution resumes when they've all resolved.
>
> **The Problem:** with current syntax, the above function would
> probably look something like this:
>
> ```javascript
> async function initialize() {
>   const [
> { data: foo }, // renaming response.data => foo
> { data: bar },
> { data: baz },
>   ] = await Promise.all([
> request('foo.json'),
> request('bar.json'),
> request('baz.json'),
>   ]);
>   render(foo, bar, baz);
> }
> ```
>
> For this kind of use case, `Promise.all` leads to "parallel lists" of
> promises and their return values, which must be kept in sync. Using
> those values either requires (sometimes deep) destructuring or
> temporary variables.
>
> This structure is also just fundamentally different from working
> serially in async/await and it forces you to reason about the problem
> in a specific way. This doesn't appear to be a conscious decision to
> force good code practices, it's just a limitation that falls naturally
> out of the current syntax. Thus, we have an opportunity to shift some
> of the burden back to the language with this new syntax.
>
> Here's the full proposal:
> https://github.com/mrjacobbloom/proposal-await-all -- let me know what
> you think!
> ___
> 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: Array.prototype.sort( callbackfn [ , thisArg ] )

2019-11-11 Thread Jordan Harband
What's the issue with creating a new function for that case, that accesses
the other list in its closure?

(Arrow functions, or .bind, are cheap; the `thisArg` makes it basically
impossible to add extra args to all functions that have it, and is almost
never used)

On Mon, Nov 11, 2019 at 11:03 PM Michaël Rouges 
wrote:

> For example, to easily sort the values, compared with another list, using
> only one iteration.
>
> Le mar. 12 nov. 2019 à 07:42, Jordan Harband  a écrit :
>
>> I'd assume it's because sort predates ES5, when the thisArg was added;
>> and also because a well-behaved comparator only operates based on `a` and
>> `b` - why would you need a receiver?
>>
>> On Mon, Nov 11, 2019 at 7:34 PM Michaël Rouges 
>> wrote:
>>
>>> Hi all,
>>>
>>> Is there a reason to not have a `thisArg ` for the
>>> `Array.prototype.sort()` callback?
>>>
>>> Actually, it enforces to bind the context or to have nested functions,
>>> each one creating a new function where it isn't strictly necessary.
>>>
>>> Michaël Rouges - https://github.com/Lcfvs - @Lcfvs
>>> ___
>>> 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: Array.prototype.sort( callbackfn [ , thisArg ] )

2019-11-11 Thread Jordan Harband
I'd assume it's because sort predates ES5, when the thisArg was added; and
also because a well-behaved comparator only operates based on `a` and `b` -
why would you need a receiver?

On Mon, Nov 11, 2019 at 7:34 PM Michaël Rouges 
wrote:

> Hi all,
>
> Is there a reason to not have a `thisArg ` for the
> `Array.prototype.sort()` callback?
>
> Actually, it enforces to bind the context or to have nested functions,
> each one creating a new function where it isn't strictly necessary.
>
> Michaël Rouges - https://github.com/Lcfvs - @Lcfvs
> ___
> 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: Template literal property names in object literals

2019-11-07 Thread Jordan Harband
It would create the ambiguity that "every property name not in brackets is
static/hardcoded" is no longer true.

On Thu, Nov 7, 2019 at 12:14 PM Alex Kodat 
wrote:

> Jordan,
>
> The sentiments in that link discuss the wisdom of having the StringLiteral
> definition include NoSubstitutionTemplate, a question about which I am
> agnostic, and wouldn't provide the full functionality I'm asking about,
> anyway.
>
> And I also understand that the spec currently only allows computed
> property names in square brackets.
>
> My suggestion was that ComputedPropertyName *could* be changed to include
> TemplateString (without square brackets). Whether this is worth doing or
> paints JS syntax into a corner is a fair question, but I don't see that
> adding TemplateString to ComputedPropertyName would create any syntactic
> ambiguities and wouldn't seem to present daunting implementation issues.
> But maybe this last assertion is incorrect and ambiguities would arise or
> implementation would be a nightmare?
>
> Thanks
>
> --
> Alex Kodat
> Senior Product Architect
> Rocket Software
> t: +1 781 684 2294 • m: +1 315 527 4764 • w:
> http://www.rocketsoftware.com/
>
> From: Jordan Harband 
> Sent: Thursday, November 7, 2019 1:46 PM
> To: Alex Kodat 
> Cc: Gus Caplan ; es-discuss@mozilla.org
> Subject: Re: Template literal propery names in object literals
>
> Anything dynamic - computed - should be in brackets, since that's what
> that indicates.
>
> Thus, template literals with substitutions must require brackets.
>
> Based on sentiments like
> https://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftc39%2Fecma262%2Fissues%2F1399%23issuecomment-452910799=02%7C01%7C%7Ca6f02ff84bd446c7593708d763bb3255%7C79544c1eed224879a082b67a9a672aae%7C0%7C0%7C637087527965990546=71bc85j8UPdAdkFjmprrximGsaySHt1o3r8zkV9ZYgQ%3D=0,
> either all template literals or none should be permitted in a given
> position.
>
> Thus, no change is possible.
>
> On Thu, Nov 7, 2019 at 10:00 AM Alex Kodat  ako...@rocketsoftware.com> wrote:
> Thanks Gus,
>
> Good stuff. Though I think I’d take a different tack on the discussion at
> that link, especially as I think the template literals should allow
> substitutions (why not?):
>
> let obj = { `${Date()}`: 1};
>
> I guess the tack I would take in the spec would be to add TemplateLiteral
> to ComputedPropertyName and not worry about whether or not it's a
> NoSubstitutionTemplate.
>
> Thanks
>
> --
> Alex Kodat
> Senior Product Architect
> Rocket Software
> t: +1 781 684 2294 • m: +1 315 527 4764 • w:
> https://nam01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.rocketsoftware.com%2F=02%7C01%7C%7Ca6f02ff84bd446c7593708d763bb3255%7C79544c1eed224879a082b67a9a672aae%7C0%7C0%7C637087527965990546=d62CHuayKkj8EhttWHK9kbMjnnkMGJgrrDbZRjtlul0%3D=0
>
> From: Gus Caplan <mailto:m...@gus.host>
> Sent: Thursday, November 7, 2019 11:13 AM
> To: Alex Kodat <mailto:ako...@rocketsoftware.com>
> Cc: mailto:es-discuss@mozilla.org
> Subject: Re: Template literal propery names in object literals
>
> Related discussion
> https://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftc39%2Fecma262%2Fissues%2F1399=02%7C01%7C%7Ca6f02ff84bd446c7593708d763bb3255%7C79544c1eed224879a082b67a9a672aae%7C0%7C0%7C637087527965990546=8XRONc3vM6asxLzdeGYYKXaqkQ0ltiNzDgBD9en3X7s%3D=0
>
> On Thu, Nov 7, 2019 at 8:46 AM Alex Kodat <mailto:mailto:
> ako...@rocketsoftware.com> wrote:
> Just curious. Is there a reason template literals are not allowed as
> property names in object literals? I can do:
>
>let obj = {'foo bar': 1};
>
> and
>
>let obj = {"foo bar": 1};
>
> but not
>
>let obj = {`foo bar`: 1};
>
> It doesn't seem that allowing the latter would present any syntactic
> problems and seems like almost an oversight that it's not allowed.
>
> The main reason I ask is that we've gone completely over to using template
> literals for all our literals (why not?) and was surprised that we can't
> use a template literal as an object literal property name. Obviously, we
> can do:
>
>let obj = {[`foo bar`]: 1};
>
> And given that square brackets allow arbitrary expressions for propery
> names, it wouldn't seem that supporting template literals for object
> literal property names would not present any daunting implementation issues.
>
> I guess I'd argue that the Principle of Least Astonishment and/or
> completeness suggests that JS should support this.
>
> Sorry if this has been asked before but couldn't find anything in the
> archive.
>
> Thanks
>
> --
> Alex Kodat
> Senior Produc

Re: Template literal propery names in object literals

2019-11-07 Thread Jordan Harband
Anything dynamic - computed - should be in brackets, since that's what that
indicates.

Thus, template literals with substitutions must require brackets.

Based on sentiments like
https://github.com/tc39/ecma262/issues/1399#issuecomment-452910799, either
all template literals or none should be permitted in a given position.

Thus, no change is possible.

On Thu, Nov 7, 2019 at 10:00 AM Alex Kodat 
wrote:

> Thanks Gus,
>
> Good stuff. Though I think I’d take a different tack on the discussion at
> that link, especially as I think the template literals should allow
> substitutions (why not?):
>
> let obj = { `${Date()}`: 1};
>
> I guess the tack I would take in the spec would be to add TemplateLiteral
> to ComputedPropertyName and not worry about whether or not it's a
> NoSubstitutionTemplate.
>
> Thanks
>
> --
> Alex Kodat
> Senior Product Architect
> Rocket Software
> t: +1 781 684 2294 • m: +1 315 527 4764 • w:
> http://www.rocketsoftware.com/
>
> From: Gus Caplan 
> Sent: Thursday, November 7, 2019 11:13 AM
> To: Alex Kodat 
> Cc: es-discuss@mozilla.org
> Subject: Re: Template literal propery names in object literals
>
> Related discussion
> https://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftc39%2Fecma262%2Fissues%2F1399=02%7C01%7C%7C9e20b9f578574ad67b1308d763a5b814%7C79544c1eed224879a082b67a9a672aae%7C0%7C1%7C637087435736614052=xDiwNTWHvdfIakrVFe6RmiP5pLHzC0i%2BoRNwKgvTMvc%3D=0
>
> On Thu, Nov 7, 2019 at 8:46 AM Alex Kodat  ako...@rocketsoftware.com> wrote:
> Just curious. Is there a reason template literals are not allowed as
> property names in object literals? I can do:
>
>let obj = {'foo bar': 1};
>
> and
>
>let obj = {"foo bar": 1};
>
> but not
>
>let obj = {`foo bar`: 1};
>
> It doesn't seem that allowing the latter would present any syntactic
> problems and seems like almost an oversight that it's not allowed.
>
> The main reason I ask is that we've gone completely over to using template
> literals for all our literals (why not?) and was surprised that we can't
> use a template literal as an object literal property name. Obviously, we
> can do:
>
>let obj = {[`foo bar`]: 1};
>
> And given that square brackets allow arbitrary expressions for propery
> names, it wouldn't seem that supporting template literals for object
> literal property names would not present any daunting implementation issues.
>
> I guess I'd argue that the Principle of Least Astonishment and/or
> completeness suggests that JS should support this.
>
> Sorry if this has been asked before but couldn't find anything in the
> archive.
>
> Thanks
>
> --
> Alex Kodat
> Senior Product Architect
> Rocket Software
> t: +1 781 684 2294 • m: +1 315 527 4764 • w:
> https://nam01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.rocketsoftware.com=02%7C01%7C%7C9e20b9f578574ad67b1308d763a5b814%7C79544c1eed224879a082b67a9a672aae%7C0%7C1%7C637087435736623994=hTNIou6kPg5Ms%2FnIK%2BFVjrWa7mcGDtAbSJrVLVufxQU%3D=0
>
> 
> Rocket Software, Inc. and subsidiaries ■ 77 Fourth Avenue, Waltham MA
> 02451 ■ Main Office Toll Free Number: +1 855.577.4323
> Contact Customer Support:
> https://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmy.rocketsoftware.com%2FRocketCommunity%2FRCEmailSupport=02%7C01%7C%7C9e20b9f578574ad67b1308d763a5b814%7C79544c1eed224879a082b67a9a672aae%7C0%7C1%7C637087435736623994=FnuZYm9iu1AHZS4TNuA1TF95h0DzCh1HyF%2FN3CLoQ9M%3D=0
> Unsubscribe from Marketing Messages/Manage Your Subscription Preferences -
> https://nam01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.rocketsoftware.com%2Fmanage-your-email-preferences=02%7C01%7C%7C9e20b9f578574ad67b1308d763a5b814%7C79544c1eed224879a082b67a9a672aae%7C0%7C1%7C637087435736623994=xWVTW4Dr2qH1Hfc9woMu1ah6M9AzNcSkVot1y8A9Dmc%3D=0
> Privacy Policy -
> https://nam01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.rocketsoftware.com%2Fcompany%2Flegal%2Fprivacy-policy=02%7C01%7C%7C9e20b9f578574ad67b1308d763a5b814%7C79544c1eed224879a082b67a9a672aae%7C0%7C1%7C637087435736633951=X3vLto4DdTHU4roy6wY0Ep%2BXVucGx3v9Dw28KsPzfsg%3D=0
> 
>
> This communication and any attachments may contain confidential
> information of Rocket Software, Inc. All unauthorized use, disclosure or
> distribution is prohibited. If you are not the intended recipient, please
> notify Rocket Software immediately and destroy all copies of this
> communication. Thank you.
> ___
> es-discuss mailing list
> mailto:es-discuss@mozilla.org
>
> https://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.mozilla.org%2Flistinfo%2Fes-discuss=02%7C01%7C%7C9e20b9f578574ad67b1308d763a5b814%7C79544c1eed224879a082b67a9a672aae%7C0%7C1%7C637087435736633951=f28Os3jqAQ5VHGcxQ5auW5vcOuoC7s2QupBH5AR52yQ%3D=0
> 
> Rocket Software, Inc. and subsidiaries ■ 77 Fourth Avenue, Waltham MA
> 02451 ■ Main Office Toll Free 

Re: Optional Curly Braces in JavaScript

2019-11-02 Thread Jordan Harband
I don’t think the obstacle to JavaScript becoming more widespread is
mandatory curly braces, nor do i think any part of python’s popularity is
due to optional curly braces.

Separately, how are you measuring “widespread”? One measurement might be,
for example, “how many computers is it used on”, and web browsers dwarf
most everything else :-)

On Sat, Nov 2, 2019 at 6:02 PM Ed Saleh  wrote:

> Hi Kai Zhu,
> We can enforce curly braces through "good practice" JavaScript
> documentation style and eslint style. Making braceless JavaScript feature
> doesn't make it the best style to use, it just give more flexibility. And
> yes Jordan, it should actually be enforced to use curly braces in actual
> coding and that's what I do personally. All I want I want is to see
> JavaScript as wide spread as Python is. I know the reason why Python is
> famous today is for this specific reason, as it's easy to write for all
> types of people.
>
> Thank you all,
> --
> *From:* es-discuss  on behalf of kai zhu <
> kaizhu...@gmail.com>
> *Sent:* Saturday, November 2, 2019 8:06:50 PM
> *To:* Jordan Harband 
> *Cc:* Bergi ; es-discuss 
> *Subject:* Re: Optional Curly Braces in JavaScript
>
> unlike python, many [client-side] javascript programs require
> rollup/minification into a single dist-file.  removing curly braces (just
> like asi) makes that task more difficult.
>
> this is also why esm-import-statements were a terrible idea. ppl like me
> would argue frontend-programs (which are mostly non-reusable anyways)
> should be written as single dist-files from the start rather than as
> modules -- and why python-programmers make terrible [frontend/ux]
> javascript-programmers in general.
>
>
> On Sun, Nov 3, 2019, 04:48 Jordan Harband  wrote:
>
> My preference would be to make them required in the places they're
> currently optional :-)
>
> Optional curly braces have led to many bugs, not just in JS (the "goto
> fail" SSL bug, for example) - why is this risk worth making it easier to
> write code on a whiteboard, where it doesn't need to be valid anyways?
>
> On Sat, Nov 2, 2019 at 12:39 PM Bergi  wrote:
>
> Hello Ed!
>
> > That would make JavaScript an easy to write on board language, where a
> language like python dominates because of it's simplicity in writing. This
> would make JavaScript spread into more areas in science, education and
> engineering.
>
> You seem to not only want to make block syntax optional, but rather make
> whitespace indentation significant. You might want to have a look at
> CoffeeScript <http://coffeescript.org/#language> which is a
> compile-to-JS language that uses this concept. Its function syntax is a
> bit different from what you imagined though, most importantly it doesn't
> offer any declarations.
>
> 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: Optional Curly Braces in JavaScript

2019-11-02 Thread Jordan Harband
My preference would be to make them required in the places they're
currently optional :-)

Optional curly braces have led to many bugs, not just in JS (the "goto
fail" SSL bug, for example) - why is this risk worth making it easier to
write code on a whiteboard, where it doesn't need to be valid anyways?

On Sat, Nov 2, 2019 at 12:39 PM Bergi  wrote:

> Hello Ed!
>
> > That would make JavaScript an easy to write on board language, where a
> language like python dominates because of it's simplicity in writing. This
> would make JavaScript spread into more areas in science, education and
> engineering.
>
> You seem to not only want to make block syntax optional, but rather make
> whitespace indentation significant. You might want to have a look at
> CoffeeScript  which is a
> compile-to-JS language that uses this concept. Its function syntax is a
> bit different from what you imagined though, most importantly it doesn't
> offer any declarations.
>
> 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


Re: Re: Modify Promise.all() to accept an Object as a parameter

2019-10-11 Thread Jordan Harband
The current API accepts an *iterable*, which means any object that has
`Symbol.iterator`, such as an array or a Set.

Throwing when it receives a non-iterable object is an important tool to
catch bugs. If Promise.all was made to accept a non-iterable object as
well, I suspect many bugs would go uncaught.

On Fri, Oct 11, 2019 at 10:15 AM Adam Eisenreich  wrote:

> Back when async/await was introduced I struggeled quite a bit with
> promises arrays that have conditional promises. RxJS is moving from array
> only support in theirs operators to objects too, there seems to be an
> actual trend going on. Is there any reason against?
> ___
> 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: Why globalThis instead of something intuitive like globalObject, systemGlobal, or globalEntity?

2019-09-21 Thread Jordan Harband
This question is more appropriate for the proposal repo, in which a very
lengthy naming document will hopefully answer all of your questions:
https://github.com/tc39/proposal-global/blob/master/NAMING.md

Please address all further comments or replies on this topic to the
proposal repo. Thanks!

On Sat, Sep 21, 2019 at 11:12 AM #!/JoePea  wrote:

> I know it may be too late for this, but I imagine `globalThis` can bring
> confusion to beginners, especially ESL beginners.
>
> Things like `globalObject`, `systemGlobal`, or `globalEntity` would've
> been more intuitive; they make sense in plain English.
>
> Well anyways, have a good weekend!
>
> - 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: Use hashes as keys instead of toString() for values like object, function to index objects

2019-09-08 Thread Jordan Harband
By default, the behavior would have to remain the same, or else it would
break the web.

See https://esdiscuss.org/topic/object-id-hash-etc for more on hash codes.

On Sun, Sep 8, 2019 at 4:36 AM Tadas Lapė  wrote:

> The problem
>
> Javascript allows to index objects not only with strings, numbers, but
> also with objects. It uses toString() object method to calculate the object
> index. If method is not overwritten, the generated index is "[object
> Object]". Many users do not know this or forget this and cause different
> objects going into same index when using more of them.
>
> The solution
>
> Instead of using the default value "[object Object]" for objects, use
> their hash codes. You can also prepend them with "function:" or "object:"
> to let the user know index origin when iterating over object keys. And if
> person has overwritten the behavior of toString() object method, use it's
> returned value as index (to consider). This should be less error-prone.
> ___
> 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: Symbols and SymbolAt

2019-09-08 Thread Jordan Harband
There's already `.codePointAt`, and `[...str].length`.

The thing that's really needed more than code points is grapheme clusters;
see https://esdiscuss.org/topic/working-with-grapheme-clusters

On Sun, Sep 8, 2019 at 5:01 AM Dimitrian Nine 
wrote:

> Maybe i don't know something, but want to proposal idea:
> We have emojis and other symbols, that have many codepoints
> And 'emoji'.length > 1
> My idea that we have something like
> 'emoji'.symbols - and get array of symbols, where symbol is array of
> codepoints
> And maybe method SymbolAt
> 'emoji'.SymobolAt(0) = array of codepoints
>
> Examples:
> '123456emoji789'.symbols.length = 10
> '123456emoji789'.SymbolAt(6) = codepoints of emoji
> ___
> 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] Refer to actual value : keyword "itself"

2019-09-06 Thread Jordan Harband
`var itself = 3;` means that your choice of keyword wouldn't be an option;
you'd be limited to something that was currently a syntax error.

On Fri, Sep 6, 2019 at 2:53 AM Cyril Auburtin 
wrote:

> also optional-chaining will help
> ```js
> return {
> ...state,
> child: {
> ...state?.child,
> subchild: {
> ...state?.child?.subchild,
> property: (state?.child?.subchild?.property ?? 0) + 1
> }
> }
> }
> ```
>
> @Herby yes that's interesting, works in any order actually `const {child,
> child: {subchild}} = state;`
>
> On Fri, Sep 6, 2019 at 11:23 AM Herby Vojčík  wrote:
>
>> On 6. 9. 2019 10:34, Cyril Auburtin wrote:
>> > You could currently do
>> > ```js
>> > object.child.property /= 5
>> > ```
>> >
>> > with destructuring:
>> > ```js
>> > const {child: {subchild}, child} = state;
>>
>> Wow, I didn't know I can do that. Nice.
>>
> ___
> 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: Optional chaining syntax but with the "mice" operator ?

2019-09-06 Thread Jordan Harband
Syntactically marking, in a chain, what you'd like the final value of the
chain to be, seems interesting - forcing optionality into it seems
unnecessary, though, if such a syntactic marker could be attached to all
forms of property access.

Something like: `a.b>.c.d` or `a?.b>?.c?.d` or `a>[b][c][d]`.

(Obviously, the `>` won't work with bracket, and any syntax for normal
properties that only applies to dot and not also bracket would somewhat be
a nonstarter; but the specific syntax can be bikeshedded separately)

On Fri, Sep 6, 2019 at 8:04 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> Indeed I'm not super convinced myself about the "branching issue" 'cause
> `const result = this?.is?.branching?.already` and all I am proposing is to
> hint the syntax where to stop in case something else fails down the line,
> as in `const result = this.?.is part is not reached, there is a certain point to keep going (which is,
> example, checking that `result !== this`)
>
> On Fri, Sep 6, 2019 at 4:17 PM Naveen Chawla 
> wrote:
>
>> Typically, "dot" expressions navigate through values of different types,
>> making "type branching" the inevitable next step in those cases (unless you
>> introduce a common method for further processing for each of those types).
>> So I'm not sure how ultimately that would be avoided.
>>
>> On Fri, 6 Sep 2019 at 14:15, Claude Pache  wrote:
>>
>>>
>>>
>>> Le 6 sept. 2019 à 14:35, Felipe Nascimento de Moura <
>>> felipenmo...@gmail.com> a écrit :
>>>
>>> Doesn't that bring risks to breaking the web?
>>>
>>> You seen, many, MANY servers running php have the "shot-tags" feature
>>> enabled, in which pages with  will be interpreted.
>>> In this case, any html page with embedded scripts using this operator,
>>> or event .js files when the server is configured to also run php in them,
>>> will break.
>>>
>>> Or am I missing something here?
>>>
>>> [ ]s
>>>
>>>
>>> Any future PHP file that incorporate that syntax will almost surely
>>> refuse to compile on servers that has short-tags enabled, making the
>>> problem evident before it produces something useful on the web. This may be
>>> an issue, but this is not what “breaking the web” is intended to mean.
>>> Existing, untouched content will not break. Carelessly updated content
>>> might break, but that’s not fundamentally different from any other careless
>>> update.
>>>
>>> (If anything else, it may convince people that having different
>>> configuration settings w.r.t. short-tags in development environment and in
>>> production environment, is a very bad idea...)
>>>
>>> —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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: [Proposal] Optional spreading

2019-08-22 Thread Jordan Harband
Since you can do this now with:

```js
[
  1,
  ...(condition ? [2, 3] : []),
  3,
]
```
and object spreading already handles this for you, is extra syntax really
needed?

On Thu, Aug 22, 2019 at 6:52 PM Scott Rudiger 
wrote:

> I like it; code seems cleaner to me with its use. However, since the
> syntax is so similar to optional chaining, it's too bad your goal with this
> sample is to check for falsey values rather than nullish values.
>
> [ 1, ?...(condition && [2, 3]), // no extras:) 3, ]
>
> On Thu, Aug 22, 2019, 6:01 PM Beknar Askarov 
> wrote:
>
>> Problem
>>
>> Spreading is great! It contributes towards "declerativity" of the
>> language and reduces verbosity. I see one more feature to add to improve it.
>>
>> Consider following
>>
>> [
>>   1,
>>   condition && 2,
>>   condition && 3,
>>   4,
>> ].filter(Boolean) // filtering needed to remove falsy values
>> // Results in
>> [1, 2, 3, 4] // if condition is `truthy`// and
>> [1, 4] // if not truthy.
>>
>> Another way to achieve the same result without the need of filtering after
>>
>> [
>>   1,
>>...(condition ? [2, 3] : []), // note extra [] in the end, to avoid errors
>>   4,
>> ]
>>
>> Similar pattern with objects
>>
>> {
>>   ...(condition ? { foo: 'bar' } : {}), // extra {}
>> }
>>
>> Another pattern is when condition is the object itself, when it is known
>> that type is one or falsy
>>
>> [
>>   item1,
>>   item2,
>>   ...(itemsOrNull || []) // extra []
>> ]
>>
>> Similar for objects
>>
>> {
>>   ...(obj || {}), // extra {}
>> }
>>
>> I see these patterns appearing very often. And these are cleanest
>> examples I have seen so far.
>> ProposalOptional spreadingWith condition
>>
>> // Arrays
>> [
>>   1,
>>   ?...(condition && [2, 3]), // no extras:)
>>   3,
>> ]// Objects
>> {
>>   ?...(condition && { foo: 'bar' }) // no extras:)
>> }
>>
>> When condition is the object
>>
>> [
>>   item1,
>>   item2,
>>   ?...itemsOrNull // no extras at all:) even (...)
>> ]
>>
>> These look nicer and can be good for performance since (?...), since no
>> cleanup is needed after to remove falsy values or extra spreading even when
>> it is not needed.
>>
>> Looks intuitive (since:
>> https://github.com/tc39/proposal-optional-chaining)
>> Plays nice with typeings.
>>
>> What do you think? https://es.discourse.group/t/optional-spreading/93
>> ___
>> 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: Array.prototype.joinWith(iterable)

2019-08-16 Thread Jordan Harband
Can you elaborate a bit more on how this is a *common* case in the wider
ecosystem?

On Fri, Aug 16, 2019 at 5:29 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> early reply  "which otehr cases"? this is just an example:
>
> [2019, 08, 16, 14, 28, 30].map(i => i < 10 ? ('0' + i) :
> i).joinWith('--T::.');
>
> On Fri, Aug 16, 2019 at 2:24 PM Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> `this ${Symbol('throws')} an error`, so anything that cannot be
>> represented as string should throw too, as it is for `[1, 2,
>> 3].join(Symbol())`.
>>
>> In few words, everything described as parameter for the
>> `Array.prototype.join(param)` should be described as the iterable value,
>> nothng new to add, nothing different to expect.
>>
>> The template literal as is returns a string, but if you use tags, as
>> functions, you deal with an array and a collection or extra values (0 to
>> template.length - 1).
>>
>> The current way to flatten a template via tag, used already in various
>> projects for a reason or another, is the following one:
>>
>> ```js
>> function tag2str(template) {
>>   let str = template[0];
>>   for (let i = 1, t = template.length; i < t; i++)
>> str += arguments[i] + template[i];
>>   return str;
>> }
>> ```
>>
>> I am proposing to simplify this common case with something that could be
>> used for other cases too.
>>
>>
>>
>>
>>
>> On Fri, Aug 16, 2019 at 1:17 PM Naveen Chawla 
>> wrote:
>>
>>> Cool.
>>>
>>> I get it now apart from the "templated string" example. I'm not very
>>> knowledgable about templated strings but on the face it looks like
>>> 'a${x}b${y}' already inserts x and y into the string, so I'm not sure what
>>> else is happening with your proposed method? Clearly I've missed something.
>>>
>>> Apart from that, how would you handle arrays that whose values are not
>>> all strings?
>>>
>>> For naming is still think "weave" would be OK from what I know so far
>>>
>>> On Fri, 16 Aug 2019 at 11:08, Andrea Giammarchi <
>>> andrea.giammar...@gmail.com> wrote:
>>>
 given an array, it joins it through the values of the iterable
 argument, without ever resulting to undefined

 ['a', 'b', 'c'].joinWith(['-']) would produce "a-b-c"

 ['a', 'b', 'c'].joinWith([1, 2]) would produce "a1b2c"

 ['a', 'b', 'c'].joinWith('012') would produce "a0b1c"
 note the string, as iterable, is acceptable too

 const tag = (template, ...values) => template.joinWith(values);
 tag`a${Math.random()}b${Math.random()}`; would fill the gap between a
 and b, or b and c, with the value returned by the two Math.random()

 ['a', 'b', 'c', 'd'].joinWith('01'); would produce "a0b1c0d" so that
 there's never an `undefined









 On Fri, Aug 16, 2019 at 12:01 PM Naveen Chawla 
 wrote:

> I'm just not seeing what it's supposed to do. If you could give a
> brief explanation of the array method, and the string method then of 
> course
> I would get it. I know it would seem obvious to you from the examples
> alone, it's just not to me.
>
> On Fri, 16 Aug 2019 at 08:32, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> Just to re-state: zip from lowdash, does **not** do what my proposed
>> method does ... anything that won't produce the following result is not
>> what I'm proposing
>>
>> console.log(['a', 'b', 'c', 'd'].joinWith([1, 2]));
>> // a1b2c1d
>>
>> function tag2str(template, ...values) {
>>   return template.joinWith(values);
>> }
>>
>> tag2str`a${1}b${2}c`;
>> // "a1b2c"
>>
>> On Fri, Aug 16, 2019 at 5:57 AM Isiah Meadows 
>> wrote:
>>
>>> For that, I'd rather see an `interleave` that just rotates through
>>> all
>>> its arguments. It'd be basically sugar for `.zip().flat()`, but an
>>> implementation could optimize the heck out of it. (In particular,
>>> they
>>> could iterate through them one-by-one and only allocate once, not in
>>> the hot loop, so it'd be fast.)
>>>
>>> I at one point had it in my list of wishlist proposals, but it
>>> somehow
>>> disappeared. I've since recreated it:
>>>
>>> https://github.com/isiahmeadows/es-stdlib-proposals/blob/master/proposals/array/interleave.md
>>>
>>> -
>>>
>>> Isiah Meadows
>>> cont...@isiahmeadows.com
>>> www.isiahmeadows.com
>>>
>>>
>>> On Thu, Aug 15, 2019 at 1:12 PM Andrea Giammarchi
>>>  wrote:
>>> >
>>> > That;s not useful for template literals tags though
>>> >
>>> > _.zip(['a', 'b', 'c'], [1, 2]);
>>> > [["a", 1], ["b", 2], ["c", undefined]]
>>> >
>>> > it basically does nothing I've proposed ... any other name
>>> suggestion?
>>> >
>>> > On Thu, Aug 15, 2019 at 3:40 PM Michał Wadas <
>>> michalwa...@gmail.com> wrote:
>>> >>
>>> >> 

Re: Array.prototype.findIndex(fn, startIndex = 0)

2019-08-15 Thread Jordan Harband
I believe every array iteration method that takes a callback, except for
reduce and reduceRight, take an optional receiver as the last argument (the
`this` value), so they can't be meaningfully/ergonomically extended.

On Thu, Aug 15, 2019 at 3:00 PM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> isn't the second argument already reserved for the context?
>
> ```js
> [1, 2, 3].findIndex(function (i) { return i == this; }, 2);
> // 1
> ```
>
> On Thu, Aug 15, 2019 at 11:51 PM Cyril Auburtin 
> wrote:
>
>> It should be possible to add a second optional argument to the `find` and
>> `findIndex` array methods, similarly to `indexOf`
>> ___
>> 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: Modulo Operator %%

2019-08-15 Thread Jordan Harband
Static functions don't have the same risk as prototype functions;
`Math.mod` would make sense to add.

One suggestion, though, would be to try to add the API method first, and
look at usage for awhile before trying to add the syntax.

On Thu, Aug 15, 2019 at 10:12 AM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> To me there's no risk, as MooTools, Prototype, and Scriptacolous are both
> things of the past, and never implemented Math.mod ... so, with that
> approach, custom transpiling functions are more dangerous, as somebody
> might have implemented `%%` already for other purposes, and we break Babel
> outcome adding new syntax anyway ... the smoosh accident, is the equivalent
> of custom Babel utilities these days.
>
> Look at TypeScript and the private class fields, if you want to compare
> new syntax instead
>
> On Thu, Aug 15, 2019 at 4:50 PM Michael Haufe 
> wrote:
>
>> Thursday, August 15, 2019 2:47 AM, Andrea Giammarchi wrote:
>>
>>
>>
>> > FWIW another disadvantage is that operators cannot be polyfilled, so
>> it'll take forever for those not using transpilers to adopt these, while
>> having a `Math,mod` would work right away
>>
>>
>>
>>
>>
>> With such an approach there is risk of another ‘smooshgate’ [1][2]. There
>> is nothing stopping those developers from using a function anyway to bridge
>> the gap if they can’t or won’t use a compiler. This is already the current
>> state of affairs.
>>
>>
>>
>> [1] https://developers.google.com/web/updates/2018/03/smooshgate
>>
>> [2]
>> https://adamsilver.io/articles/the-disadvantages-of-javascript-polyfills/
>>
>>
>>
>> Michael
>>
> ___
> 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: Promise resolution handler fires before synchronous constructor stack has finished.

2019-07-28 Thread Jordan Harband
No, that's not accurate - every `.then` always executes on a future tick,
never synchronously.

On Sat, Jul 27, 2019 at 11:11 PM Ranando King  wrote:

> 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


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

2019-07-28 Thread Jordan Harband
When I run this in a node repl, that's exactly what happens - perhaps your
simplified example has simplified out the bug?

On Sat, Jul 27, 2019 at 6: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-28 Thread Jordan Harband
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] <https://twitter.com/BrendanEich/status/798317702775324672>
> >
> >
> >
> > 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/274e49412c09f81a0a82f386e6eead4

Re: Proposal: Typeof Trap

2019-07-27 Thread Jordan Harband
typeof is very often useful - the only case where it can be arguably
considered "broken" is with null.

The reason `instanceof` is unreliable is indeed because [[Prototype]]s are
mutable - eg `({ __proto__: Array.prototype }) instanceof Array` - but also
because it returns a false negative when compared with builtins from
different realms (which is why `Array.isArray` is needed.

If the ability you're talking about is to freeze the [[Prototype]] slot on
an object without fully freezing, sealing, or preventing extensions, that
is something a future proposal is very likely to add.

On Sat, Jul 27, 2019 at 2:06 PM Ranando King  wrote:

> 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] <https://twitter.com/BrendanEich/status/798317702775324672>
>>>
>>>
>>>
>>> *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: Proposal: Typeof Trap

2019-07-27 Thread Jordan Harband
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] <https://twitter.com/BrendanEich/status/798317702775324672>
>
>
>
> *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


Re: Lazy Iterators

2019-07-27 Thread Jordan Harband
See https://github.com/tc39/proposal-iterator-helpers

On Sat, Jul 27, 2019 at 1:45 PM Artem Kobzar  wrote:

> The proposal based on really worst thing in JavaScript Arrays.
>
> If i as developer want to make declarative code with combination of
> `Array#map`, `Array#filter` or `Array#reduce` - i will take a lot of
> iterations (count of chain element will determinate count of iterations).
>
> ```js
> const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
>
> const newArr = arr
>   .map(a => a + 1)
>   .filter(a => a % 2 === 0)
>   .filter((a, i) => i < 3); // [2, 4, 6], but 3 iterations across `arr`
> ```
>
> So, my proposal is: add lazy iterator with additional functions which help
> to use declarative collection method in chain as "zero-abstraction" and
> will iterate only once (will not be related to count of chain methods).
>
> Actually, i've already created implementation and usage of this
> implementation looks like this:
>
> ```js
> const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
>
> const newArr = arr
>   .lazy()
>   .map(a => a + 1)
>   .filter(a => a % 2 === 0)
>   .take(3)
>   .collect(); // [ 2, 4, 6 ], but 1 iterations across `arr`
> ```
>
> And, actually, current implementation could be used with all `Iterable`
> objects, if this object will implement method `fromIterator` (it's needed
> for `LazyIterator#collect` method).
> ___
> 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 Jordan Harband
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


Re: Proposal: SuperSet

2019-07-09 Thread Jordan Harband
Are you perhaps looking for https://github.com/tc39/proposal-set-methods ?

On Tue, Jul 9, 2019 at 1:18 PM Oğuz Kılıç  wrote:

> Yes, I already consider it as an enriched version of the current set
> method, I just like calling it superset :)
>
> On Tue, Jul 9, 2019 at 11:05 PM Григорий Карелин 
> wrote:
>
>> Maybe add those methods into Set instead of creating new type?
>>
>> On Tue, 9 Jul 2019 at 23:02, Oğuz Kılıç  wrote:
>>
>>> As you know, the current Set feature is not sufficient in some aspects.
>>> We benefit from utility libraries or special implementations to fill this
>>> deficiency.
>>>
>>> For example, wouldn’t it be better if we had the following approach?
>>>
>>> UNION
>>>
>>> X ∪ Y = { x | x ∈ X or x ∈ Y }
>>>
>>> let first = new SuperSet(["a", "b", "c"]);
>>> let second = new SuperSet(["b", "c", "d", "e"]);
>>>
>>> first.union(second); //→ SuperSet { "a", "b", "c", "d", "e" }
>>>
>>> DIFFERENCE
>>>
>>> X - Y = { x | x ∈ X and x ∉ Y }
>>>
>>> let nums = new SuperSet([3, 4, 5, 6]);
>>> let primes = new SuperSet([2, 3, 5, 7]);
>>>
>>> nums.diff(primes); // → SuperSet { 4, 6 }
>>>
>>> INTERSECT
>>>
>>> X ∩ Y = { x | x ∈ X and x ∈ Y }
>>>
>>> let nums = new SuperSet([3, 4, 5, 6]);
>>> let primes = new SuperSet([2, 3, 5, 7]);
>>> nums.intersect(primes); // → SuperSet { 3, 5 }
>>>
>>> DISCARD
>>>
>>> let nums = new SuperSet([1, 2, 3, 4]);
>>> nums.discard([1, 3]); // → SuperSet { 2, 4 }
>>>
>>> Motivation
>>> SuperSet - https://github.com/BYK/superset
>>> ___
>>> 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: effect of editor/ide on javascript programming-style

2019-06-28 Thread Jordan Harband
As much as I like vim, this seems like more of an argument against using
vim than anything for the language - also it's not "usually" just 1
frontend developer; altho that may be your experience. I often like to say
it's *never* just one - even if it's you, it's also "you in 6 months", and
that person is really annoyed with you.

As an anecdotal data point, my garage startup which had no funding had 3 JS
devs working on our frontend. I would argue it's not very cost effective to
*under*invest in frontend dev, but obviously everyone has different
opinions on that - and it's not relevant to this discussion list.

On Fri, Jun 28, 2019 at 9:59 AM kai zhu  wrote:

> adding a datapoint on effects of vim-editor on my javascript
> coding-style.  this is to expand on discussion of "JavaScript and Syntax
> Research Methods" in tc39-notes [1].
>
> vim has the following file-editing properties:
> 1. poor UX in opening new files
> 2. efficient content-search/jump/traversal of large files
> 3. can display the same file in multiple editing-windows
>
> because of above properties, i default to writing javascript applications
> as a single, large file (which may get broken up if it becomes "too" large,
> e.g. >10k sloc).  developing javascript-apps with a single js-file leads me
> to:
> 1. prefer reusing external-code by copy/pasting it into single-file rather
> than load it as commonjs/es-module
> 2. be selective about what external-code i want to copy/paste -- generally
> only self-contained or "rolled-up" ones w/ minimal external-dependencies
> 3. general preference to write self-contained code that easy-to-reuse by
> copy/pasting into a new project [2].
>
> an argument against writing javascript-applications as a single,
> self-contained file, is that it leads to merge/commit conflicts when
> multiple devs are working on same file.  its valid ... except most
> javascript-products are developed by just 1-3 js-devs.  for the frontend,
> its usually just 1 developer.  the hype of making javascript "scalable" so
> you can have 20x people working on a product is just that -- hype.  there
> are very few real-world products where its cost-effective to have more than
> 5 js-devs working on it.
>
> [1] JavaScript and Syntax Research Methods
>
> https://github.com/rwaldron/tc39-notes/blob/7a4af23d/meetings/2019-06/june-6.md#javascript-and-syntax-research-methods
>
> [2] documentation of various [minimal-dependency] self-contained functions
> that can be copy/pasted
>
> https://kaizhu256.github.io/node-utility2/build..beta..travis-ci.org/apidoc.html
>
>
>
>
> screenshot of me vim-editing multiple locations of one, large
> javascript-file (each sub-window is a different location of the same file).
> [image: vim-editor-min.png]
>
> ___
> 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: `String.prototype.trimStart`/`String.prototype.trimEnd` with a given string

2019-06-24 Thread Jordan Harband
That's also true, although I believe `\s` in a regex includes line
terminators that trim's concept of whitespace does not.

On Mon, Jun 24, 2019 at 4:15 PM Jacob Pratt  wrote:

> Just thinking about this, the argument that it could be done with regex
> would also apply to spaces. It's by no means an argument _in favor_, but it
> clearly wasn't a blocker.
>
> On Mon, Jun 24, 2019 at 4:10 PM kai zhu  wrote:
>
>> fyi, a search of the entire markedjs/marked repo shows 2 places where
>> rtrim is used:
>>
>> ```js
>> // https://github.com/markedjs/marked/blob/master/lib/marked.js
>> 227
>> <https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L227>
>> codeBlockStyle: 'indented',
>> 228
>> <https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L228>
>> text: !this.options.pedantic
>> 229
>> <https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L229>
>> ? rtrim(cap, '\n')
>> 230
>> <https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L230>
>> : cap
>> …
>> 1425
>> <https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1425>
>> baseUrls[' ' + base] = rtrim(base, '/', true);
>> 1426
>> <https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1426>
>>  }
>>
>> 1427
>> <https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1427>
>>  }
>>
>> 1428
>> <https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1428>
>>  base
>> = baseUrls[' ' + base];
>> 1429
>> <https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1429>
>> 1430
>> <https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1430>
>> if (href.slice(0, 2) === '//') {
>> ```
>>
>> only the 1st use-case does what this thread proposes (the 1st trimRight's
>> "\n", while the 2nd behaves differently and is more like nodejs'
>> `require("path").dirname()`
>>
>> if i were writing the library, i wouldn't have bothered with a
>> helper-function if its only going to show up in 2 [trivial] places.
>> would've instead inlined two throwaway regexp-expressions, to keep code
>> more-self-contained / less-fragmented:
>>
>> ```js
>> 228  text: !this.options.pedantic
>> 229? cap.replace((/\n+$/), "") // remove trailing "\n" or
>> perhaps just use .trimRight()
>> 230: cap
>> …
>> 1425  baseUrls[' ' + base] = base.replace((/\/[^\/]*$/), "/"); //
>> get "dirname" of base-url
>> 1426}
>> ```
>>
>> On Mon, Jun 24, 2019 at 2:27 PM Jacob Pratt  wrote:
>>
>>> No idea how common of a use case this is; I personally ran across it
>>> when reviewing the source code for marked (specifically the [rtrim
>>> method]). That example only does characters, not strings, but it's used in
>>> the wild by a package with ~2m weekly downloads on npm.
>>>
>>> Of course we wouldn't want `trimStart` to differ from `trimLeft`, they'd
>>> all be modified in unison. I just think that symmetry between similar
>>> methods is important, and (apparently) has use cases.
>>>
>>> [rtrim method]:
>>> https://github.com/markedjs/marked/blob/master/lib/marked.js#L1493-L1517
>>>
>>> On Mon, Jun 24, 2019 at 12:46 AM Jordan Harband 
>>> wrote:
>>>
>>>> `trimStart` and `trimEnd` are better-named versions of the very very
>>>> long-existing `trimLeft` and `trimRight`, which lack this ability, along
>>>> with ES5's `trim`.
>>>>
>>>> It wouldn't make sense for these three to differ.
>>>>
>>>> It certainly seems like a potential language proposal to add a string
>>>> argument to all three; however, at what point is that reimplementing
>>>> `string.replace(/^(foo)+/, '')`, `string.replace(/(foo)+$/, '')`, and
>>>> `string.replace(/^(foo)+|$(foo)+$/, '')`? How common is the use case to
>>>> trim matching substrings off of the ends of a string? (the use cases for
>>>> padding were quite common)
>>>>
>>>> On Sun, Jun 23, 2019 at 12:14 AM Jacob Pratt 
>>>> wrote:
&

Re: `String.prototype.trimStart`/`String.prototype.trimEnd` with a given string

2019-06-23 Thread Jordan Harband
`trimStart` and `trimEnd` are better-named versions of the very very
long-existing `trimLeft` and `trimRight`, which lack this ability, along
with ES5's `trim`.

It wouldn't make sense for these three to differ.

It certainly seems like a potential language proposal to add a string
argument to all three; however, at what point is that reimplementing
`string.replace(/^(foo)+/, '')`, `string.replace(/(foo)+$/, '')`, and
`string.replace(/^(foo)+|$(foo)+$/, '')`? How common is the use case to
trim matching substrings off of the ends of a string? (the use cases for
padding were quite common)

On Sun, Jun 23, 2019 at 12:14 AM Jacob Pratt  wrote:

> `String.prototype.padStart` and `String.prototype.padEnd` accept the
> string to pad with as their final parameter. Is there any particular reason
> `String.prototype.trimStart` and `String.prototype.trimEnd` don't do the
> same? It would be nice to have a parallel, such that `'foo'.padEnd(10,
> 'bar').trimEnd('bar') === 'foo'`.
>
> References:
> - https://github.com/tc39/proposal-string-pad-start-end
> - https://github.com/tc39/proposal-string-left-right-trim
>
> Jacob Pratt
> ___
> 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: What do you think about a C# 6 like nameof() expression for

2019-06-16 Thread Jordan Harband
again, `Object.keys({ y })[0]` will give you the string `y`, and will
survive refactoring tools. you can even do `function nameof(obj) { return
Object.keys(obj)[0]; }` and then `nameof({ y })`.

Obviously it's slightly less ergonomic than `nameof y` would be - but
adding new syntax is very expensive, so there'd need to be overwhelming
evidence that this pattern is commonly used enough, and that userland
workarounds like my `nameof` function were insufficient.

On Sun, Jun 16, 2019 at 10:13 PM Frederick Stark  wrote:

> > > your examples are all completely incorrect anyway
> > "incorrect" as to precisely what?
> Keep reading the email mate.
> Incorrect as to your understanding of how the language works and at what
> point variables are defined.
>
> > The user MUST _already_ know the _exact_ identifier name
> It's not an issue to need to know the name of the identifier. In fact, as
> you correctly pointed out, it's necessary.
> If I'm understanding it correctly, the value of the proposal is to make it
> easier to refactor (especially with variable renaming tools) without
> leaving behind string literals that no longer match the variable name.
>
> I've run into this issue before, but it's been a relatively minor pain for
> me personally. So I can see some use for the proposal, though I suspect it
> would see most of it's use in tooling.
> On the other hand, it might add unnecessary complexity to the language,
> which should be avoided.
> Overall I'm very mildly supportive.
>
> > That leaves the use case of getting ALL of the names of the identifiers
> in the current scope
> I have not seen anyone proposing this, so there's no reason to criticize
> it yet.
>
>
> Obligatory disclaimer: not a TC39 member, no decision making power or
> influence on process
> On Jun 17 2019, at 2:42 pm, guest271314  wrote:
>
> The user MUST _already_ know the _exact_ identifier name or an error will
> be thrown for the original proposal and additional use case for ```nameof```
>
> const x = nameof y; // "y"
> const y = 1;
>
> making the need for ```nameof``` moot given that the user cannot then
> rationally state that the identifier as a _string_ will somehow be
> mispelled if they are able to write the _exact_ name of the identifer at
> ```nameof``` 100% of the time.
>
> That leaves the use case of getting ALL of the names of the identifiers in
> the current scope
>
> // NAMEOF is always dynamic list of let, const declarations in current scope
> console.log(NAMEOF); // ["x", "y"]; [{name:"x", line:5}, {name:"y", line:7}]
> // should resolve be in the list even if not declared using const or let?
> await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 
> 1000)));
> const x = nameof y
> await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 
> 1000)));
> const y = 1;
>
>
> without having to already know the name of the identifiers, as is required
> by the original proposal, which essentially negates itself as the string
> literal ```'y'``` is briefer than ```nameof y```.
>
>
> On Mon, Jun 17, 2019 at 4:19 AM Frederick Stark 
> wrote:
>
> guest271314, your examples are all completely incorrect anyway since all
> variable declarations (including let and const) are hoisted to the top of
> the scope, so when nameof y is evaluated, y is already declared in the
> scope.
>
> The special behaviour introduced with let and const is that they set up a
> "Temporal Dead Zone" where attempts to set or get their value before the
> line where they are declared in code throws an exception.
> Since nameof doesn't care about the value, only the name of the variable,
> it would not *need* to throw an exception.
> Of course, were this proposal to be taken seriously, it could be specced
> either way
>
>
> On Jun 17 2019, at 10:15 am, guest271314  wrote:
>
> > - If `y` is directly visible in scope and is neither a parameter or
> destructured binding, `nameof y` should just evaluate to `"y"`. This
> should be agnostic to whether the binding has been declared yet, so in
> your example, `x` should be set to `"y"`.
>
> The 1st question at
> https://esdiscuss.org/topic/what-do-you-think-about-a-c-6-like-nameof-expression-for#content-33
> remains:
>
> Without having composed or previously read the source code, at line 1
> adjacent to ```nameof``` how does the user know that there will be later
> declared variable named ```y```?
>
>
>
> On Sun, Jun 16, 2019 at 7:04 AM Isiah Meadows 
> wrote:
>
> Here's my opinion:
>
> - If `y` is directly visible in scope and is neither a parameter or
> destructured binding, `nameof y` should just evaluate to `"y"`. This
> should be agnostic to whether the binding has been declared yet, so in
> your example, `x` should be set to `"y"`.
> - If `y` is entirely undeclared, it should be a runtime
> `ReferenceError` in the same way it is when accessing undefined
> globals. So in your second example, I'd expect it to throw before even
> attempting assignment
>
> -
>
> Isiah Meadows
> 

Re: Re: What do you think about a C# 6 like nameof() expression for

2019-06-14 Thread Jordan Harband
`nameof whatever` → `Object.keys({ whatever })[0]`, but I'm a bit confused
why it'd be better to type `nameof foo` in code, rather than `'foo'` - if
you change `foo` to `bar`, you have to change both of them anyways.

On Fri, Jun 14, 2019 at 1:31 PM guest271314  wrote:

> Am neither for nor against the proposal. Do not entertain "like"s or
> "dislike"s in any field of endeavor. Am certainly not in a position to
> prohibit anything relevant JavaScript. Do what thou wilt shall be the whole
> of the Law.
>
> Have yet to view a case where code will be "broken" by ```nameof``` not
> being a JavaScript feature. "robustness", as already mentioned, is a
> subjective adjective that is not capable of being objectively evaluated as
> to code itself. That description is based on preference or choice.
>
> In lieu of the proposal being specificed, use the posted code example of
> ```Object.keys()``` that "works".
>
> ```
> function func1({userName = void 0} = {}) {
>   console.assert(userName !== undefined, [{userName}, 'property needs to
> be defined'])
> }
> ```
>
> provides a direct indication that the property value is required to be
> defined. Note that the example code posted thus far does not first check if
> ```options``` is passed at all, for which ```nameof``` will not provide any
> asssitance.
>
> Usually try to meet requirement by means already available in FOSS
> browsers. Have no interest in TypeScript or using an IDE.
>
> FWIW, have no objection to the proposal.
>
> On Fri, Jun 14, 2019 at 7:53 PM Stas Berkov  wrote:
>
>> guest271314, what is you point against `nameof` feature?
>>
>> If you don't like it - don't use it. Why prohibit this feature for
>> those who find it beneficial?
>>
>> I see `nameof` beneficial in following cases
>>
>> Case 1. Function guard.
>> ```
>> function func1(options) {
>> ...
>>if (options.userName == undefined) {
>>throw new ParamNullError(nameof options.userName); //
>> `ParamNullError` is a custom error, derived from `Error`, composes
>> error message like "Parameter cannot be null: userName".
>>  // `Object.keys({options.userName})[0]` will not work here
>>}
>> }
>> ```
>>
>> Case 2. Accessing property extended info
>> Those ES functions that accept field name as string.
>> e.g.
>> ```
>> const descriptor1 = Object.getOwnPropertyDescriptor(object1, 'property1');
>> ```
>> vs
>> ```
>> const descriptor1 = Object.getOwnPropertyDescriptor(object1, nameof
>> object1.property1);
>>  // `Object.keys({options1.property1})[0]` will not work here
>> ```
>> 2nd variant (proposed) has more chances not to be broken during
>> refactoring (robustness).
>>
>> It would make devs who use IDE more productive and make their life
>> easier. Why not give them such possiblity and make them happy?
>>
> ___
> 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: native XML object support.

2019-05-15 Thread Jordan Harband
(that's not react's creator; that's redux's creator, who is now a member of
the react core team)

On Wed, May 15, 2019 at 8:17 PM Isiah Meadows 
wrote:

> Fun fact: React elements are plain JS objects that are nearly
> JSON-compatible. The only reason why they aren't is because of the presence
> of a `$$typeof: Symbol.for("react.element")` property on React elements, to
> prevent people from using non-array object results of
> `JSON.parse(jsonString)` directly as a child. The rationale for this is
> explained in this blog post by React's creator:
> https://overreacted.io/why-do-react-elements-have-typeof-property/
>
> I would say that we live in a JSON-centric world for APIs,
> SGML/XML-centric for UIs. (I wish XHTML efforts actually stuck, to be
> honest. `` is one reason XML would've been better than
> SGML IMHO.)
>
> On Tue, May 14, 2019 at 01:47 Ed Saleh  wrote:
>
>> Thanks for reply. Didn't know that it existed before!
>> I don't think we can say that we live in a JSON centric world when things
>> like React show up and revolutionize web development. I think JSON has its
>> uses and XML has its uses. UI shouldn't been ever seperated from controller
>> since one can't exist without the other.
>> --
>> *From:* es-discuss  on behalf of Sanford
>> Whiteman 
>> *Sent:* Tuesday, May 14, 2019 1:37:46 AM
>> *To:* es-discuss@mozilla.org
>> *Subject:* Re: Proposal: native XML object support.
>>
>> > let foo = 
>>
>> This is a retread of E4X (
>> https://en.wikipedia.org/wiki/ECMAScript_for_XML)
>> so I can't imagine it would be resuscitated in a (for better or worse)
>> JSON-centric
>> world.
>>
>> —— Sandy
>>
>> ___
>> 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
>>
> --
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
> ___
> 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: Lazy Error.message

2019-05-11 Thread Jordan Harband
It can already be a getter if you like, which would allow a function to
compute the value on demand.

On Sat, May 11, 2019 at 6:55 AM _ zaoqi  wrote:

> Allow Error.prototype.message to be a Function
>
> It is useful in this case:
>
> https://github.com/browserify/commonjs-assert/pull/47
>
> ___
> 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: Discussion: Module Reflection - import.reflect

2019-04-24 Thread Jordan Harband
`import * as Self from '.'` should work in every implementation of ESM
that's shipped so far that I'm aware of.

On Wed, Apr 24, 2019 at 8:39 AM Randy Buchholz 
wrote:

> Maybe my example was misleading by using an `import`. What I’m talking
> about is inspecting the module from within itself. Similar to `this` or
> `self`,  AFAIK, I can’t get a reference to the module from within the
> module – e.g., `module`. Say, I’m in a module that has a default export of
> class “Foo”. In a function **in** that module (or class), I want to
> create an instance of that default export. I can do it by name `new Foo()`.
> But, in more generic code, I need to do it by “role” - `default`. So my
> generic version wants something that represents `new module.default()`.
> This is because I may not have access to the name – say the function is in
> a base class. Take for example a “type” module, that is a wrapper for a
> single class, and the filename = class name. One way I can implement
> `instanceof` is a string approach:
>
>
>
> ```
>
> // Foo.mjs
>
> export default class Foo {
>
> static type = import.meta.url;
>
>
>
> meta = { type: import.meta.url };
>
>
>
> // instanceof
>
> static [Symbol.hasInstance](instance) {
>
> return instance.meta.type === Foo.type;
>
> }
>
> }
>
> ```
>
> Some weaknesses are it’s strings, and I need to know the name of the class
> (for `Foo.type`). So I can’t move this to a base class.
>
>
>
> With module reflection, I could do this with objects:
>
> ```
>
> // Foo.mjs
>
> export default class Foo {
>
> meta = { type: import.reflect.default };
>
>
>
> // instanceof
>
> static [Symbol.hasInstance](instance) {
>
> return instance.meta.type === import.reflect.default;
>
> }
>
> }
>
> ```
>
>
>
> A similar idea would be to define a Module Scope - `module`. Within a
> module, using `module` would be like a “static self” – it works on the
> structure (e.g., definition) of the module.
>
> Then `import.reflect.default`  could be `module.default`.
> ___
> 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 Promise.prototype.flatten

2019-04-24 Thread Jordan Harband
Would this not work?

async function test(promise1, promise2, promise3) {
  const val1 = await promise1.catch(); // ignore exceptions
  const [val2, val3] = [] = await Promise.all([promise2, promise3]).catch();

  await Promise.all([promise1, promise2, promise3]); // throw to caller

  return val1 + val2 + val3;
}


On Tue, Apr 23, 2019 at 1:25 PM Aaron Silvas  wrote:

> https://github.com/asilvas/proposal-promise-flatten
>
> Looking for interest, and TC39 champion.
>
> The basic idea is to provide a simpler, more consistent interface, and
> easier to read code over using try/catches for async code paths. Regardless
> of which errors are handled or ignored, it's treated as nothing more than
> another input in the result, not all that dissimilar to callbacks.
>
> async function test(promise1, promise2, promise3) {
>   const [, val1] = await promise1.flatten(); // ignore exceptions
>   const [err, [val2, val3] = []] = await Promise.all([promise2, 
> promise3]).flatten();
>
>   if (err) throw err; // throw to caller
>
>   return val1 + val2 + val3;
> }
>
>
> Original topic that spurred interest in this pattern:
> https://twitter.com/DavidWells/status/1119729914876284928
>
> Spec discussions:
> https://twitter.com/Aaron_Silvas/status/1120721934730137601
>
>
> Thanks,
>
> Aaron
> ___
> 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 Jordan Harband
`const` means it can't be reassigned, but a non-frozen value can still have
its properties changed or its [[Prototype]] changed (including Promise,
which could have its `.then` method changed), which would change the type.

On Fri, Apr 5, 2019 at 11:36 AM guest271314  wrote:

> Two possible solutions to the requirement of not being able to change a
> "type" both include utilizing `const`.
>
> 1. Using `Object.freeze()`
>
> `const x = Object.freez([1,2,3])`
>
> 2. Using `Promise.resolve()`
>
> `const x = Promise.resolve([1,2,3])`
>
> neither of which can be deleted or changed within the current scope.
> ___
> 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 Jordan Harband
`const [a, b] = Array.from(anyArraylikeObject);`

On Tue, Mar 19, 2019 at 7:22 PM Frederick Stark  wrote:

> This already works with an iterator, because array destructuring uses the
> iterator protocol
>
> const [a, b] = {
>   0: "ayy",
>   1: "bee",
>   length: 2,
>   *[Symbol.iterator]() {
>   let i = 0;
>   while (i < this.length) {
>   yield this[i]
>   i++
>   }
>   },
> };
>
>
>
> On Mar 20 2019, at 11:59 am, 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
>
___
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-09 Thread Jordan Harband
There'd still have to be a way for an arbitrary function - which (unless
called in `a.b()` form) has no guaranteed connection back to `a` - to have
a reference back to the object.

On Sat, Mar 9, 2019 at 10:57 PM Michael Luder-Rosefield <
rosyatran...@gmail.com> wrote:

> How about binding `this` to a variable in the constructor? The following
> syntax throws an error due to `this` being a reserved word, so won't break
> any existing code:
>
> ```
> class Foo {
>   constructor (this: self, /* normal args */) {
> // ...
>   }
> }
> ```
>
> I can see arguments against that as it breaks the convention for how
> parameter lists work, and also requires a constructor. Perhaps, then, we
> could either use something like a modified version of class field
> declarations to make class variables:
>
> ```
> class Foo {
>   const self = this;
>   // ...
> }
> ```
>
> Or, maybe, allow parentheses before the class body to define variables:
>
> ```
> class Foo (this: self) {
>   //...
> }
> ```
>
> No, I don't like that one either.
>
> The second suggestion (class variables as extension of class fields
> proposal) seems like it has potential to me, so it seems like an excellent
> time for everyone here to tell me why it's awful and stupid.
>
> On Sun, 10 Mar 2019 at 06:59 Jordan Harband  wrote:
>
>> The engine only has that knowledge when you call it in `a.b()` form - at
>> which point, `this` is already the instance. For a keyword to not be
>> context dependent, it'd have to be the instance even when you'd done
>> something like `const { b } = a; b()`. To do this would require either a)
>> `a` has its own distinct copy of `b` that's bound to `a`, or b) `a.b` to be
>> a getter that does that binding upon request.
>>
>> Constructor-binding, field-binding, or arrow function fields all work the
>> same way - they create a separate copy of a function for *each and every*
>> instance, so that the function can point back to the instance even when
>> extracted off of the object.
>>
>> I'm not clear on how there'd be any other way to do it.
>>
>> On Sat, Mar 9, 2019 at 1:41 PM john larson 
>> wrote:
>>
>>> Although the method lives on the prototype, the engine should already
>>> have knowledge of the object whose method is being invoked. I am not an
>>> expert on the internal workings of the engine, so I would be glad if anyone
>>> would correct me on this if I am wrong.
>>>
>>>
>>> <https://www.avast.com/sig-email?utm_medium=email_source=link_campaign=sig-email_content=webmail_term=icon>
>>>  Virus-free.
>>> www.avast.com
>>> <https://www.avast.com/sig-email?utm_medium=email_source=link_campaign=sig-email_content=webmail_term=link>
>>> <#m_4773041203224270933_m_6849901573705770350_m_-8660865756228832385_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
>>>
>>> On Sun, Mar 10, 2019 at 12:27 AM Jordan Harband 
>>> wrote:
>>>
>>>> An additional keyword like this would require a function to have a
>>>> hidden reference back to the instance. However, especially for `class`
>>>> methods, but also for ES5-style inheritance, or even for `class Foo {}
>>>> Foo.prototype.bar = function () {}`, methods are *shared*. You might have a
>>>> billion instances, but only one function that uses your new keyword - how
>>>> would the engine know which instance you were referring to?
>>>>
>>>> On Sat, Mar 9, 2019 at 7:50 AM Bergi  wrote:
>>>>
>>>>> Hi John,
>>>>>
>>>>> > I believe that it would be a trivial task for
>>>>> > current static code analyzers to restrict usage of "this" for anyone
>>>>> > opting in to use this new keyword exclusively.
>>>>>
>>>>> Static tooling, like the TypeScript compiler, can detect problematic
>>>>> method usage already today. Sure, having a dedicated syntax for this
>>>>> will make static analysis simpler, but I don't deem that a worthy
>>>>> addition to the language.
>>>>>
>>>>> > As you mentioned, arrow functions might have their own
>>>>> > problems. Wouldn't such an alternative keyword be a good addition to
>>>>> our
>>>>> > toolkit anyway?
>>>>>
>>>>> What I was trying to say is that your proposed alternative has exactly
>>>>> the same problems as instance-member arrow functions have today.
>>>>>
>>>>> 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


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

2019-03-09 Thread Jordan Harband
The engine only has that knowledge when you call it in `a.b()` form - at
which point, `this` is already the instance. For a keyword to not be
context dependent, it'd have to be the instance even when you'd done
something like `const { b } = a; b()`. To do this would require either a)
`a` has its own distinct copy of `b` that's bound to `a`, or b) `a.b` to be
a getter that does that binding upon request.

Constructor-binding, field-binding, or arrow function fields all work the
same way - they create a separate copy of a function for *each and every*
instance, so that the function can point back to the instance even when
extracted off of the object.

I'm not clear on how there'd be any other way to do it.

On Sat, Mar 9, 2019 at 1:41 PM john larson  wrote:

> Although the method lives on the prototype, the engine should already have
> knowledge of the object whose method is being invoked. I am not an expert
> on the internal workings of the engine, so I would be glad if anyone would
> correct me on this if I am wrong.
>
>
> <https://www.avast.com/sig-email?utm_medium=email_source=link_campaign=sig-email_content=webmail_term=icon>
>  Virus-free.
> www.avast.com
> <https://www.avast.com/sig-email?utm_medium=email_source=link_campaign=sig-email_content=webmail_term=link>
> <#m_-8660865756228832385_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
>
> On Sun, Mar 10, 2019 at 12:27 AM Jordan Harband  wrote:
>
>> An additional keyword like this would require a function to have a hidden
>> reference back to the instance. However, especially for `class` methods,
>> but also for ES5-style inheritance, or even for `class Foo {}
>> Foo.prototype.bar = function () {}`, methods are *shared*. You might have a
>> billion instances, but only one function that uses your new keyword - how
>> would the engine know which instance you were referring to?
>>
>> On Sat, Mar 9, 2019 at 7:50 AM Bergi  wrote:
>>
>>> Hi John,
>>>
>>> > I believe that it would be a trivial task for
>>> > current static code analyzers to restrict usage of "this" for anyone
>>> > opting in to use this new keyword exclusively.
>>>
>>> Static tooling, like the TypeScript compiler, can detect problematic
>>> method usage already today. Sure, having a dedicated syntax for this
>>> will make static analysis simpler, but I don't deem that a worthy
>>> addition to the language.
>>>
>>> > As you mentioned, arrow functions might have their own
>>> > problems. Wouldn't such an alternative keyword be a good addition to
>>> our
>>> > toolkit anyway?
>>>
>>> What I was trying to say is that your proposed alternative has exactly
>>> the same problems as instance-member arrow functions have today.
>>>
>>> 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


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

2019-03-09 Thread Jordan Harband
An additional keyword like this would require a function to have a hidden
reference back to the instance. However, especially for `class` methods,
but also for ES5-style inheritance, or even for `class Foo {}
Foo.prototype.bar = function () {}`, methods are *shared*. You might have a
billion instances, but only one function that uses your new keyword - how
would the engine know which instance you were referring to?

On Sat, Mar 9, 2019 at 7:50 AM Bergi  wrote:

> Hi John,
>
> > I believe that it would be a trivial task for
> > current static code analyzers to restrict usage of "this" for anyone
> > opting in to use this new keyword exclusively.
>
> Static tooling, like the TypeScript compiler, can detect problematic
> method usage already today. Sure, having a dedicated syntax for this
> will make static analysis simpler, but I don't deem that a worthy
> addition to the language.
>
> > As you mentioned, arrow functions might have their own
> > problems. Wouldn't such an alternative keyword be a good addition to our
> > toolkit anyway?
>
> What I was trying to say is that your proposed alternative has exactly
> the same problems as instance-member arrow functions have today.
>
> 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


Re: Proposal: export ** from './FooBar'

2019-03-02 Thread Jordan Harband
https://github.com/tc39/ecma262/pull/1174 adds `export * as someName from
'path'`; https://github.com/tc39/proposal-export-default-from is the
proposal that you're looking for.

On Fri, Mar 1, 2019 at 6:48 AM Mike Samuel  wrote:

>
>
> On Fri, Mar 1, 2019 at 1:35 AM Cyril Auburtin 
> wrote:
>
>> Sometimes, (particularly in React codebases) you have to write many lines
>> like:
>> ```js
>> export { default as FooBar } from './FooBar';
>> ```
>> It could be automated of course
>>
>> It could also be tuned into
>> ```js
>> export * from './FooBar';
>> ```
>> only if FooBar is also a named export in that file, but usually files
>> with one export just use a default export
>>
>> --
>> This proposed syntax:
>> ```js
>> export ** from './FooBar';
>> ```
>> Would do:
>> ```js
>> export * from './FooBar';
>> export { default as FooBar } from './FooBar';
>> ```
>> the filename is used as default export name.
>>
>> If the filename isn't a valid JS identifier, like 'foo-bar' for example,
>> it would throw
>>
>
> ES doesn't impose many constraints on the string content of a module
> specifier but in practice it maps fairly directly to a URL per
> https://html.spec.whatwg.org/multipage/webappapis.html#hostgetimportmetaproperties
> so filename is probably broadly available.
>
> Would this use the filename from the module specifier or from the URL
> (assuming import.meta.url)?
> IIRC, only the module specifier is available within ES currently.
> The translation between specifiers and URLs (if that happens) is up to a
> host callback (HostResolveImportedModule) and does not surface inside the
> ES engine.
> That import.meta.url exists is up to another host callback so assuming
> it's existence might require constraining host implementations of
> HostGetMetaProperties(?).
>
> What would this do when import.meta.url/specifier has a query part, or
> that look like a non-hierarchical URL?
> export ** from "path?foo=bar";
> export ** from "?foo=bar";
> export ** from "data:application/javascript+module,export default
> null;"
>
> Does anyone know if existing CDNs use the path component for something
> other than the path contributed by the uploader and expect the original
> filename in the query, like
> host.cdn/path/to/tarball?p=path/within/tarball.js ?
>
>
>
>> ___
>> 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: switch expressions

2019-02-25 Thread Jordan Harband
Pattern Matching is still at stage 1; so there's not really any permanent
decisions that have been made - the repo theoretically should contain
rationales for decisions up to this point.

I can speak for myself (as "not a champion" of that proposal, just a fan)
that any similarity to the reviled and terrible `switch` is something I'll
be pushing back against - I want a replacement that lacks the footguns and
pitfalls of `switch`, and that is easily teachable and googleable as a
different, distinct thing.

On Mon, Feb 25, 2019 at 12:42 PM David Koblas  wrote:

> Jordan,
>
> One question that I have lingering from pattern matching is why is the
> syntax so different?  IMHO it is still a switch statement with a variation
> of the match on the case rather than a whole new construct.
>
> Is there somewhere I can find a bit of discussion about the history of the
> syntax decisions?
>
> --David
>
>
> On Feb 25, 2019, at 12:33 PM, Jordan Harband  wrote:
>
> Additionally, https://github.com/tc39/proposal-pattern-matching - switch
> statements are something I hope we'll soon be able to relegate to the
> dustbin of history.
>
> On Mon, Feb 25, 2019 at 6:01 AM David Koblas  wrote:
>
>> I quite aware that it’s covered in do expressions. Personally I find do
>> expressions non-JavaScript in style and it’s also not necessarily going to
>> make it into the language.
>>
>> Hence why I wanted to put out there the idea of switch expressions.
>>
>> --David
>>
>>
>> On Feb 25, 2019, at 5:28 AM, N. Oxer  wrote:
>>
>> Hi,
>>
>> This would be covered by do expressions
>> <https://github.com/tc39/proposal-do-expressions>. You could just do:
>>
>> ```js
>> const category = do {
>>   switch (...) {
>> ...
>>   };
>> };
>> ```
>>
>> On Sun, Feb 24, 2019 at 10:42 AM David Koblas  wrote:
>>
>>> After looking at a bunch of code in our system noted that there are many
>>> cases where our code base has a pattern similar to this:
>>>
>>>  let category = data.category;
>>>
>>>  if (category === undefined) {
>>>// Even if Tax is not enabled, we have defaults for incomeCode
>>>switch (session.merchant.settings.tax.incomeCode) {
>>>  case TaxIncomeCode.RENTS_14:
>>>category = PaymentCategory.RENT;
>>>break;
>>>  case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17:
>>>category = PaymentCategory.SERVICES;
>>>break;
>>>  case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17:
>>>category = PaymentCategory.SERVICES;
>>>break;
>>>}
>>>  }
>>>
>>> I also bumped into a block of go code that also implemented similar
>>> patterns, which really demonstrated to me that there while you could go
>>> crazy with triary nesting there should be a better way.  Looked at the
>>> pattern matching proposal and while could possibly help looked like it
>>> was overkill for the typical use case that I'm seeing. The most relevant
>>> example I noted was switch expressions from Java.  When applied to this
>>> problem really create a simple result:
>>>
>>>  const category = data.category || switch (setting.incomeCode) {
>>>case TaxIncomeCode.RENTS_14 => PaymentCategory.RENT;
>>>case TaxIncomeCode.ROYALTIES_COPYRIGHTS_12 =>
>>> PaymentCategory.ROYALTIES;
>>>case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17 =>
>>> PaymentCategory.SERVICES;
>>>default => PaymentCategory.OTHER;
>>>  }
>>>
>>> Note; the instead of using the '->' as Java, continue to use => and with
>>> the understanding that the right hand side is fundamentally function.
>>> So similar things to this are natural, note this proposal should remove
>>> "fall through" breaks and allow for multiple cases as such.
>>>
>>>  const quarter = switch (foo) {
>>>case "Jan", "Feb", "Mar" => "Q1";
>>>case "Apr", "May", "Jun" => "Q2";
>>>case "Jul", "Aug", "Sep" => "Q3";
>>>case "Oct", "Nov", "Dec" => { return "Q4" };
>>>default => { throw new Error("Invalid Month") };
>>>  }
>>>
>>> Also compared this to the 

Re: Function Overloading or Pattern Matching of functions in Ecma

2019-02-25 Thread Jordan Harband
That only allows you to switch on things that have a string representation;
object identity (more complex than the basic form that switch currently
allows) is a particularly common use case that the pattern matching
proposal addresses.

On Sun, Feb 24, 2019 at 2:36 PM kai zhu  wrote:

> if it helps, you can already "pattern-match" using string-concat like this
> full-working-demo [1]
> derived from a closed-source real-world example.
>
> ```html
> 
> *,
> *:after,
> *:before {
> box-sizing: border-box;
> }
> body { background: #eee; display: flex; flex-flow: column; font-family:
> Arial, Helvetica, sans-serif; margin: 0; padding: 10px;
> }
> body > div { background: #fff; border: 1px solid #ddd; margin-top: 10px;
> padding: 10px; }
> body > div:first-child { margin-top: 0; }
> #panelBody1 { border: 0; display: flex; flex: 1; padding: 0; }
> #panelBody1 > div { border: 1px solid #ddd; padding: 10px; }
> #panelBody1 > #borderResize1 { background: #fbb; border: 0; cursor:
> ew-resize; padding: 5px; }
> 
>
> 
> #header1 - drag
> red-bar
> between #panelSidebar1 and #panelSidebar2 to resize
> 
> 
> #panelSidebar1 (width: 0px)
> 
> #panelContent1 (width:
> 0px)
> 
> #footer1
>
> 
> /* jslint browser */
> (function () {
> "use strict";
> var local;
> local = {};
>
> // init event-handling - resize panel
> local.domOnEventDrag = function (event) {
> /*
>  * this function will handle  to drag-and-drop
>  */
> // "pattern-match" with string-concat
> switch (Boolean(local.domOnEventDragEvent) + "." + event.type) {
> case "false.mousedown":
> local.domOnEventDragEvent = event;
> return;
> case "true.mouseenter":
> case "true.mouseup":
> local.domOnEventDragEvent = null;
> return;
> case "true.mousemove":
> switch (local.domOnEventDragEvent.target.id) {
> case "borderResize1":
> event.preventDefault();
> event.stopPropagation();
> document.querySelector(
> "#panelContent1"
> ).style.width = "0";
> document.querySelector(
> "#panelSidebar1"
> ).style.width = event.x + "px";
> local.domOnEventWindowResize();
> // display resize-info
> document.querySelectorAll(
> "#panelContent1 span, #panelSidebar1 span"
> ).forEach(function (elem) {
> elem.textContent = elem.parentElement.offsetWidth;
> });
> return;
> }
> return;
> }
> };
> Array.from(document.querySelectorAll(
> "#borderResize1"
> )).forEach(function (elem) {
> elem.addEventListener("mousedown", local.domOnEventDrag);
> });
> document.addEventListener("mouseenter", local.domOnEventDrag);
> document.body.addEventListener("mousemove", local.domOnEventDrag);
> document.body.addEventListener("mouseup", local.domOnEventDrag);
>
> // init event-handling - resize window
> local.domOnEventWindowResize = function () {
> /*
>  * this function will handle  to resize window
>  */
> // resize body
> document.body.style.height = window.innerHeight + "px";
> // resize - #panelBody1 > div
> document.querySelectorAll(
> "#panelBody1 > div"
> ).forEach(function (elem) {
> elem.height = elem.parentElement.clienthHeight + "px";
> });
> // display resize-info
> document.querySelectorAll(
> "#panelContent1 span, #panelSidebar1 span"
> ).forEach(function (elem) {
> elem.textContent = elem.parentElement.offsetWidth;
> });
> };
> window.addEventListener("resize", local.domOnEventWindowResize);
> local.domOnEventWindowResize();
> }());
> 
> ```
>
> [1] using pattern-match to resize html-panels
> *https://codepen.io/kaizhu256/pen/rRBLLP
> *
>
>
>
> On 23 Oct 2018, at 03:57, Cyril Auburtin  wrote:
>
> I suggested it in
> https://github.com/tc39/proposal-pattern-matching/issues/48, I think zkat
> extended the proposal since with
> https://github.com/tc39/proposal-pattern-matching/blob/latest/TO_INFINITY_AND_BEYOND.md
>
> On Mon, Oct 22, 2018 at 10:35 PM Isiah Meadows 
> wrote:
>
>> You might want to check out the proposal's repo and make the suggestion
>> there (it's been considered already IIRC, and I believe it was already
>> noted in the repo as a possible future extension):
>> https://github.com/tc39/proposal-pattern-matching
>> On Mon, Oct 22, 2018 at 15:38 Matthew Robb 
>> wrote:
>>
>>> Perhaps the following form could eventually make sense for pattern
>>> matching in function declarations:
>>>
>>> ```js
>>> function sum_list(input, result = 0) case (input) {

Re: Proposal: switch expressions

2019-02-25 Thread Jordan Harband
Additionally, https://github.com/tc39/proposal-pattern-matching - switch
statements are something I hope we'll soon be able to relegate to the
dustbin of history.

On Mon, Feb 25, 2019 at 6:01 AM David Koblas  wrote:

> I quite aware that it’s covered in do expressions. Personally I find do
> expressions non-JavaScript in style and it’s also not necessarily going to
> make it into the language.
>
> Hence why I wanted to put out there the idea of switch expressions.
>
> --David
>
>
> On Feb 25, 2019, at 5:28 AM, N. Oxer  wrote:
>
> Hi,
>
> This would be covered by do expressions
> . You could just do:
>
> ```js
> const category = do {
>   switch (...) {
> ...
>   };
> };
> ```
>
> On Sun, Feb 24, 2019 at 10:42 AM David Koblas  wrote:
>
>> After looking at a bunch of code in our system noted that there are many
>> cases where our code base has a pattern similar to this:
>>
>>  let category = data.category;
>>
>>  if (category === undefined) {
>>// Even if Tax is not enabled, we have defaults for incomeCode
>>switch (session.merchant.settings.tax.incomeCode) {
>>  case TaxIncomeCode.RENTS_14:
>>category = PaymentCategory.RENT;
>>break;
>>  case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17:
>>category = PaymentCategory.SERVICES;
>>break;
>>  case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17:
>>category = PaymentCategory.SERVICES;
>>break;
>>}
>>  }
>>
>> I also bumped into a block of go code that also implemented similar
>> patterns, which really demonstrated to me that there while you could go
>> crazy with triary nesting there should be a better way.  Looked at the
>> pattern matching proposal and while could possibly help looked like it
>> was overkill for the typical use case that I'm seeing. The most relevant
>> example I noted was switch expressions from Java.  When applied to this
>> problem really create a simple result:
>>
>>  const category = data.category || switch (setting.incomeCode) {
>>case TaxIncomeCode.RENTS_14 => PaymentCategory.RENT;
>>case TaxIncomeCode.ROYALTIES_COPYRIGHTS_12 =>
>> PaymentCategory.ROYALTIES;
>>case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17 =>
>> PaymentCategory.SERVICES;
>>default => PaymentCategory.OTHER;
>>  }
>>
>> Note; the instead of using the '->' as Java, continue to use => and with
>> the understanding that the right hand side is fundamentally function.
>> So similar things to this are natural, note this proposal should remove
>> "fall through" breaks and allow for multiple cases as such.
>>
>>  const quarter = switch (foo) {
>>case "Jan", "Feb", "Mar" => "Q1";
>>case "Apr", "May", "Jun" => "Q2";
>>case "Jul", "Aug", "Sep" => "Q3";
>>case "Oct", "Nov", "Dec" => { return "Q4" };
>>default => { throw new Error("Invalid Month") };
>>  }
>>
>> Also compared this to the do expression proposal, it also provides a
>> substantial simplification, but in a way that is more consistent with
>> the existing language.  In one of their examples they provide an example
>> of the Redux reducer
>> https://redux.js.org/basics/reducers#splitting-reducers -- this would be
>> a switch expression implementation.
>>
>>  function todoApp(state = initialState, action) => switch
>> (action.type) {
>>case SET_VISIBILITY_FILTER => { ...state, visibilityFilter:
>> action.filter };
>>case ADD_TODO => {
>>...state, todos: [
>>  ...state.todos,
>>  {
>>text: action.text,
>>completed: false
>>  }
>>]
>>  };
>>case TOGGLE_TODO => {
>>...state,
>>todos: state.todos.map((todo, index) => (index ===
>> action.index) ? { ...todo, completed: !todo.completed } : todo)
>>  };
>>default => state;
>>  }
>>
>>
>>
>> ___
>> 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.isEmpty(value)`

2019-02-13 Thread Jordan Harband
`Reflect.ownKeys(x || {}).length === 0`?

On Wed, Feb 13, 2019 at 10:31 PM Isiah Meadows 
wrote:

> This would be roughly equivalent to `Object.keys(value).length === 0`,
> but with a few exceptions:
>
> 1. If `value` is either `null` or `undefined`, it gracefully falls
> back to `false` instead of throwing an error.
> 2. It takes enumerable symbols into account, like `Object.assign`.
>
> So more accurately, it returns `false`  if the value is neither `null`
> nor `undefined` and has an own, enumerable property, or `true`
> otherwise.
>
> It's something I sometimes use when dealing with object-based hash
> maps (like what you get from JSON, input attributes). I typically fall
> back to the (partially incorrect) `for ... in` with a `hasOwnProperty`
> check for string keys, but I'd like to see this as a built-in.
>
> There's also a performance benefit: engines could short-circuit this
> for almost everything with almost no type checks. It's also an obvious
> candidate to specialize for types.
>
> - If it's not a reference type (object or function), return `true`.
> - If it's not a proxy object, or a proxy object that doesn't define
> `getPropertyDescriptor` or `ownKeys`, it's often just a memory load,
> even with dictionary objects and arrays.
> - If it's a proxy object with `ownKeys` and/or
> `getOwnPropertyDescriptor`, this is the slow path, but you can still
> short-circuit when `ownKeys` returns an empty array.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
> ___
> 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: add stage4 constraint - ease-of-minification

2019-02-12 Thread Jordan Harband
So effectively, you're arguing that stagnant tools should hold back
evolution of the language, even when non-stagnant alternatives exist?

On Tue, Feb 12, 2019 at 3:26 PM kai zhu  wrote:

> > Can you expand on what you mean by this, or provide an example of a
> > feature that can't be "easily minified”?
>
> fat-arrow/destructuring/es6-classes comes to mind.  if you have legacy
> build-chain that doesn't use babel or terser, is it worth the effort to
> retool the minifier to support these syntaxes so you can use it?  also any
> feature which introduce new symbol/symbol-combo which requires re-auditing
> minifier's regexp-detection (private-fields, optional-chaining, etc.).
>
> there’s also the argument using babel in minification-toolchain defeats
> the purpose of reducing code-size.
>
> > On 12 Feb 2019, at 4:02 PM, Tab Atkins Jr.  wrote:
> >
> > On Tue, Feb 12, 2019 at 7:44 AM kai zhu  wrote:
> >> i think there’s an industry-painpoint (at least from my experience), of
> resistance adopting es6+ features because legacy-toolchains cannot be
> easily retooled to minify them.
> >>
> >> i’m not sure the best way to address this problem? i favor requiring 2
> independent minifiers to be able to handle a stage3-proposal before
> advancement (indicating retooling is feasible), but that may be
> overly-restrictive to some folks.
> >
> > Can you expand on what you mean by this, or provide an example of a
> > feature that can't be "easily minified"?
> >
> > ~TJ
>
> ___
> 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: A way to fire logic at the end of completion of the current class method (regardless of super call order).

2019-02-09 Thread Jordan Harband
If the superclass constructor has a way to run any code after subclass
constructors, then implementation details of the *subclasses* are then
leaked.

On Sat, Feb 9, 2019 at 2:15 AM Isiah Meadows  wrote:

> I've also had *several* scenarios where I could've used this
> personally. I feel ES classes are overly restrictive in preventing
> this, since it basically forces you to force subclasses to do
> something like `this.init()` right after the class is allocated,
> leaking implementation details left and right.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
> On Fri, Feb 8, 2019 at 1:22 AM #!/JoePea  wrote:
> >
> > I many times find myself in cases where a base class wants to ensure
> that logic is always fired after the current method's execution, so that
> for example no matter in which order sub classes call the `super` method,
> the `super` method can still guarantee that logic fires after the whole
> stack of the same method in the class hierarchy.
> >
> > So what I can do now is use `Promise.resolve().then(() => { ... })` to
> schedule that logic for later, that way all the invocations of a `foo`
> method along the class hierarchy have all fired. But this means that other
> code can also fire before the next microtask.
> >
> > Is there some way to do it? If not, I wonder if some language feature
> for doing it would be possible?
> >
> > - 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Introspect bind function targets

2019-02-04 Thread Jordan Harband
Given that you can also do `const c = (...args) => proto.call(null,
...args);`, and `Function.isSameTarget(a, c)` would presumably be `false`,
can you elaborate more on the use case for this?

On Mon, Feb 4, 2019 at 9:38 AM Sultan  wrote:

> A way to determine if two bound functions reference the same target
> function.
>
> For example:
>
> function proto () {}
>
> const a = proto.bind(null, 1)
> const b = proto.bind(null, 2)
>
> console.assert(Function.isSameTarget(a, b))
> ___
> 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: returning non-Promise values from async functions and running them synchronously (or Promise.sync() idea)

2019-02-03 Thread Jordan Harband
Typically, APIs that are sometimes sync and sometimes async are called
"z̲̗̼͙̥͚͛͑̏a̦̟̳͋̄̅ͬ̌͒͟ļ̟̉͌ͪ͌̃̚g͔͇̯̜ͬ̒́o̢̹ͧͥͪͬ" - unpredictable, hard to
maintain, hard to understand. The general best practice is that a function
should always be async, or always sync, but never the twain shall meet.

Relevant:  http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony

On Sun, Feb 3, 2019 at 4:49 PM Isiah Meadows  wrote:

> You could move the async part into a helper function and call that from a
> sync function you instead expose. I've used this trick more than once, and
> although it is a bit of boilerplate, it works well enough.
> On Sun, Feb 3, 2019 at 18:40 #!/JoePea  wrote:
>
>> I often find myself enjoying async functions until the time comes when I
>> don't want to await anything, and I want the call stack to be sync (i.e. I
>> don't want to defer if I don't have to).
>>
>> But, async functions always return a Promise. So I find my self
>> converting my async functions back into normal functions so that I can
>> return non-Promise values, this way the caller can wait only if I return a
>> promise, otherwise continue synchronously.
>>
>> Here's an example function in one of my classes:
>>
>> ```js
>> initWebGL() {
>> if (this.__glLoading) return false
>> this.__glLoading = true
>>
>> // order of the if-else matters!
>> if (this.__glUnloading) return
>> Promise.resolve().then(A.bind(this))
>> else if (this.__glLoaded) return false
>>
>> A.call(this)
>>
>> function A() {
>> // ... load stuff (omitted for brevity) ...
>> }
>>
>> return true
>> }
>> ```
>>
>> then the caller (f.e. a subclass) only needs to wait when a promise is
>> returned:
>>
>> ```js
>> initWebGL() {
>> const superResult = super.initWebGL()
>> if (superResult instanceof Promise) return
>> superResult.then(A.bind(this))
>> if (!superResult) return false
>>
>> A.call(this)
>>
>> function A() {
>> // ... subclass loads stuff (omitted for brevity) ...
>> }
>>
>> return true
>> }
>> ```
>>
>> This is just one example, but in general I find many cases where I want
>> to run synchronously most of the time, and only sometimes have to defer
>> (whether by choice or not).
>>
>> So I am losing out on the nice `await` syntax just because I can not do
>> what I want to do with `async`/`await`.
>>
>> What if async functions could have some way to continue synchronously,
>> and return non-Promise values?
>>
>> Or, what if we could have some sort of Promise API that would cause any
>> callers to synchronously away, like in the following example, so that the
>> change is not a breaking change, and async functions would still return
>> Promises but the Promise could perhaps continue synchronously:
>>
>> ```js
>> async function example() {
>>   return Promise.sync()
>> }
>> ```
>>
>> Then, in a caller, there would be no microtask deferral:
>>
>> ```js
>> async function test() {
>>   await example()
>>   console.log('one')
>>   // implicit return is a Promise.sync() here.
>> }
>>
>> function main() {
>>   test()
>>   console.log('two')
>> }
>> ```
>>
>> The output in this case would be:
>>
>> ```
>> "one"
>> "two"
>> ```
>>
>> Note that in that example, we are _sure_ that `two` is logged after `one`
>> because those async functions only ever use `Promise.sync()`.
>>
>> It would be good practice to use `await` regardless, because one may not
>> know if the async function they are calling will return a
>> non-`Promise.sync` value. So the `main` function is better written as
>>
>> ```js
>> async function main() {
>>   await test()
>>   console.log('two')
>> }
>> ```
>>
>> In this case, everything still happens synchronously, but if the author
>> of `example()` changes the implementation to return a non-sync Promise,
>> then things will still run in the expected order. F.e.
>>
>> ```js
>> async function example() {
>>   await fetch(...)
>> }
>> ```
>>
>> I keep finding scenarios where I want to avoid async unless I need async,
>> but then I lose the convenient async/await syntax.
>> ___
>> 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: idea: Array.prototype.remove

2019-02-03 Thread Jordan Harband
Why "remove" and not `.filter`, to produce a new array?

On Sun, Feb 3, 2019 at 9:56 PM #!/JoePea  wrote:

> I sometimes find myself doing things like
>
> ```js
> this.children.splice(this.children.indexOf(child), 1)
> ```
>
> but it seems that it will iterate the array twice. Maybe a new method can
> be introduced so engines can optimize it:
>
> ```js
> this.children.remove(child)
> // or
> this.children.remove(...childrenToRemove)
> ```
> ___
> 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: Named factory functions

2019-02-03 Thread Jordan Harband
I suspect that would break a ton of code - ES6 name inference already broke
some of mine, but I was able to work around it by using this kind of
indirection.

On Sun, Feb 3, 2019 at 11:02 AM Sultan  wrote:

> Where there any attempts to allow factory functions the ability to assume
> the name of the binding they are assigned to?
>
> Consider the following:
>
> function factory () { return function () {} }
> var foo = factory()
> console.assert(foo.name === 'foo')
> ___
> 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: Dash-case keys

2019-01-29 Thread Jordan Harband
There's a difference, though, between private field access - an entirely
distinct and new kind of thing - and normal property access, a
well-established and understood thing.

On Mon, Jan 28, 2019 at 11:53 PM Sultan Tarimo  wrote:

> This is expected and by design. For example obj[‘#invalidPrivateSigil’] is
> also not invalid. The affordances would be the same.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dash-case keys

2019-01-28 Thread Jordan Harband
i think if i can use something unquoted in an object literal, i'd expect to
be able to use it in dot access - ie, `obj.font-size` - and then that
problem arises.

On Mon, Jan 28, 2019 at 3:43 PM Sultan Tarimo  wrote:

> The former as the following is equally invalid syntax errors:
>
> const font = 1
> const size = 1
>
> const a = {
> font-size: 10
> }
> const b = {
> font+size: 10
> }
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dash-case keys

2019-01-28 Thread Jordan Harband
is that a key called "font-size" or the subtraction of `size` from `font`?

On Mon, Jan 28, 2019 at 1:48 PM Sultan  wrote:

> Is there any reason that dash-case keys are not supported in the object
> literal syntax.
>
> For example:
>
> const style = {
> font-size: 10
> }
>
> Compared to what one needs to do today:
>
> const style = {
> 'font-size': 10
> }
> ___
> 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-27 Thread Jordan Harband
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 UserCreator(userRepository);
>
> class UserSignupHandler {
>   constructor(userCreator) {
> // NOTE: at the consumer, it almost makes more sense to
> // name these with action verbs, as is done here.
> //
> this.createUser = userCreator;
>   }
>
>   handle(userName) {
> // UserSignupHandler is no longer coupled to the implementation
> details it doesn't need.
> //
> return this.createUser(userName);
>   }
> }
>
> const handler = new UserSignupHandler(userCreator);
> ```
>
> ___
> 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: Discussion: Module Reflection - import.reflect

2019-01-25 Thread Jordan Harband
In `import * as m from myModule`, `m.default` is already the default
export; `Object.keys(m)` is already the list of export names, and
`Object.entries(m).filter(([k, v]) => typeof v === 'function'))` is the
list of functions.

On Fri, Jan 25, 2019 at 5:27 AM Randy Buchholz 
wrote:

> Would it be worthwhile to add reflection to modules as a distinct feature?
>
>
>
> `import.meta.url` is a basic form of reflection, but it seems (?) `meta`
> is trying to be a fairly loose specification. Being able query a module can
> be helpful. For example, if I can see the static imports, I can
> conditionally do dynamic imports. Or (thinking out loud here), can
> “generic” modules be built where `default` is the generic?
>
>
>
> Some of the possibilities are
>
> `import.reflect.default` - returns `default` in its native form (function,
> class, value)
>
> `import.reflect.imports` - provides a list of static imports. Not sure
> what this should be (value or key-value (e.g., [importName, module]), but
> should be enumerable.
>
> `import.reflect.functions` - provides a list of exported functions. Can be
> use, for instance, to validate the shape of a module.
>
>
>
> This can be exposed to an importing module.
>
>
>
> ```
>
> // myModule has default export of `class xxx`
>
>
>
> Import * as m from myModule
>
> const instance = Reflect.construct(m.import.reflect.default, []);
>
>
>
> ```
>
>
> ___
> 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: enhanced case clause

2019-01-19 Thread Jordan Harband
Rather than investing more in switch statements,
https://github.com/tc39/proposal-pattern-matching may be more compelling :-)

On Sat, Jan 19, 2019 at 11:23 AM Sm In  wrote:

> *Before read: I'm not a native. so I may used some unnatural expression,
> or non-sense sentence. I feel so sorry for this. :(*
>
> ## preface
>
> currently, a switch statements's case claues compares equality between
> it's value and the switch statements's input value.
> just like this:
> ```js
> switch(x) {
>   case 1:
> console.log('x is 1');
> break;
>   case 2:
> console.log('x is 2');
> break;
>   default:
> console.log('x is not 1 and 2');
> }
> ```
>
> As I know, many books teaches people to use switch statement when there is
> many cases for one value.
> like above example.
>
> But, sadly, In many case include above one, the if statement is better
> than switch statement.
> the above example can be replaced by if statement like blow.
>
> ```js
> if (x === 1) {
>   console.log('x is 1');
> } else if (x === 2) {
>   console.log('x is 2');
> } else {
>   console.log('x is not 1 and 2');
> }
> ```
>
> code which uses if statement is shorter then switch statement, but we know
> **shorter code is not good at anytime**, I mean, sometimes, loger but more
> meaningful code is better then shorter one.
> So, about that simple example, some people would say "code which uses if
> statement is better" and other would say "no, code which uses switch
> statement is better".
> yes, this far, people could have different opionion about better example.
>
> but, let's check more complex example. what about checking value's
> properties?
> maybe it is number, "checking value's properties" can be cheacking is it
> integer or real number.
>
> I think code would be better then my english sentence. here is an example
> with if statement.
>
> ```js
> if (x % 1) {
>   console.log('x is real number');
> } else {
>   console.log('x is integer');
> }
> ```
>
> then, here is above example by switch statement.
> since switch statement compares equality between it's value and the case
> clause's input value.
>
> ```js
> switch(true) {
>   case x % 1 !== 0:
> console.log('x is real number');
> break;
>   default:
> console.log('x is integer');
> }
> ```
>
> yes, this code is dirty. also it containes redundant codes(which required
> by syntax, but in view of human(who reads code), something like `true` or
> `x` is useless one).
> So, I propose a new syntax for switch statement in order to reduce some 
> redundant
> codes from switch statement.
>
> ## new syntax for switch statement
>
> here is an example of the new syntax that works same as above example
>
> ```js
> switch(x) {
>   case % 1 !== 0:
> console.log('x is real number');
> break;
>   default:
> console.log('x is integer');
> }
> ```
>
> yes, this is it. more meaning then before.
>
> anyway, let me explain detailed sementic.
>
> when case clause's expression's most left operend is omitted, switch's
> input value(in above example, x is it) gose to that place(omitted operend
> place!)
>
> I will finish my email by showing one more example to you. thank you for
> reading this and have a nice day!
>
> ```js
> switch(x) {
>   case > 10:
> console.log('x is bigger then 10');
> break;
>   case > 5:
> console.log('x is bigger then 5, but smaller then 10');
> break;
>   case > 0:
> console.log('x is bigger then 0, but smaller then 5');
> break;
>   default:
> console.log('x is smaller then 0');
> }
> ```
> ___
> 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: [Symbol.equals]

2019-01-19 Thread Jordan Harband
As has been stated many times before, many JS developers have been hired to
do things entirely unrelated to UX workflows; regardless, whether you like
a specific coding style or not is *irrelevant* to discussing language
features, and is very disruptive to these discussions. Please confine that
to discussing style with your own team, or within a styleguide.

On Fri, Jan 18, 2019 at 11:08 PM kai zhu  wrote:

> > This thread would apply equally well to objects (there's no such thing
> as a "json object" - json is a string, and once it's parsed into an object
> it's not json anymore) as to classes.
>
> i’m not so sure when you start having classes with
> getters/setters/private-fields.  then people begin digging
> rabbit-holes/silos trying to solve low-level equality-issues that shouldn’t
> even exist, and overall lose focus of the big-picture UX-workflow problems
> most of us js-devs were originally hired to solve.
>
> On 18 Jan 2019, at 11:32 PM, Jordan Harband  wrote:
>
> This thread would apply equally well to objects (there's no such thing as
> a "json object" - json is a string, and once it's parsed into an object
> it's not json anymore) as to classes.
>
> Please stop derailing threads with your off-topic ideology about how to
> write code - that belongs in a style guide, or in your own project, but not
> here.
>
> On Fri, Jan 18, 2019 at 9:28 PM kai zhu  wrote:
>
>> the most reliable/idiot-proof equality is by avoiding classes altogether;
>> stick with plain json-objects and compare their
>> canonical-json-representation like this real-world example [1]:
>>
>> ```
>> /*jslint devel*/
>> (function () {
>> "use strict";
>> var jsonStringifyCanonical;
>>
>> jsonStringifyCanonical = function (obj, replacer, space) {
>> /*
>>  * this function will JSON.stringify ,
>>  * with object-keys sorted and circular-references removed
>>  */
>> var circularSet;
>> var stringify;
>> var tmp;
>> stringify = function (obj) {
>> /*
>>  * this function will recursively JSON.stringify obj,
>>  * with object-keys sorted and circular-references removed
>>  */
>> // if obj is not an object or function,
>> // then JSON.stringify as normal
>> if (!(
>> obj
>> && typeof obj === "object"
>> && typeof obj.toJSON !== "function"
>> )) {
>> return JSON.stringify(obj);
>> }
>> // ignore circular-reference
>> if (circularSet.has(obj)) {
>> return;
>> }
>> circularSet.add(obj);
>> // if obj is an array, then recurse its items
>> if (Array.isArray(obj)) {
>> tmp = "[" + obj.map(function (obj) {
>> // recurse
>> tmp = stringify(obj);
>> return (
>> typeof tmp === "string"
>> ? tmp
>> : "null"
>> );
>> }).join(",") + "]";
>> circularSet.delete(obj);
>> return tmp;
>> }
>> // if obj is not an array,
>> // then recurse its items with object-keys sorted
>> tmp = "{" + Object.keys(obj).sort().map(function (key) {
>> // recurse
>> tmp = stringify(obj[key]);
>> if (typeof tmp === "string") {
>> return JSON.stringify(key) + ":" + tmp;
>> }
>> }).filter(function (obj) {
>> return typeof obj === "string";
>> }).join(",") + "}";
>> circularSet.delete(obj);
>> return tmp;
>> };
>> circularSet = new Set();
>> return JSON.stringify((
>> (typeof obj === "object" && obj)
>> // recurse
>> ? JSON.parse(stringify(obj))
>> : obj
>> ), replacer, space);
>> };
>>
>> // true
>> console.assert(
>> // {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}}
>> jsonSt

Re: Proposal: [Symbol.equals]

2019-01-18 Thread Jordan Harband
This thread would apply equally well to objects (there's no such thing as a
"json object" - json is a string, and once it's parsed into an object it's
not json anymore) as to classes.

Please stop derailing threads with your off-topic ideology about how to
write code - that belongs in a style guide, or in your own project, but not
here.

On Fri, Jan 18, 2019 at 9:28 PM kai zhu  wrote:

> the most reliable/idiot-proof equality is by avoiding classes altogether;
> stick with plain json-objects and compare their
> canonical-json-representation like this real-world example [1]:
>
> ```
> /*jslint devel*/
> (function () {
> "use strict";
> var jsonStringifyCanonical;
>
> jsonStringifyCanonical = function (obj, replacer, space) {
> /*
>  * this function will JSON.stringify ,
>  * with object-keys sorted and circular-references removed
>  */
> var circularSet;
> var stringify;
> var tmp;
> stringify = function (obj) {
> /*
>  * this function will recursively JSON.stringify obj,
>  * with object-keys sorted and circular-references removed
>  */
> // if obj is not an object or function,
> // then JSON.stringify as normal
> if (!(
> obj
> && typeof obj === "object"
> && typeof obj.toJSON !== "function"
> )) {
> return JSON.stringify(obj);
> }
> // ignore circular-reference
> if (circularSet.has(obj)) {
> return;
> }
> circularSet.add(obj);
> // if obj is an array, then recurse its items
> if (Array.isArray(obj)) {
> tmp = "[" + obj.map(function (obj) {
> // recurse
> tmp = stringify(obj);
> return (
> typeof tmp === "string"
> ? tmp
> : "null"
> );
> }).join(",") + "]";
> circularSet.delete(obj);
> return tmp;
> }
> // if obj is not an array,
> // then recurse its items with object-keys sorted
> tmp = "{" + Object.keys(obj).sort().map(function (key) {
> // recurse
> tmp = stringify(obj[key]);
> if (typeof tmp === "string") {
> return JSON.stringify(key) + ":" + tmp;
> }
> }).filter(function (obj) {
> return typeof obj === "string";
> }).join(",") + "}";
> circularSet.delete(obj);
> return tmp;
> };
> circularSet = new Set();
> return JSON.stringify((
> (typeof obj === "object" && obj)
> // recurse
> ? JSON.parse(stringify(obj))
> : obj
> ), replacer, space);
> };
>
> // true
> console.assert(
> // {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}}
> jsonStringifyCanonical({
> data: {x: 1, y: 2, z: 3},
> meta: {label: "point #32"}
> })
> // === {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}}
> === jsonStringifyCanonical({
> meta: {label: "point #32"},
> data: {z: 3, y: 2, x: 1}
> })
> );
> }());
> ```
>
>
> [1] testing aa “==“ b by comparing their canonical json-representation
> https://github.com/kaizhu256/node-utility2/blob/2018.12.30/test.js#L2903
>
> https://github.com/kaizhu256/node-utility2/blob/2018.12.30/lib.utility2.js#L2760
>
>
> On 18 Jan 2019, at 3:39 PM, Isiah Meadows  wrote:
>
> Yeah, I agree. I'd suggest overloading `==`, but that'd risk serious web
> compat issues, especially if `null`/`undefined` aren't special-cased. I
> feel an `equals` instance method added to all builtins and an
> `Object.equals` attempting that method first before performing a shallow
> object comparison would be the best solution.
> On Fri, Jan 18, 2019 at 15:24 Jordan Harband  wrote:
>
>> It's pretty important that the meaning `===` not be able to change.
>>
>> On Fri, Jan 18, 2019 at 10:33 AM ViliusCreator <
>> viliuskubilius...@gmail.

Re: Proposal: [Symbol.equals]

2019-01-18 Thread Jordan Harband
It's pretty important that the meaning `===` not be able to change.

On Fri, Jan 18, 2019 at 10:33 AM ViliusCreator 
wrote:

> What about having Symbol.equals?
>
> For example, for now this is what it does:
>
> ```js
>
> class Position {
> constructor(o) {
> this.x = o.x instanceof Number ? o.x : 0
>
> this.y = o.y instanceof Number ? o.y : 0
>
> this.z = o.z instanceof Number ? o.z : 0
> }
> }
> console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10,
> y: 10, z: 10})
>
> ```
> Output is of course, false.
> With `Symbol.equals`, we could make it easier, instead of
> `instance.equals(otherInstance)`.
>
>
>
> For example:
>
> ```js
>
> class Position {
>
> [Symbol.equals](oIn) {
> return oIn.x === this.x && oIn.y === this.y && oIn.z === this.z
> }
> constructor(o) {
> this.x = o.x instanceof Number ? o.x : 0
>
> this.y = o.y instanceof Number ? o.y : 0
>
> this.z = o.z instanceof Number ? o.z : 0
> }
> }
> console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10,
> y: 10, z: 10})
>
> ```
> Now output would be true.
>
> This would save most of the time, instead of writing .equals and then
> surrounding everything with ().
>
>
> 
>  Virus-free.
> www.avast.com
> 
> <#m_4203195586323233386_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: De-structuring array arguments

2019-01-17 Thread Jordan Harband
I'm not sure what you mean, that should certainly be possible today. In
node, I get this:
```

function foo ([a, b] = [1, 2]) { return [a, b]; }

foo([2, 3]) // [2, 3]

foo() // [1, 2]

```

On Thu, Jan 17, 2019 at 9:50 AM Sultan  wrote:

> Consider the following is not possible today:
>
> function foo ([a, b] = [1, 2]) {}
>
> foo([2, 3])
>
> While the the following is outside of function arguments:
>
> const arr = [1, 2]
> const [a, b] = arr
>
> Is there any reason for the current status quo?
>
> ___
> 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: Symbol Linked to `typeof`

2019-01-16 Thread Jordan Harband
https://github.com/michaelficarra/proposal-first-class-protocols may be
relevant.

On Wed, Jan 16, 2019 at 9:06 AM Augusto Moura 
wrote:

> I don't think string namespaced names are the right feature here
>
> Namespaces are intended mainly to avoid conflicts with names when
> sharing a global scope (like when using classpath in Java, or libs in
> C++)
> Javascript already solves this problems with modules, you can always
> guard your code with instanceof and the right instance of your class,
> you don't need "qualified names"
> ``` js
> // flow.js
> export class Flow {
> }
> ```
> ``` js
> // main.js
> import { Flow } from './flow.js'; // we don't need namespaces, a "file
> path" already resolves conflicts for us
>
> const doSomething = (obj)  => {
>   if (obj instanceof Flow) {
> // ...
>   }
> }
> ```
>
> You can also customize the instanceof operation with `Symbol.hasInstance`
> ``` js
> class Flow {
>   // Normally you would check the minimum contract required to any guard
> work
>   // Probably bad idea to override in most of the cases
>   static [Symbol.hasInstance](obj) {
> return '_flow' in obj;
>   }
> }
>
> // Note that the control is inverse to your proposal the Class
> determines if a value is instance (this why it's static)
> // Without altering `Flow[Symbol.hasInstance]` just expected objects
> will pass the check in `doSomething`
> doSomething({}); // doesn't work
> doSomething({ __proto__: Flow.prototype }); // doesn't work
> doSomething({ _flow: undefined }); // actually works
> ```
>
> ~string qualified names are so 20th century~
>
>
> Em qua, 16 de jan de 2019 às 01:48, Randy Buchholz
>  escreveu:
> >
> > Right. Misappropriating a symbol corrupts its intent. As ES moves in a
> more towards a more “class-ish” feel, and people start writing more
> classes, a type/namespace system isn’t far behind. Implementing some
> symbols to support this helps drive some standard approaches and
> discourages symbol misappropriation.
> >
> >
> >
> > ___
> > 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Proposal: Class Templates

2019-01-16 Thread Jordan Harband
https://github.com/michaelficarra/proposal-first-class-protocols may be a
more palatable approach here.

On Wed, Jan 16, 2019 at 9:41 AM ViliusCreator 
wrote:

> Also, using `new (Abc(4, 5, 6))(1, 2, 3)` causes error ` Uncaught
> TypeError: Abc(...) is not a constructor`.
>
>
>
>
> 
>  Virus-free.
> www.avast.com
> 
> <#m_-2762429988630184872_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: Proposal: Named de-structuring arguments.

2019-01-16 Thread Jordan Harband
See https://github.com/zkat/proposal-as-patterns

On Wed, Jan 16, 2019 at 12:24 AM Sultan  wrote:

> The ability to both name and de-structure an argument.
>
> Relying on the spread operator does not archive the same effect
> considering that the spread operator "by design" has some short-comings
> related to exotic objects when the objects in question have a rich
> prototype you want to preserve.
>
> Consider the following proposal:
>
> function fn (arg pick {a, b = arg.b = 'value'}) {}
>
> This would allow four fundamental things of note missing from current
> de-structuring status-quo:
>
> 1. The ability to have both named arguments and de-structuring.
>
> 2. The ability to reference the named argument within the de-structure.
> This allows the above pattern of setting a default value on the passed
> argument when it doesn't exist.
>
> 3. This in turn also affords you the ability to de-structure while also
> preserving the exotic nature of an object when it is not a POJO object.
>
> That is when "arg" is an exotic use-defined object using the spread
> operator "{...arg}" will discard its prototype.
>
> For example:
>
> function a ({a, ...b}) { return b }
>
> a([1, 2])
>
> Returns a object with index-able keys instead of the array.
>
> 4. Consequently this addition would also afford the avoidance of any
> overhead that one might want to avoid with the rest spread operation: {a,
> b, ...arg} in hot paths.
> ___
> 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: Symbol Linked to `typeof`

2019-01-15 Thread Jordan Harband
Symbol.toStringTag can be used for this purpose now (and it already
unfortunately destroyed the reliability of
`Object.prototype.toString.call`).

On Tue, Jan 15, 2019 at 3:07 PM Randy Buchholz 
wrote:

> My thought was Symbol.typeof could improve both reliability and
> flexibility. It could be abused, but no more than Symbol.toStringTag. My
> use case is putting classes into “namespaces”. With [Symbol.typeof] =
> “Collections.Lists.LinkedList”, I can get the qualified type of the object.
> I can also use this in my IDE to keep my classes organized if I write tools
> to help me. Since imports use paths, if I move a file refactoring can be
> painful. With an IDE extension, I can trigger an event when I move a file
> to prompt “Update all imports?”. It can parse my project and update all
> imports to point to the right place.
>
>
>
> *From:* es-discuss  * On Behalf Of *Jordan
> Harband
> *Sent:* Tuesday, January 15, 2019 3:36 PM
> *To:* J Decker 
> *Cc:* es-discuss@mozilla.org
> *Subject:* Re: Proposal: Symbol Linked to `typeof`
>
>
>
> `.constructor` is unreliable, and can be easily forged - of course,
> `Symbol.typeof` would create the same unreliability with one of the few
> truly reliable operators in the language.
>
>
>
> On Tue, Jan 15, 2019 at 12:38 PM J Decker  wrote:
>
>
>
>
>
> On Sat, Jan 12, 2019 at 8:19 AM Randy Buchholz 
> wrote:
>
> (Hi all, new to group)
>
>
>
> Some of the Well Known Symbols are linked to standard functions –
>  Symbol.toStringTag - A string value used for the default description of an
> object. Used by Object.prototype.toString().
>
>
>
> When I have a Class instance (say, `const flow = new Flow()`, the
> debugger shows `flow = Flow {`.
>
> But when I do `console.log( typeof flow)` the output is `object`.
>
>
>
> I assume changing basic behavior `typeof` would be breaking, but extending
> it through a symbol would be useful.
>
>
>
> `Symbol.typeofTag` of just `Symbol.typeof`
>
>
>
> Invoking `typeof` on an object with this symbol would return “user-typed”
> information.
>
>
>
>
>
> can't you just use the constructor name when needing more detail?
>
>
>
> var a = new Date();
>
> a.constructor.name
>
> "Date"
>
>
>
>
>
> (Posting Question)
>
> What is the preferred format/approach for highlighting code in posts?
>
> 
>
> Possible Approaches
>
> ```
>
> class Flow {
>
> get [Symbol.typeof]() { return Flow; }  or { return “Flow” }
>
> }
>
> ```
>
> would work much like Symbol.species.  Implicitly casting to string would
> be more intuitive I think.
>
>
>
> Other approaches, (special handling of well-knowns) could be:
>
>
>
> Decorator-ish
>
> ```
>
> [Symbol.typeof] = “Flow”
>
> Class Flow {…
>
> ```
>
> or inferred
>
>
>
> ```
>
> [Symbol.typeof]
>
> class Flow {…
>
> ```
>
>
>
> Internal – In class, but not in a function.
>
>
>
> ```
>
> Class Flow {
>
> [Symbol.typeof]
>
> or
>
> [Symbol.typeof] = “Flow”
>
> or
>
> [Symbol.typeof] = Flow
>
> or
>
> [Symbol.typeof] = this
>
>
>
> ```
>
>
>
> Constructor
>
> ```
>
> Class Flow {
>
>Constructor() {
>
>   this[Symbol.typeof] = …
>
>   …
>
> ```
>
>
>
> ___
> 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: Symbol Linked to `typeof`

2019-01-15 Thread Jordan Harband
`.constructor` is unreliable, and can be easily forged - of course,
`Symbol.typeof` would create the same unreliability with one of the few
truly reliable operators in the language.

On Tue, Jan 15, 2019 at 12:38 PM J Decker  wrote:

>
>
> On Sat, Jan 12, 2019 at 8:19 AM Randy Buchholz 
> wrote:
>
>> (Hi all, new to group)
>>
>>
>>
>> Some of the Well Known Symbols are linked to standard functions –
>>  Symbol.toStringTag - A string value used for the default description of an
>> object. Used by Object.prototype.toString().
>>
>>
>>
>> When I have a Class instance (say, `const flow = new Flow()`, the
>> debugger shows `flow = Flow {`.
>>
>> But when I do `console.log( typeof flow)` the output is `object`.
>>
>>
>>
>> I assume changing basic behavior `typeof` would be breaking, but
>> extending it through a symbol would be useful.
>>
>>
>>
>> `Symbol.typeofTag` of just `Symbol.typeof`
>>
>>
>>
>> Invoking `typeof` on an object with this symbol would return “user-typed”
>> information.
>>
>>
>>
>
> can't you just use the constructor name when needing more detail?
>
> var a = new Date();
> a.constructor.name
> "Date"
>
>
>
>> (Posting Question)
>>
>> What is the preferred format/approach for highlighting code in posts?
>>
>> 
>>
>> Possible Approaches
>>
>> ```
>>
>> class Flow {
>>
>> get [Symbol.typeof]() { return Flow; }  or { return “Flow” }
>>
>> }
>>
>> ```
>>
>> would work much like Symbol.species.  Implicitly casting to string would
>> be more intuitive I think.
>>
>>
>>
>> Other approaches, (special handling of well-knowns) could be:
>>
>>
>>
>> Decorator-ish
>>
>> ```
>>
>> [Symbol.typeof] = “Flow”
>>
>> Class Flow {…
>>
>> ```
>>
>> or inferred
>>
>>
>>
>> ```
>>
>> [Symbol.typeof]
>>
>> class Flow {…
>>
>> ```
>>
>>
>>
>> Internal – In class, but not in a function.
>>
>>
>>
>> ```
>>
>> Class Flow {
>>
>> [Symbol.typeof]
>>
>> or
>>
>> [Symbol.typeof] = “Flow”
>>
>> or
>>
>> [Symbol.typeof] = Flow
>>
>> or
>>
>> [Symbol.typeof] = this
>>
>>
>>
>> ```
>>
>>
>>
>> Constructor
>>
>> ```
>>
>> Class Flow {
>>
>>Constructor() {
>>
>>   this[Symbol.typeof] = …
>>
>>   …
>>
>> ```
>>
>>
>> ___
>> 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: Bind function without thisArg

2019-01-13 Thread Jordan Harband
```
var foo = function(a) { console.assert(this === obj) };
var obj = { foo() { return foo.apply(this, arguments); } };
```
?

On Sun, Jan 13, 2019 at 10:01 PM 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
>
___
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 Jordan Harband
"who calls function B" has, and must have, no bearing on how function B
behaves. Every single call site that passes identical (`Object.is`)
arguments must behave the same. Am I misunderstanding what you mean?

On Sun, Jan 13, 2019 at 9:50 PM 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Array.create and Function.create

2019-01-11 Thread Jordan Harband
You can already do that - `function f() {} Object.setPrototypeOf(f,
customObject)`

On Thu, Jan 10, 2019 at 4:18 PM Matthew Robb  wrote:

> Fwiw I'd absolutely love a way to create function objects that inherit
> from an existing custom object.
>
> On Thu, Jan 10, 2019, 2:13 PM Sultan 
>> >what're the benefits over a object indexed by numbers `const o =
>> Object.create(null); o[0] = 12; ...`?
>>
>> Better "optimisable" heuristics in a similar vain to `TypedArrays`. Most
>> engines have perf cliffs with indexed objects after a certain threshold,
>>
>> Memory: at some point indexed objects have to grow by some factor(* N of
>> the current size) until it reaches and exceeds your desired size resulting
>> in more memory use that you bargained for or at some point the engine could
>> downgrade it to dictionary-mode for any one reason.
>>
>> It is a fickle round to cross when you want predictable throughput
>> performance, TypedArrays afford this, but they are not generic(support any
>> value).
>>
>> >About the other function proposal (`Function.create`) I don't see any
>> benefits in day to day use having a function without prototype
>>
>> Both the Array.create and Function.create are not meant as day-to-day
>> data-structures.
>> They are meant as low-level building blocks for abstraction that might be
>> used on a day-to-day, abstractions that wish to guarantee better
>> predictable performance.
>>
>> >and there'd be no way to get the length or iterate over it if you did.
>>
>> You don't need a length property to iterate the array if you own and
>> manage the data-strucure:
>>
>> Exhibit A:
>> var len = 10
>> var arr = Array.create(null, len)
>> for (var i = 0; i < len; i++) arr[i]
>>
>> Exhibit B: (tuple)
>>
>> var arr = Array.create(null, 2)
>> arr[0] = 'a'
>> arr[1] = 'b'
>> return a
>>
>> In both examples you don't need a length property to access/visit all the
>> elements in the array given they are both statically known at creation time.
>>
>>
>> On Fri, Jan 11, 2019 at 12:20 AM Jordan Harband  wrote:
>>
>>> Sorry if I was unclear; it's *impossible* to have an array without a
>>> `.length` own property, and there'd be no way to get the length or iterate
>>> over it if you did. I'm also not clear on why you'd want to store named
>>> properties on an array, especially if you can't iterate it because it
>>> doesn't have a length?
>>>
>>> On Thu, Jan 10, 2019 at 11:04 AM T.J. Crowder <
>>> tj.crow...@farsightsoftware.com> wrote:
>>>
>>>> On Thu, Jan 10, 2019 at 1:54 PM Augusto Moura
>>>>  wrote:
>>>> >
>>>> > If you don't want the iterable features neither the own properties,
>>>> > what're the benefits over a object indexed by numbers `const o =
>>>> > Object.create(null); o[0] = 12; ...`?
>>>>
>>>> Exactly.
>>>>
>>>> And re functions, using them as state containers without their usual
>>>> features seems like a bad idea^H^H^H^H^H^H^H^H edge case best handled
>>>> by `setPrototypeOf` and `delete`. :-)
>>>>
>>>> -- T.J. Crowder
>>>> ___
>>>> es-discuss mailing list
>>>> es-discuss@mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>> ___
>>> es-discuss mailing list
>>> es-discuss@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Array.create and Function.create

2019-01-10 Thread Jordan Harband
Sorry if I was unclear; it's *impossible* to have an array without a
`.length` own property, and there'd be no way to get the length or iterate
over it if you did. I'm also not clear on why you'd want to store named
properties on an array, especially if you can't iterate it because it
doesn't have a length?

On Thu, Jan 10, 2019 at 11:04 AM T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Thu, Jan 10, 2019 at 1:54 PM Augusto Moura
>  wrote:
> >
> > If you don't want the iterable features neither the own properties,
> > what're the benefits over a object indexed by numbers `const o =
> > Object.create(null); o[0] = 12; ...`?
>
> Exactly.
>
> And re functions, using them as state containers without their usual
> features seems like a bad idea^H^H^H^H^H^H^H^H edge case best handled
> by `setPrototypeOf` and `delete`. :-)
>
> -- 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: Array.create and Function.create

2019-01-10 Thread Jordan Harband
Why would this be better than `const a = []; Object.setPrototypeOf(a,
null)`?

On Thu, Jan 10, 2019 at 12:09 AM Sultan  wrote:

> >An array with no prototype wouldn't have any of the iteration methods on
> it...
>
> Yes, that is what is intended with this, similar to an Object.create(null)
> object with number-ed keys.
>
> Alternatively one could look at the objects created from this to be the
> "bare-bones" structure around these data-structures.
>
> That is the in-existence of prototypes and own properties like "length"
> makes it clear that these "flat" objects are intended as author managed
> objects.
>
> There are is no visible default prototype or own properties because the
> author will create, expose and managed these for the data-structure
> explicitly if need be or more commonly choose to not expose the
> data-structure at all and use these for low-level internal book keeping for
> other abstractions.
>
> This would create a new ceiling(or ground-level) for how "low-level" one
> could go with JavaScript if these where part for the language and as a
> secondary consequence allow engines to make stronger assumptions with
> regards to operations on these structs.
>
> On Thu, Jan 10, 2019 at 9:48 AM Jordan Harband  wrote:
>
>> An array with no prototype wouldn't have any of the iteration methods on
>> it; a function with no prototype wouldn't have .call/.bind/.apply - length
>> and name are own properties of functions, and length is an own property of
>> an array, so you'd get those regardless.
>>
>> (`Array.from({ length: 1000 })` already creates an array of length 1000
>> without holes, fwiw)
>>
>> On Wed, Jan 9, 2019 at 10:43 PM Sultan  wrote:
>>
>>> Identical to Object.create but for Arrays and Functions.
>>>
>>> This method will allow you to create arrays with no prototype.
>>>
>>> This would allow authors the ability to use array objects as state
>>> containers without the need to resort to index-based objects with
>>>
>>> Object.create(null, length)
>>>
>>> When you want to both use an array-like struct as both a property and
>>> index-able map.
>>>
>>> A side-effect of this would afford engines a strong heuristic for
>>> avoiding holey-array look-ups operations when there's no prototype to walk.
>>>
>>> For example the following would create an array with a length of 1000
>>> without "holes".
>>>
>>> const arr = Array.create(null, 1000)
>>>
>>> In addition this could also apply to functions with
>>>
>>> Function.create(null, () => {})
>>>
>>> When you want to use functions as state-containers but don't want any of
>>> the implicit properties(length, name) etc.
>>> ___
>>> 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: Array.create and Function.create

2019-01-09 Thread Jordan Harband
An array with no prototype wouldn't have any of the iteration methods on
it; a function with no prototype wouldn't have .call/.bind/.apply - length
and name are own properties of functions, and length is an own property of
an array, so you'd get those regardless.

(`Array.from({ length: 1000 })` already creates an array of length 1000
without holes, fwiw)

On Wed, Jan 9, 2019 at 10:43 PM Sultan  wrote:

> Identical to Object.create but for Arrays and Functions.
>
> This method will allow you to create arrays with no prototype.
>
> This would allow authors the ability to use array objects as state
> containers without the need to resort to index-based objects with
>
> Object.create(null, length)
>
> When you want to both use an array-like struct as both a property and
> index-able map.
>
> A side-effect of this would afford engines a strong heuristic for avoiding
> holey-array look-ups operations when there's no prototype to walk.
>
> For example the following would create an array with a length of 1000
> without "holes".
>
> const arr = Array.create(null, 1000)
>
> In addition this could also apply to functions with
>
> Function.create(null, () => {})
>
> When you want to use functions as state-containers but don't want any of
> the implicit properties(length, name) etc.
> ___
> 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: How to prettify output of objects in the console, when using get/set, like browsers do?

2019-01-09 Thread Jordan Harband
`console` isn't part of the language; node and browsers have their own
implementations (which is likely covered by an HTML spec), so you'd want to
look into it there.

node's `util.inspect`, for example, provides a `util.inspect.custom` symbol
that's invoked to get a custom string version of the object:
https://nodejs.org/api/util.html#util_util_inspect_custom

On Wed, Jan 9, 2019 at 1:32 PM #!/JoePea  wrote:

> Here's some nice output in the console in Chrome, for `DOMPoint` and
> `DOMPointReadOnly` classes:
>
> ```js
> const point = new DOMPoint(1,2,3,4)
> console.log(point)
> ```
>
> output:
>
> ```
> > DOMPoint {x: 1, y: 2, z: 3, w: 4}
> ```
>
> ([codepen example](https://codepen.io/anon/pen/xmaVej), open the devtools
> console then re-run the example to see the "nice" output)
>
> However if I use the my polyfill [here](
> https://github.com/trusktr/geometry-interfaces/blob/master/src/DOMPoint.js),
> then the output is not as helpful:
>
> ```js
> const point = new DOMPoint(1,2,3,4) // uses polyfill
> console.log(point)
> ```
>
> output (notice, it does not show the x,y,z,w values):
>
> ```
> > DOMPoint {}
> ```
>
> ([codepen example](https://codepen.io/anon/pen/QzVNeE), open the devtools
> console then re-run the example to see the expected output)
>
> When I expand the object in the console, I can see the getters, marked
> with `(...)`, and I can click on them to trigger them, but the output is
> limited and does not show the x,y,z,w values like the native one does.
>
> Is it possible to make the output nice with the polyfill? Or does the
> engine have internal mechanisms that we don't get to use in plain
> JavaScript?
> ___
> 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: Add `NoSubstitutionTemplate` to `StringLiteral` Definition

2019-01-09 Thread Jordan Harband
import path specifiers are another.

On Wed, Jan 9, 2019 at 10:16 AM T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Wed, Jan 9, 2019 at 5:36 PM FERREIRA, ERIC B
>  wrote:
> > I contend that adding `NoSubstitutionTemplate`s to the definition of
> > `StringLiteral` will bring the benefit of allowing teams to
> > completely opt to use only template strings instead of mixing quote
> > marks, while having very little risk or downside, if any at all.
>
> I've been toying with defaulting to template literals for some time. :-)
>
> Interesting idea. Where specifically do you see benefits of this
> change? The only places that immediately jump out to me are
>
> * "use strict", mentioned in your linked article
> * Quoted property names in object initializers (aka "object literals")
> -- oddly not mentioned in that article (it mentions JSON, but not
> object initializers)
>
> That second one could be a bit of a footgun for people, who may trip
> over this working:
>
> ```js
> const obj = {`I have a space`: `bar`};
> ```
>
> ...but this failing:
>
> ```js
> const obj = {`I have a space ${x}`: `bar`};
> ```
>
> ...because that's not a NoSubstitutionTemplate and so it needs to be a
> computed property name.
>
> Are there other places?
>
> -- 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: Array.prototype.count

2019-01-07 Thread Jordan Harband
All the iteration methods are a specific case of reduce, in that you can
implement them all with reduce.

On Mon, Jan 7, 2019 at 11:27 AM Ranando King  wrote:

> 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Fixed-length untyped arrays

2018-12-21 Thread Jordan Harband
Is there any evidence that existing arrays *prevent* engines from making
optimizations? I believe (and any implementors, please correct me if I'm
wrong) that the most common approach is to guess the likely maximum size
for the array, double it, and then allocate that much memory - and thus all
the array methods can remain optimized until the memory size needs to
double again.

On Fri, Dec 21, 2018 at 6:52 PM Isiah Meadows 
wrote:

> Usually, the native resizable array is good enough. But sometimes, you
> don't want to resize it, just allocate a slab of memory for objects.
> Typed arrays already implement this for integers, but I find it quite
> often in certain applications that I want to do this for arbitrary
> objects, too. So how about a `FixedArray` analogue to `TypedArray`
> that implements most the same stuff `TypedArray` does, just without
> the binary data integration or numeric coercion?
>
> There's a few other benefits to having a native fixed-size untyped array:
>
> 1. Engines can make major assumptions about allocation and use that to
> improve performance and minimize allocations - notably, they can
> choose to allocate the array's entries in the object itself, since it
> can't change for the lifetime of that object. This is the norm in some
> languages, like Rust.
> 2. Engines can optimize things like `.map`, `.filter`, `.concat`, and
> similar far more easily. Those don't have to be generic, and since
> they can assume everything's contiguous, it's much easier to
> implement.
> 3. Engines can make guarantees about allocation size, and that's the
> whole point of this proposal. These objects only require a minimum of
> type info, GC info, its length, and `length` number of machine
> pointers.
>
> Of course, yes, normal arrays *could* provide most of these, but
> consider how V8 internally uses an `InternalArray` extensively to
> implement many JS built-ins in JS and its CodeStubAssembler DSL. It's
> also worth noting V8 didn't start inlining `Array.prototype.map` and
> friends for dense arrays until it figured out how to bail out of a
> JIT-compiled loop from within that loop with negligible overhead (it
> took an internal redesign), and no other engine I'm aware of performs
> this optimization, either - it's all because JS's resizable arrays can
> also be sparse.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
> ___
> 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


  1   2   3   4   5   >