Re: Since JSDoc seems cerebrally dead...

2020-08-17 Thread Isiah Meadows
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


Re: Are ES Modules garbage collected? If so, do they re-execute on next import?

2020-07-18 Thread Isiah Meadows
For the web, one could lock it down with CORS-like restrictions, too,
so a script from one domain isn't allowed to modify cached entries
from another domain. It's not insurmountable.

This is part of why I feel the invariant should be removed and the
spec should just internally resolve static imports to dedupe them and
then resolve them accordingly when executing them, rather than
consulting external caches every time. (It's also easier for the
engine to handle, assuming they don't do this already.)

-

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

On Thu, Jul 16, 2020 at 6:44 AM Andrea Giammarchi
 wrote:
>
> FWIW explicit eviction is not only fine, if you own the code that does that, 
> but the only way I can code cover 100% all the branches of my libraries. The 
> issue here is the untrusted Web, where I'd never expect any 3rd parts library 
> to evict a module I am using within my code ... like ... ever.
>
> Accordingly, I think Allen, if it was Allen, made the right call for ESM.
>
> On Thu, Jul 16, 2020 at 3:23 PM Guy Bedford  wrote:
>>
>> Node.js in the CommonJS loader and dynamic loaders like SystemJS have 
>> supported module unloading for many years by permitting eviction from the 
>> loader registry. Evicting the full parent tree was the traditional reloading 
>> workflow in SystemJS, but live binding pushes are also permitted in SystemJS 
>> as well for this.
>>
>> I agree there are issues and invariants of course to consider from a 
>> theoretical perspective, but those are decisions to be made in terms of what 
>> invariants are valued, and I don't feel they are necessarily absolute 
>> constraints. These decisions should be made based on what is best for the JS 
>> users and engines. Not that I feel strongly this should be a requirement but 
>> that it should still be open to consideration.
>>
>> I'm not sure it was Allen's intention to ban any concept of reloading 
>> modules when defining the idempotency requirement for the host resolve 
>> function. Perhaps he could speak to that if he's around.
>>
>>
>> On Tue, 14 Jul 2020 at 23:05, Mark S. Miller  wrote:
>>>
>>> Only a module registry as a whole may be GCed. During the lifetime of any 
>>> one module registry, it can only grow. No other solution is possible.
>>>
>>> Btw, I remember being surprised ages ago when the same issue came up for 
>>> the Java ClassLoader. A classLoader holds on to all the classes it ever 
>>> loaded. Each class holds onto its classLoader. Each instance holds on to 
>>> its class. During the lifetime of a classLoader or any of its classes, the 
>>> graph of that classLoader and its classes can only grow new classes. Not 
>>> until the classLoader and all of its classes are unreachable at the same 
>>> time can any of them be collected. This was equally unfortunate, 
>>> surprising, and inescapable.
>>>
>>>
>>>
>>> On Tue, Jul 14, 2020 at 10:16 PM #!/JoePea  wrote:
>>>>
>>>> How can we ensure that long-running applications (even if theoretical),
>>>> that may load and unload an unlimited number of new modules over time
>>>> (f.e. routes in a web page specified by 3rd parties as time
>>>> progresses), not leak memory?
>>>>
>>>> Even if it is theoretical, I don't like the thought of something that
>>>> only ever allocates memory that will never be freed.
>>>>
>>>> Is someone working on a solution for this?
>>>>
>>>>
>>>> #!/JoePea
>>>>
>>>> On Wed, Jul 1, 2020 at 6:16 AM Mark S. Miller  wrote:
>>>> >
>>>> > No, definitely not. The table from specifiers to module instances is 
>>>> > indexed by specifiers. Specifiers are strings, so this table is not 
>>>> > weak. It is not a "cache" in the sense that it is allowed to drop 
>>>> > things. Rather it is a registry of module instances. Only a registry as 
>>>> > a whole can be gc'ed, and which point that context is no longer around 
>>>> > for instantiating or reinstantiating modules.
>>>> >
>>>> > As you suggest, if it could drop things because of GC that it would then 
>>>> > need to regenerate, that would expose the non-determinism of gc. That 
>>>> > would be a big deal. We carefully designed WeakMaps so that gc was 
>>>> > non-observable. WeakMaps introduce no observable non-determinism. 
>>>> > WeakRefs alone expose the non-determinism of gc, and are kept well 
>>>&

Re: Are ES Modules garbage collected? If so, do they re-execute on next import?

2020-07-01 Thread Isiah Meadows
That's part of the caching I'm referring to. And if the cache entry
for it has been evicted, I would *not* expect it to necessarily return
the same instance, consistent with the behavior with `require` and
`require.cache` in Node (and similar with most other module loaders
that support cache eviction).

-

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

On Tue, Jun 30, 2020 at 11:57 PM Andrea Giammarchi
 wrote:
>
> even if dereferenced, a dynamic import could re-reference it any time, and I 
> would expect it to still be the same module, it'd be a surprise otherwise 
> (cached things, same namespace checks, etc).
>
> On Wed, Jul 1, 2020 at 7:33 AM Isiah Meadows  wrote:
>>
>> Just to expand on that, if the module record itself is dereferenced
>> (like if it's evicted from the cache somehow), then yes, it should be
>> collected as appropriate. However, I'm not aware of any major
>> implementation that offers that functionality.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Tue, Jun 30, 2020 at 6:22 PM Gus Caplan  wrote:
>> >
>> > Modules in the spec are cached by specifier by modules that import them. 
>> > Modules in major implementations are additionally cached for the entire 
>> > realm by absolute URLs. I would say that for actual code (functions and 
>> > classes and whatnot) leaks aren't really a problem. Even if you import a 
>> > ton of levels, that's not that much memory. The main concern I've seen 
>> > raised is JSON modules, where once you import them the JSON object, which 
>> > can be quite large, will never be collected. Of course, there is a simple 
>> > solution to that (fetch) so it isn't a world ending problem.
>> >
>> > On Tue, Jun 30, 2020 at 7:41 PM #!/JoePea  wrote:
>> >>
>> >> I am curious: can modules be garbage collected if the exports are not
>> >> references by anything anymore? And if so, will the module be
>> >> re-evaluated the next time it is imported?
>> >>
>> >> I haven't tried an experiment to answer this yet. I'll be back to post
>> >> findings if someone doesn't post an official answer first.
>> >>
>> >> I'm thinking about code longevity. For example, if we make
>> >> long-running web-based applications with many routes and features (for
>> >> sake of example imagine a desktop environment, or a MMORPG game, with
>> >> apps or components that are loaded within the same context). Over
>> >> time, if imports are not collected, then it means we have a memory
>> >> leak.
>> >>
>> >> Imagine, for example, an infinite-universe MMORPG where you can land
>> >> on different planets where the code for features of a planet are
>> >> provided by third parties as ES Modules. I know, this might not be a
>> >> safe idea to import any code into an app, but just imagine it for sake
>> >> of example (imagine we have a continuous integration system to test
>> >> and verify code security, or something, before that code is allowed to
>> >> be consumed in the app). Imagine you play this app for many many days,
>> >> and visit many places, and you leave the app running the whole time
>> >> (because farming for resources is disabled if the app is not running,
>> >> or something).
>> >>
>> >> I would imagine that we want unused modules (when we leave a planet,
>> >> for example) to be (destroyed) garbage collected so that we don't
>> >> waste memory.
>> >>
>> >> #!/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
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Are ES Modules garbage collected? If so, do they re-execute on next import?

2020-06-30 Thread Isiah Meadows
Just to expand on that, if the module record itself is dereferenced
(like if it's evicted from the cache somehow), then yes, it should be
collected as appropriate. However, I'm not aware of any major
implementation that offers that functionality.

-

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

On Tue, Jun 30, 2020 at 6:22 PM Gus Caplan  wrote:
>
> Modules in the spec are cached by specifier by modules that import them. 
> Modules in major implementations are additionally cached for the entire realm 
> by absolute URLs. I would say that for actual code (functions and classes and 
> whatnot) leaks aren't really a problem. Even if you import a ton of levels, 
> that's not that much memory. The main concern I've seen raised is JSON 
> modules, where once you import them the JSON object, which can be quite 
> large, will never be collected. Of course, there is a simple solution to that 
> (fetch) so it isn't a world ending problem.
>
> On Tue, Jun 30, 2020 at 7:41 PM #!/JoePea  wrote:
>>
>> I am curious: can modules be garbage collected if the exports are not
>> references by anything anymore? And if so, will the module be
>> re-evaluated the next time it is imported?
>>
>> I haven't tried an experiment to answer this yet. I'll be back to post
>> findings if someone doesn't post an official answer first.
>>
>> I'm thinking about code longevity. For example, if we make
>> long-running web-based applications with many routes and features (for
>> sake of example imagine a desktop environment, or a MMORPG game, with
>> apps or components that are loaded within the same context). Over
>> time, if imports are not collected, then it means we have a memory
>> leak.
>>
>> Imagine, for example, an infinite-universe MMORPG where you can land
>> on different planets where the code for features of a planet are
>> provided by third parties as ES Modules. I know, this might not be a
>> safe idea to import any code into an app, but just imagine it for sake
>> of example (imagine we have a continuous integration system to test
>> and verify code security, or something, before that code is allowed to
>> be consumed in the app). Imagine you play this app for many many days,
>> and visit many places, and you leave the app running the whole time
>> (because farming for resources is disabled if the app is not running,
>> or something).
>>
>> I would imagine that we want unused modules (when we leave a planet,
>> for example) to be (destroyed) garbage collected so that we don't
>> waste memory.
>>
>> #!/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: Object.safeAssign

2020-05-01 Thread Isiah Meadows
Missed the list. Also, it apparently does trigger setters. Crossed it up
with spread properties (which don't).

On Fri, May 1, 2020 at 06:28 Isiah Meadows  wrote:

> I thought `Object.assign`already used the `Object.keys` +
> `Object.defineProperty` algorithms under the hood and thus were immune to
> this. Am I misremembering or misunderstanding?
>
> On Fri, May 1, 2020 at 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
>>
> --
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
-- 
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
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 Isiah Meadows
Edit: never mind. In either case, it's an engine problem, not a spec
problem.

I wouldn't mind a couple things that could desugar to that making it in
(like `Array.range`), but those all have something special the engine can
do to fill it in less than half the time provided appropriate ISA support.

On Tue, Feb 11, 2020 at 08:44 Isiah Meadows 
wrote:

> You have proof of this? That it doesn't produce a dense array in engines?
>
> On Mon, Feb 10, 2020 at 01:09 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
>>
> --
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
-- 
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
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 Isiah Meadows
You have proof of this? That it doesn't produce a dense array in engines?

On Mon, Feb 10, 2020 at 01:09 Andrea Giammarchi 
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
>
-- 
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Async iterator destructuring?

2020-02-07 Thread Isiah Meadows
It might be useful on some occasions to destructure async iterators. For
the sake of example, I'm using `await [...]` as the syntax, but I'm by no
means married to it.

1. Collecting a Node stream into a buffer:

```js
const await [...buffers] = someStream.setEncoding('buffer')
return Buffer.concat(buffers)
```

2. Collecting the first matching entry in a database scan:

```js
// It's different for each database
const await [item] = db.scan({
filter: {key: value},
limit: 1,
})
```

It's not a common need, but it's useful either way, and it brings async
iterators and sync iterators closer to feature parity.
-- 
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: syntax for case ranges

2020-02-03 Thread Isiah Meadows
Does make me wonder if engines should start collecting statistics on how
often it's used and how often that result differs from if a Python-style
chained comparison was done instead.

On Mon, Feb 3, 2020 at 09:18 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>> 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 
>>> 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 _ 
>>>>>> 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-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
>>>>>
>>>> --
>>>> -
>>>>
>>>> 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
>>>
>>
>>
>> --
>>   Cheers,
>>   --MarkM
>>
> ___
> 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


Re: syntax for case ranges

2020-01-31 Thread Isiah Meadows
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 
> 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 _  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-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
>
-- 
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: strict built-in functions

2019-12-08 Thread Isiah Meadows
You might do better to file a pull request directly against the spec for
this: https://github.com/tc39/ecma262. To me, it looks more like an
oversight, not something that would likely have to go through all 4 stages.
(If it does, at least you already have a repo for it.)

On Sun, Dec 8, 2019 at 08:43 Jack Works  wrote:

> In the current spec, strictness of the built-in functions are
> implementation-dependent behaviors. This proposal is going to fix this
> problem.
> https://github.com/Jack-Works/proposal-strict-built-in-functions
>
> ___
> 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


Re: Proposal: Property Accessor Function Shorthand

2019-12-03 Thread Isiah Meadows
BTW, all this is very much just a special case of this (existing stage
1) proposal, and is part of why it exists:
https://github.com/tc39/proposal-partial-application

I do find it surprising that property access isn't addressed there,
but it seems like it was likely just overlooked - it has no mention in
the repo, in the open issues, or even in the closed issues or any of
the open or closed pull requests.

-

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

On Tue, Dec 3, 2019 at 5:43 AM Michael Luder-Rosefield
 wrote:
>
> At the cost of adding more code, but giving more power, perhaps what we want 
> is something akin to Kotlin's `it` keyword:
> https://kotlinlang.org/docs/reference/lambdas.html?_ga=2.238822404.500195435.1575368476-1345353619.1575368476#it-implicit-name-of-a-single-parameter
>
> it: implicit name of a single parameter
> It's very common that a lambda expression has only one parameter.
> If the compiler can figure the signature out itself, it is allowed not to 
> declare the only parameter and omit ->. The parameter will be implicitly 
> declared under the name it:
> ints.filter { it > 0 } // this literal is of type '(it: Int) -> Boolean'
>
>
> What we'd want is something concise and non-ambiguous to fulfill the same 
> role; something that cannot currently be a valid identifier, maybe. This is 
> the point where I start scanning the keyboard for underutilised symbols... 
> I'm thinking the hash symbol would work. To re-use the original example:
>
> ```js
> const activeProducts = products.filter(#.active);
> const productNames = products.map(#.name);
> const sortedProducts = _.sortBy(products, #.name);
> const { true: activeProducts, false: inactiveProducts } = _.groupBy(products, 
> #.active);
> ```
>
> It makes intuitive sense in 2 ways, I think; # makes you think of the object 
> hash you're extracting a property from, and also is familiar as something's 
> id from CSS selectors.
>
> We could also extend it to represent multiple parameters: # is also aliased 
> as #0, the 2nd parameter is #1, etc.
>
> Further, dynamic properties would work too: `const fooProducts = 
> products.filter(#[foo]);
> --
> Dammit babies, you've got to be kind.
>
>
> On Mon, 2 Dec 2019 at 22:32, Waldemar Horwat  wrote:
>>
>> On 11/24/19 9:17 PM, Bob Myers wrote:
>> > FWIW, the syntax `.propName` does appear to be syntactically unambiguous.
>>
>> It conflicts with contextual keywords such as `new . target`.
>>
>>  Waldemar
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Proposal: `await.all {...}` for parallelism

2019-11-26 Thread Isiah Meadows
gt;
>>>> const x12 = s12() // sync code in-the-middle
>>>>
>>>> const x4 = await || p4(x1, x2)
>>>> const x5 = await || p5(x2, x3, x12)
>>>> const x6 = await p6(x4, x5, x10)
>>>>
>>>> const x7 = await || p7(x4, x6)
>>>> const x9 = await || p9(x5, x6)
>>>> const x8 = await p8(x6, x7)
>>>>
>>>> await p11(x8, x9)
>>>>
>>>>
>>>> // it would resolve a tree of parallel and series like following with 
>>>> traditional promises
>>>>
>>>> p0
>>>> .then(x0 => {
>>>> const x11 = f11()
>>>>
>>>> return Promise.all([p1(x0), p3(x11)])
>>>> .then((x1, x3) =>
>>>> p2(x1)
>>>>     .then(x2 =>
>>>> p10(x2, x3)
>>>> .then(x10 => {
>>>> const x12 = s12()
>>>>
>>>> return Promise.all([p4(x1, x2), p5(x2,
>>>> x3, x12)])
>>>> .then((x4, x5) =>
>>>> p6(x4, x5, x10)
>>>> .then(x6 => Promise.all([p7
>>>> (x4, x6), p9(x5, x6)])
>>>> .then((x7, x9) => p8(x6
>>>> , x7)
>>>> .then(x8 => p11(x8
>>>> , x9))
>>>> )
>>>> )
>>>> )
>>>> })
>>>> )
>>>> )
>>>> })
>>>> ```
>>>>
>>> ___
> 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


Re: Proposal: `await.all {...}` for parallelism

2019-11-20 Thread Isiah Meadows
Just FYI, I previously suggested a couple things substantially more
flexible than this [1] [2] (originated from this [3]), and it mostly
fell flat due to being highly premature. Anything exclusive to
promises is unlikely to win as library methods exist for basically all
use cases and from my experience, committee members are in general
very hesitant to add syntax for anything that doesn't pay for itself
well. Similar questions have come up a few times in the past, too, and
I've commented on two of them. [4] [5]

If anything, I don't feel we know the problem space well enough, and
the language lacks the primitives needed to really dig into it. (This
is why I came up with my generator forking strawman. [6])

[1]: https://github.com/isiahmeadows/non-linear-proposal
[2]: https://github.com/isiahmeadows/lifted-pipeline-strawman
[3]: 
https://esdiscuss.org/topic/observable-promise-parallel-control-flow-proposal
[4]: https://esdiscuss.org/topic/stream-async-await
[5]: 
https://esdiscuss.org/topic/improved-syntax-for-observable-mapping-and-subscribing
[6]: https://github.com/isiahmeadows/proposal-generator-fork

-

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

On Wed, Nov 20, 2019 at 6:16 PM Jacob Bloom  wrote:
>
> ...strike that, I misread the "but that still waits for the async
> functions to complete" part. So what you're proposing is that
> everything functions normally inside the curly braces, but execution
> doesn't continue until all promises have resolved? So your example
> would work essentially like this:
>
> ```javascript
> const x = doSomethingAsync();
> const y = doSomethingElseAsync();
> await x, await y;
> // all promises are resolved by now, but
> // still need to use await to unbox the values
> someFunction(await x, await y);
> ```
>
> On Wed, Nov 20, 2019 at 3:28 PM Jacob Bloom  wrote:
> >
> > >Maybe if you drop the "await" in your example:
> > >
> > >```javascript
> > >await.all {
> > >const x = doSomethingAsync();
> > >//x is just the promise here
> > >}
> > >```
> > >
> > >...but that still waits for the async functions to complete, I think it 
> > >would
> > >cause fewer bugs and would seem to still satisfy the motivation?
> >
> > It doesn't seem like the `await.all` block is doing anything in that
> > case. That code seems equivalent to this:
> >
> > ```javascript
> > const x = doSomethingAsync();
> > myFunction(await x)
> > ```
> >
> > >```javascript
> > >await.all {
> > >  const x = await doSomethingAsync();
> > >  //x is still undefined here!
> > >}
> > >```
> >
> > You bring up a good point about scoping and race conditions. It's a
> > little tricky since the curly braces create a block scope but none of
> > the parallel statements should be allowed to access each-other's
> > variables, it's almost like each statement should have its own scope.
> > Maybe it'd be better to have a syntax that ensures a set of curly
> > braces for each parallel task? Async do-expressions could be a good
> > solution (assuming they'd work kind of like an async IIFE):
> >
> > ```javascript
> > async function initialize() {
> >   let foo, bar, baz;
> >   await Promise.all([
> > async do { foo = (await request('foo.json')).data },
> > async do { bar = (await request('bar.json')).data },
> > async do { baz = (await request('baz.json')).data },
> >   ]);
> >   render(foo, bar, baz);
> > }
> > ```
> >
> > (this is also a less drastic syntax change that piggybacks on an
> > existing proposal)
> >
> > On Wed, Nov 20, 2019 at 11:50 AM Bergi  wrote:
> > >
> > > Hello!
> > >
> > > > This [current] 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
> > >
> > > Actually I'd argue that it is. Doing stuff concurrently *is*
> > > fundamentally different from doing it serially, and should be reasoned
> > > about every time you use it.
> > >
> > > 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: Ternary operator enhancement proposal

2019-11-15 Thread Isiah Meadows
Also, this particular use case could be addressed by adding an
equivalent of the stage 3 optional chaining operators to the proposed
pipeline operator: https://github.com/tc39/proposal-pipeline-operator.

In this light, I've also filed an issue there:
https://github.com/tc39/proposal-pipeline-operator/issues/159

-

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

On Thu, Nov 14, 2019 at 4:21 AM Cyril Auburtin  wrote:
>
> the `do` operator might be good enough
>
> ```js
> const z = do { const z = x?.y?.z; z ? doSomethingWithValue(z) : null; };
> ```
>
> On Wed, Nov 13, 2019 at 3:48 PM Claude Pache  wrote:
>>
>>
>>
>> Le 13 nov. 2019 à 03:43, devlato  a écrit :
>>
>> Hey folks,
>>
>> not sure if you haven't discussed something similar, but what do you think 
>> about making an enhancement for the ternary operator, to make it more 
>> powerful?
>> I've created a small explanatory doc on GitHub: 
>> https://github.com/devlato/proposal-ternary-placeholder
>>
>> Warmest regards,
>> Denis
>>
>>
>> The generic problem is: you do some computation, and you want to reuse the 
>> result of that computation later.
>>
>> The generic solution is to use a temporary variable:
>>
>> ```js
>> // declare a temporary variable at the top of some scope
>> var _;
>>
>> // later, use it:
>> const X = () => (_ = x?.y?.z) ? doSomethingWithValue(_) : null;
>> ```
>>
>> Now, you are not satisfied with the existing solution, and you want to avoid 
>> declaration of temporary variables in some outer scope...? Maybe:
>>
>> ```js
>> const X = () => (#1 = x?.y?.z) ? doSomethingWithValue(#1) : null;
>> ```
>>
>> (Any similarity with 
>> https://developer.mozilla.org/en-US/docs/Archive/Web/Sharp_variables_in_JavaScript
>>  is not at all fortuitous.) However, I’m not convinced that the need to 
>> declare your temporary variables is such a problem that it is worth the 
>> introduction of new syntax.
>>
>>
>> —Claude
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Template literal property names in object literals

2019-11-07 Thread Isiah Meadows
Just wanted to chime in with the fact this has been a thing in
CoffeeScript for most (if not all) its existence, as well as with Ruby
hash maps, which special-case string keys (you can do
`{"foo#{bar}baz": whatever}`).

Not that I would expect this to have much impact on whether this
really minor nice-to-have makes it in, though...

-----

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

On Thu, Nov 7, 2019 at 4:23 PM Alex Kodat  wrote:
>
> Gus,
>
> Sure, but your (const) example is simply syntactically invalid – 
> syntactically invalid code will always be hard for humans to digest. A better 
> example might be one involving operator precedence – I’ll plead guilty to 
> adding unnecessary parentheses so someone looking at code doesn’t have to 
> waste cycles thinking through operator precedence issues.
>
> But, in any case, I don't think human would find:
>
>   let obj = {`foo bar`: 1}
>
> or even
>
>   let obj = {`foo${i}`: 1}
>
> daunting to parse. And if it upsets them, just like I add unnecessary 
> parantheses to my code, they could do
>
>   let obj = {[`foo${i}`]: 1}
>
> if they feel that somehow makes the code clearer (it gives me a headache ;-)).
>
> 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 3:13 PM
> To: Alex Kodat 
> Cc: Jordan Harband ; es-discuss@mozilla.org
> Subject: Re: Template literal property names in object literals
>
> Syntactic ambiguities are not very representative of what humans find 
> ambiguous. For example, `const x = 1 const x = 2` (no semicolon) is not 
> ambiguous to a parser at all, but humans have a hard time tracking it.
>
> On Thu, Nov 7, 2019 at 12:53 PM Alex Kodat <mailto:ako...@rocketsoftware.com> 
> wrote:
> Jordan,
>
> That’s not an ambiguity, it’s just a rule of thumb that’s currently true. No? 
> My question is whether adding TemplateString to ComputedPropertyName in the 
> spec would create **syntactic** ambiguities or daunting implementation issues.
>
> Clearly, there's little interest in this so I'll drop it, I was just curious 
> as I, at least, was somewhat surprised to see it didn't work.
>
> 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%7Ce77faaad7c8444d9792f08d763c74e54%7C79544c1eed224879a082b67a9a672aae%7C0%7C1%7C637087579982532174=wl5HN9LEKavzBGkxJf0SugC2iN2oOQu12kmnXKUkXoo%3D=0
>
> From: Jordan Harband <mailto:ljh...@gmail.com>
> Sent: Thursday, November 7, 2019 2:44 PM
> To: Alex Kodat <mailto:ako...@rocketsoftware.com>
> Cc: Gus Caplan <mailto:m...@gus.host>; mailto:es-discuss@mozilla.org
> Subject: Re: Template literal property names in object literals
>
> 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 
> <mailto:mailto:ako...@rocketsoftware.com> 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: 
> https://nam01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.rocketsoftware.com%2F=02%7C01%7C%7Ce77faaad7c8444d9792f08d763c74e54%7C79544c1eed224879a082b67a9a672aae%7C0%7C1%7C637087579982532174=wl5HN9LEKavzBGkxJf0SugC2iN2oOQu12kmnXKUkXoo%3D=0
>
> From: Jordan Harband <mailto:mailto:ljh...@gmail.com>
> Sent: Thursday, November 7, 2019 1:46 PM
> To: Alex Kodat <mailto:mailto:ako...@rocketsoftware.com>
> Cc: Gus Caplan <mailto:mailto:m...@gus.host>; 
> mailto:mailto:es-discuss

Re: Optional Curly Braces in JavaScript

2019-11-02 Thread Isiah Meadows
Python is so broadly used in those fields due to good library support, not
just ease of language use. But since that discussion is pretty off-topic,
I'll leave it there.

On Sat, Nov 2, 2019 at 21:33 Ed Saleh  wrote:

> I don't see any reason why Python is widely used in math and science, and
> specially AI, other than this reason. It's easy to write and prototype in.
> --
> *From:* Jordan Harband 
> *Sent:* Saturday, November 2, 2019 9:23:31 PM
> *To:* Ed Saleh 
> *Cc:* Bergi ; es-discuss ; kai
> zhu 
>
> *Subject:* Re: Optional Curly Braces in JavaScript
>
> 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
>
-- 
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


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

2019-10-13 Thread Isiah Meadows
Maybe Promise.join(object)? Also, if a map is passed (or any iterable), it
should be joined into a map.

At the most basic level:

```js
Promise.join = (o) => {
let isMap = o[Symbol.iterator] != null
let ps = (
isMap ? Array.from : Object.entries
)(o)
let ks = ps.map(p => p[0])
return Promise.all(ps.map(p => p[1]))
.then(vs => {
let ps = vs.map((v, i) => [ks[i], v])
return isMap
? new Map(ps)
: Object.fromEntries(ps)
})
}
```

On Sun, Oct 13, 2019 at 13:40 Cyril Auburtin 
wrote:

> OP probably means he would like Promise.all to return an object as well,
> if an object if given
>
> It's possible to hack an object to be iterable, but Promise.all
> already return an array unfortunately
>
> On Sun, Oct 13, 2019 at 7:16 PM Boris Zbarsky  wrote:
>
>> On 10/12/19 12:52 AM, Jacob Bloom wrote:
>> > const responses = await Promise.all(requests);
>>
>> As opposed to:
>>
>>const responses = await Primise.all(requests.values());
>>
>> which works right now?
>>
>> -Boris
>> ___
>> 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


Re: Conditional await, anyone?

2019-10-09 Thread Isiah Meadows
I had a similar example in real-world code, but it was just to merge
sync and async into the same code path. I handled it by using
generators and basically running them myself:
https://github.com/isiahmeadows/mithril-node-render/blob/v2/index.js#L195-L206

In either case, I'm not sure it's worth adding new syntax for it.

-

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

On Wed, Oct 9, 2019 at 3:08 AM Andrea Giammarchi
 wrote:
>
> I don't know why this went in a completely unrelated direction so ... I'll 
> try to explain again what is `await?` about.
>
> My first two examples show a relevant performance difference between the 
> async code and the sync one.
>
> The async code though, has zero reasons to be async and so much slower.
>
> ```js
> (async () => {
>   console.time('await');
>   const result = await (async () => [await 1, await 2, await 3])();
>   console.timeEnd('await');
>   return result;
> })();
> ```
>
> Why would `await 1` ever need to create a micro task, if already executed 
> into a scheduled one via async?
>
> Or in general, why any callback that would early return a value that is not a 
> promise should create a micro task?
>
> So the proposal was implemented in an attempt to de-sugar `await?` into the 
> steps proposed by the dev I've interacted with:
>
> ```js
> const value = await? callback();
>
> // as sugar for
> let value = callback();
> if ('then' in value)
>   value = await value;
> ```
>
> The order is guaranteed and linear in every case, so that nothing actually 
> change logically speaking, and the hint would be about performance, 'cause 
> engines don't apparently optimize non-promise based cases.
>
> However, since the initial intent/proposal about performance got translated 
> into everything else, I've instantly lost interest myself as it's evident an 
> `await?` would causes more confusion than it solves.
>
> I am also not answering other points as not relevant for this idea/proposal.
>
> Thanks regardless for sharing your thoughts, it helped me see it would 
> confuse developers.
>
> Best Regards
>
>
>
>
>
> On Tue, Oct 8, 2019 at 11:58 PM Dan Peddle  wrote:
>>
>> Have to agree, mixing sync and async code like this looks like a disaster 
>> waiting to happen. Knowing which order your code will be executed in might 
>> seem not so important for controlled environments where micro optimisations 
>> are attractive, but thinking about trying to track down a bug through this 
>> would drive me nuts.
>>
>> Imagine you have a cached value which can be retrieved synchronously - other 
>> code which runs in order, and perhaps not directly part of this chain, would 
>> be fine. When it’s not there, zalgo would indeed be released. The solution 
>> to this is to use promises (as I’m sure you know) so you have a consistent 
>> way of saying when something is ready... otherwise it’s thenable sniffing 
>> all the way through the codebase.
>>
>> Async infers some kind of IO or deferred process, scheduling. If there’s a 
>> dependency, then we need to express that. That it may be in some cases 
>> available synchronously seems like something to be extremely wary of.
>>
>> > On 8. Oct 2019, at 22:25, Tab Atkins Jr.  wrote:
>> >
>> > I'm not sure I understand the intended use-case here.  If the author
>> > knows the function they're calling is async, they can use `await`
>> > normally. If they know it's not async, they can avoid `await`
>> > altogether. If they have no idea whether it's async or not, that means
>> > they just don't understand what the function is returning, which
>> > sounds like a really bad thing that they should fix?  And in that
>> > case, as Gus says, `await?`'s semantics would do some confusing things
>> > to execution order, making the line after the `await?` either run
>> > *before* or *after* the calling code, depending on whether the await'd
>> > value was a promise or not.
>> >
>> > ~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
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Custom Elements in Templates

2019-09-24 Thread Isiah Meadows
You'd have better luck in https://discourse.wicg.io than here. This is
about the ECMAScript spec and JavaScript the language, not anything related
to the web platform at large.

On Tue, Sep 24, 2019 at 09:55 Randy Buchholz  wrote:

> I’m putting a custom element in a template and then “selecting” it out to
> Window level. It seem to loose its identity as a custom element.
>
>
>
> ```
>
> // In page
>
> 
>
> 
>
> 
>
>
>
> 
>
> class MyElement extends HTMLElement {
>
> constructor() {
>
> super();
>
> }
>
> get Field() { return this.getAttribute("field");}
>
> }
>
>
>
> window.customElements.define("my-element", MyElement);
>
> 
>
>
>
> 
>
> const frag = document.querySelector("#holder").content;
>
> const el = frag.querySelector("my-element");
>
> console.log({el});
>
> 
>
> ```
>
>
>
> When `` is a page level and not in a template I can read
> `xxx.Field`. When it comes from within a template it seems to no longer act
> like the custom element – xxx.Field isn’t defined. The script selecting it
> is at “Window” level, so shouldn’t it “cast” correctly?
> ___
> 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


Re: Why globalThis instead of something intuitive like globalObject, systemGlobal, or globalEntity?

2019-09-21 Thread Isiah Meadows
If you look in the proposal's repo, they explain the rationale behind the
identifier:
https://github.com/tc39/proposal-global/

Here's a short summary: `globalThis` is the same value you get from
evaluating `this` in the global scope of a sloppy mode script. This is
subtly different than a "global object", which JS has no concept of.
There's other nuances involved, too.

Concretely, for one example, `globalObject` was explicitly rejected because
in HTML, the global `this` is a proxy of `window`, not the `window` object
itself. The `window` proxy delegates all operations to the current global
`window`, as you might expect. But here's where things get interesting:
during navigation, the window changes, yet the global `this` does not, so
if you define a property, capture the global `this`, and navigate, the
property you just defined will disappear, but the global `this` you
captured still has the same identity as the new reference.

This file in particular explains the naming side of it in detail:
https://github.com/tc39/proposal-global/blob/master/NAMING.md It covers the
other suggested names here indirectly.

And do keep in mind much of TC39's members are non-native speakers
themselves, including one of the proposal's biggest champions/fans,
Matthias. So it's not like that concern goes unnoticed - if anything, it
gets accounted for without them even thinking about it. It might also
explain why it's `array.entries()`, `map.entries()`, and similar when the
more proper English name would've been `array.pairs()`, `map.pairs()`, and
so on: entries are really what values from `value[Symbol.iterator]()`
represent, and non-native speakers sometimes misuse "entries" as if it were
synonymous with "pairs". Contrast this with Underscore's `_.pairs`, named
by a native English speaker back in 2012, long before ES6 was a thing, and
it stood as precedent for having `coll.entries()` for various collections.

On Sat, Sep 21, 2019 at 14:12 #!/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: A new proposal for syntax-checking and sandbox: ECMAScript Parser proposal

2019-09-16 Thread Isiah Meadows
Nit: Acorn's *output* is based on Esprima. Its code is *not* and
hasn't been for a few years now. It started a fork of Esprima, but it
wasn't long before it was rewritten the first time.

-

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

On Mon, Sep 16, 2019 at 1:58 AM kai zhu  wrote:
>
> adding datapoint on application in code-coverage.
>
> a builtin parser-api would be ideal (and appreciate the insight on 
> implementation difficulties).
> lacking that, the next best alternative i've found is acorn (based on 
> esprima),
> available as a single, embedabble file runnable in browser:
>
> ```shell
> curl https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz | tar -O -xz 
> package/dist/acorn.js > acorn.rollup.js
> ls -l acorn.rollup.js
> -rwxr-xr-x 1 root root 191715 Sep 15 16:49 acorn.rollup.js
> ```
>
> i recently added es9 syntax-support to in-browser-variant of istanbul by 
> replacing its aging esprima-parser with acorn [1].
> ideally, i hope a standardized ast will be available someday, and get rid of 
> acorn/babel/shift altogether (or maybe acorn can become that standard?).
> even better, is if [cross-compatible] instrumentation becomes a common 
> bultin-feature in engines, and get rid of istanbul.
>
> chrome/puppeteer's instrumentation-api is not yet ideal for my use-case 
> because it currently lack code-coverage-info on branches (which 
> istanbul-instrumentation provides).
>
> [1] istanbul-lite - embeddable, es9 browser-variant of istanbul code-coverage
> https://kaizhu256.github.io/node-istanbul-lite/build..beta..travis-ci.org/app/
>
>
>
> On Sun, Sep 15, 2019 at 9:08 AM David Teller  wrote:
>>
>> In theory, it should be possible to have both modes, if the parser is
>> designed for it. Unfortunately, that's not the case at the moment.
>>
>> Mozilla has recently started working on a new parser which could be used
>> both by VMs and by JS/wasm devs. It might help towards this issue, but
>> it's still early days.
>>
>> Cheers,
>>  David
>>
>> On 15/09/2019 13:09, Jack Works wrote:
>> > Happy to see standard ast in binary ast proposal.
>> >
>> > For compiler, it can have a "slow" mode when parsing with this parser
>> > API and still use fast code generation in other cases. But unfortunately
>> > it seems there are much more work than I think to provide such an API.
>> >
>> ___
>> 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: A new proposal for syntax-checking and sandbox: ECMAScript Parser proposal

2019-09-14 Thread Isiah Meadows
I do want to note a couple things here, as someone familiar with the
implementation aspect of JS and programming languages in general:

1. The HTML and CSS parsers (for inline style sheets) have to build a
full DOM trees for each anyways just to conform to spec, so they can't
just, say, parse `.foo { display: block; color: red; }` as `.foo {
display: block; } .foo { color: red }` with a cached selector (which
*would* be easier to process later on). In this case, they're
basically just exposing the same parsers they'd have to use in
practice anyways, so it's literally trivial for them to add.
2. No JS engine parses nodes the way the spec processes them, just in
a way it's unobservable mod timings. They internally parse `1` and
`1.0` as different types, and they will do things like constant
propagation - `3 * 5` gets parsed as `15` usually, and `"a" + "b"`
will usually get read as `"ab"` by some engines. Furthermore, browser
engines lazily parse functions where they can, only validating them
for early errors and storing the source code to reparse them on first
call, because it helps them start up faster with less memory. And of
course, `typeof value === "string"` is often not simply compiled to
`%IsString(value)` but literally parsed as such if `value` is defined
in that scope. And finally, engines typically merge the steps of AST
generation and scope detection, not only to detect `let`/`const`
errors but also to speed up bytecode generation.

So although it sounds like JS engines could reuse their logic, they
really couldn't. This is further evidenced by SpiderMonkey's parser
API (the predecessor to the ESTree spec) not sharing the same
implementation as the core language parser. There's two vastly
different concerns between generating an AST for tooling and
generating an AST to execute. In the former, you want as much info as
possible readily available. In the latter, you just want to have the
bare minimum to compile to bytecode with relevant source locations for
stack traces, and anything else is literally just unnecessary
overhead.

-

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

On Sat, Sep 14, 2019 at 9:41 AM Gareth Heyes
 wrote:
>
> I had a few goes with making a JS sandbox. I also created a safe DOM 
> environment that allowed safe manipulation of innerHTML etc
>
> JS sandbox with regular expressions
> http://www.businessinfo.co.uk/labs/jsreg/jsreg.html
>
> JS sandbox and safe DOM environment
> http://businessinfo.co.uk/labs/MentalJS/MentalJS.html
>
> It would be great to have a parser in JS!
>
> On 14 Sep 2019, at 06:46, Jack Works  wrote:
>
> Just like DOMParser in HTML and Houdini's parser API in CSS, a built-in 
> parser for ECMAScript itself is quite useful in many ways.
>
> Check out https://github.com/Jack-Works/proposal-ecmascript-parser for 
> details (and also, finding champions!)
>
>
> ___
> 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: Stage 0 proposal: specifying concurrency for "for...of" loops potentially containing "await" statements

2019-09-10 Thread Isiah Meadows
 The major benefit here is that *the developer does not have to shift
>>>> gears mentally from async/await to thinking about promises to deal with a
>>>> common case in systems programming. *They are able to continue with
>>>> the pattern they are already comfortable with.
>>>>
>>>> Up to 5 loop bodies commence concurrently with regard to "await"
>>>> statements (see below).
>>>>
>>>> There is no guarantee that item 3 will finish before item 2, or that
>>>> item 4 won't start (due to 3 being finished) before item 2 ends, etc.
>>>>
>>>> If an exception is not caught inside the loop body, the loop stops,
>>>> that exception is thrown beyond the loop, and any further exceptions from
>>>> that invocation of the loop due to concurrently executing loop bodies are
>>>> discarded.
>>>>
>>>> Just as with an ordinary "for...of" loop containing an "await"
>>>> statement, *it is guaranteed that, barring an exception, the loop body
>>>> will execute completely for every item in "items" before the loop exits and
>>>> the console.log statement executes.* The only difference is that *the
>>>> specified amount of concurrency is permitted during the loop*.
>>>>
>>>> "5" may be any expression resulting in a number. It is cast to an
>>>> integer. If  the result is not a natural number, an error is thrown (it
>>>> must not be 0 or a negative number).
>>>>
>>>> *FAQs*
>>>>
>>>> *"What if I want unlimited concurrency?"*
>>>>
>>>> It is rarely a good idea. It results in excessive stress on back ends,
>>>> unnecessary guards that force serialization in interface libraries just to
>>>> cope with (and effectively negate) it, and API rate limiting. This feature
>>>> teaches the best practice that the level of concurrency should be mindfully
>>>> chosen. However, those who really want it can specify "concurrency
>>>> items.length" or similar.
>>>>
>>>> *"What about async iterators?"*
>>>>
>>>> The feature should also be supported here:
>>>>
>>>> ```js
>>>> for *async* (item of items *concurrency 5*) {
>>>>   // db.insert is an async function
>>>>   await db.insert(item);
>>>> }
>>>> ```
>>>>
>>>> While the async iterator itself is still sequential rather than
>>>> concurrent, frequently these can supply values considerably faster than
>>>> they are processed by the loop body, and so there is still potential
>>>> benefit in having several items "in the hopper" (up to the concurrency
>>>> limit) at a time.
>>>>
>>>> --
>>>> Chief Software Architect
>>>> Apostrophe Technologies
>>>> Pronouns: he / him / his
>>>> ___
>>>> 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
>
-- 
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: persisting large wasm-sqlite3 datasets in browser (beyond kv-storage)

2019-09-04 Thread Isiah Meadows
Not sure this pertains to the ECMAScript spec in any way. You may have
better luck with WICG, because they are who deal with those specs -
those are specific to the web, while JS is used in places where those
might not even make sense (like IoT sensors).

-

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

On Wed, Sep 4, 2019 at 12:40 PM kai zhu  wrote:
>
> at work, we have browser-app that load-and-persist ~100MB (500k rows) 
> csv-files into wasm-sqlite3 [1], (ingestion-time is ~15s for 100MB csv).  we 
> wish to go bigger, but chrome's indexeddb has a hard-limit of 125MB per 
> key-value object (on windows).
>
> i don't have anything actionable.  just want people aware of datapoint, and 
> think about javascript-language-design to improve UX-handling with 
> sqlite3-persistence.
>
> fyi, ignoring persistence, chrome can handle wasm-sqlite3 datasets as large 
> as 300MB (1.5 million rows) in memory, before crashing (on 8gb windows10 
> machine).
>
> [1] sql.js wasm-sqlite3
> https://github.com/kripken/sql.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


Re: Re: Async Class

2019-08-26 Thread Isiah Meadows
Not a bad idea, but I'd *strongly* prefer the promise to be returned
from `new AsyncClass(...)` itself instead. And down that vein, `super`
with async classes should also implicitly `await` in its `super` call,
setting `this` to the value itself. For sanity reasons, `super` should
return a promise resolved with the set `this`, so you can still use it
and await it in inner arrow functions (it's possible), but it should
still do its own implicit awaiting, just so you can add properties to
the right instance. (This will also come into play with private
properties - you want those on the *instance*, not the *promise*.)

I do have a preference: `async` should decorate the `constructor`, not
the `class`. It's not the class that's async, it's the constructor
itself. You can still have sync methods elsewhere in the class, and
this doesn't do anything to affect that, hence why I'd prefer an
`async constructor(...) { ... }` instead of an `async class`.

-

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

On Mon, Aug 26, 2019 at 11:11 AM Dimitrian Nine
 wrote:
>
> Ok so much time has passed. I have learned more js. And created some 
> [wrapper][1] for my idea:
> Class is just function constructor that return object
> Async Class is async function constructor that returns promise object. 
> Wrapper code:
> ```js
> class PromiseClass { //promisified class
> static async new(obj){ return obj;}
> constructor() {return PromiseClass.new(this); }//new
> }//class
> class AsyncClass extends PromiseClass{ // can ext Class|PromiseClass
> static async new(obj){return await obj();}
> constructor(){return AsyncClass.new(async()=>{await super(); return 
> this});}//new
> }//AsyncClass
> ```
> And we work with Async Class like we work with functions. I dont see here 
> some differents to use them. Code without wrapper be clean:
> ```js
> async class PromiseClass { //return Promise
> constructor() {}//async()=>Promise object
> }//class
> async class AsyncClass extends PromiseClass{ // can ext Class|PromiseClass
> constructor(){ await super();} //async()=>Promise object
> }//AsyncClass
> ```
> [1]:https://repl.it/repls/InsubstantialPortlyCores
> вс, 25 февр. 2018 г. в 11:47, Dimitrian Nine :
>>
>> ([Classes][1]):
>> [1]: 
>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
>> «JavaScript classes, introduced in ECMAScript 2015, are primarily 
>> syntactical sugar over JavaScript's existing prototype-based inheritance. 
>> The class syntax does not introduce a new object-oriented inheritance model 
>> to JavaScript»
>> «Classes are in fact "special functions"»
>>
>> ```js class = function Create(); ```
>> all i want:
>> ``` js async class = async function Create(); ```
>
> ___
> 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-17 Thread Isiah Meadows
BTW, that very example is something I cover in my proposal's
introduction. It's also part of why I want an operator - this is one
of the few times where spreading FUD *is* a good idea IMHO.
https://github.com/isiahmeadows/proposal-divisor-dependent-modulo/

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
On Fri, Aug 16, 2019 at 12:33 PM Alex Gordon  wrote:
>
> Code that uses % is often surprisingly buggy. For example even a simple 
> function such as this is broken if n is negative:
>
> function isOdd(n) {
> return n % 2 === 1;
> }
>
> isOdd(-3) // false
>
> The same is not true in other programming languages. The same in Python works 
> just fine:
>
> def isOdd(n):
> return n % 2 == 1
>
> isOdd(-3) // true
>
> The advantage of an operator over a function is that it allows us to say to 
> people who are new to JS: "Always use %% instead of % unless you have a good 
> reason". Just the same as we say "Always use === instead of == unless you 
> have a good reason".
>
>
> On Thu, Aug 15, 2019 at 10:01 PM Isiah Meadows  wrote:
>>
>> BTW, I just wrote up a more precise, formalized proposal over here:
>> https://github.com/isiahmeadows/proposal-divisor-dependent-modulo/,
>> and I'd be more than willing to work with a TC39 champion on it. I
>> personally prefer syntax (pretty strongly), but I'm not beholden to
>> it.
>>
>> I do feel the semantics are simple enough it'd be okay to lower it to
>> syntax, and it naturally just glides right in. I find it *very* odd
>> that some languages use a simple operator `%` or relatively short
>> function for remainder keeping the sign of the dividend but relegate
>> the version keeping the sign of the divisor (the more useful and
>> intuitive of them) to a much more verbose function call. Of all
>> Wikipedia lists in https://en.wikipedia.org/wiki/Modulo_operation,
>> here's the four that do this currently - all but one expose an
>> operator for the first:
>>
>> - Fortran: `mod` for dividend-dependent, `modulo` for divisor-dependent
>> - Julia: `%`/`rem` for dividend-dependent, `mod` for divisor-dependent
>> - Java: `%` for dividend-dependent, `Math.floorMod` for divisor-dependent
>> - XBase++: `%` for dividend-dependent, `Mod` for divisor-dependent
>>
>> And it's worth noting most other languages (including some end
>> user-oriented ones) that show a syntactic preference to one or the
>> other expose a simpler one where the sign matches the divisor, a more
>> complicated one where the sign matches the dividend. For a variety of
>> examples:
>>
>> - Ruby: `%`/`modulo` for divisor-dependent, `remainder` for 
>> dividend-dependent
>> - SML: `mod` for divisor-dependent, `Int.rem` for dividend-dependent
>> - Elm: `modBy` for divisor-dependent, `remainderBy` for dividend-dependent
>> - Euphoria: `mod` for divisor-dependent, `remainder` for dividend-dependent
>> - Python: `%` for divisor-dependent, `math.fmod` for dividend-dependent
>> - Smalltalk: `\\` for divisor-dependent, `rem:` for dividend-dependent
>>
>> And of course, many don't even expose a type of modulo where the sign
>> matches the divisor. For some examples:
>>
>> - APL
>> - LibreOffice/Excel
>> - Lua
>> - Perl
>> - Mathematica
>> - PL/I
>> - TCL
>>
>> There's also Dart, a relatively new language which defaults to
>> non-negative always.
>>
>> This relatively long list of languages, *despite* C's heritage and
>> semantics being inherited in much of them, makes me question using a
>> function for this, and there would need to be a *lot* of FUD to get
>> people to use the function more than the operator.
>>
>> So this is why I would prefer an operator as opposed to syntax for this.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Thu, Aug 15, 2019 at 3:58 PM Jordan Harband  wrote:
>> >
>> > 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 
>> >  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 someb

Re: Array.prototype.joinWith(iterable)

2019-08-15 Thread Isiah Meadows
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  wrote:
>>
>> https://lodash.com/docs/#zip
>> https://docs.python.org/3/library/functions.html#zip
>>
>> On Thu, 15 Aug 2019, 15:34 Andrea Giammarchi,  
>> wrote:
>>>
>>> the suggested name is just ... suggested, I don't have strong opinion on 
>>> it, it just `join` values through other values
>>> what's `Array.zip` ? I've no idea
>>>
>>>
>>> On Thu, Aug 15, 2019 at 12:53 PM Michał Wadas  wrote:
>>>>
>>>> I would rather see Array.zip, it covers this use case.
>>>>
>>>> On Thu, 15 Aug 2019, 10:50 Andrea Giammarchi, 
>>>>  wrote:
>>>>>
>>>>>
>>>>> I wonder if there's any interest in adding another handy Array method as 
>>>>> joinWith could be:
>>>>>
>>>>> ```js
>>>>> // proposal example
>>>>> Array.prototype.joinWith = function (values) {
>>>>>   const {length} = this;
>>>>>   if (length < 2)
>>>>> return this.join('');
>>>>>   const out = [this[0]];
>>>>>   const len = values.length;
>>>>>   for (let i = 1; i < length; i++) {
>>>>> console.log(i, len);
>>>>> out.push(values[(i - 1) % len], this[i]);
>>>>>   }
>>>>>   return out.join('');
>>>>> };
>>>>> ```
>>>>>
>>>>> The goal is to simplify joining array entries through not the same value, 
>>>>> example:
>>>>>
>>>>> ```js
>>>>> 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"
>>>>> ```
>>>>>
>>>>> Throughts?
>>>>> ___
>>>>> 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 Isiah Meadows
BTW, I just wrote up a more precise, formalized proposal over here:
https://github.com/isiahmeadows/proposal-divisor-dependent-modulo/,
and I'd be more than willing to work with a TC39 champion on it. I
personally prefer syntax (pretty strongly), but I'm not beholden to
it.

I do feel the semantics are simple enough it'd be okay to lower it to
syntax, and it naturally just glides right in. I find it *very* odd
that some languages use a simple operator `%` or relatively short
function for remainder keeping the sign of the dividend but relegate
the version keeping the sign of the divisor (the more useful and
intuitive of them) to a much more verbose function call. Of all
Wikipedia lists in https://en.wikipedia.org/wiki/Modulo_operation,
here's the four that do this currently - all but one expose an
operator for the first:

- Fortran: `mod` for dividend-dependent, `modulo` for divisor-dependent
- Julia: `%`/`rem` for dividend-dependent, `mod` for divisor-dependent
- Java: `%` for dividend-dependent, `Math.floorMod` for divisor-dependent
- XBase++: `%` for dividend-dependent, `Mod` for divisor-dependent

And it's worth noting most other languages (including some end
user-oriented ones) that show a syntactic preference to one or the
other expose a simpler one where the sign matches the divisor, a more
complicated one where the sign matches the dividend. For a variety of
examples:

- Ruby: `%`/`modulo` for divisor-dependent, `remainder` for dividend-dependent
- SML: `mod` for divisor-dependent, `Int.rem` for dividend-dependent
- Elm: `modBy` for divisor-dependent, `remainderBy` for dividend-dependent
- Euphoria: `mod` for divisor-dependent, `remainder` for dividend-dependent
- Python: `%` for divisor-dependent, `math.fmod` for dividend-dependent
- Smalltalk: `\\` for divisor-dependent, `rem:` for dividend-dependent

And of course, many don't even expose a type of modulo where the sign
matches the divisor. For some examples:

- APL
- LibreOffice/Excel
- Lua
- Perl
- Mathematica
- PL/I
- TCL

There's also Dart, a relatively new language which defaults to
non-negative always.

This relatively long list of languages, *despite* C's heritage and
semantics being inherited in much of them, makes me question using a
function for this, and there would need to be a *lot* of FUD to get
people to use the function more than the operator.

So this is why I would prefer an operator as opposed to syntax for this.

-

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

On Thu, Aug 15, 2019 at 3:58 PM Jordan Harband  wrote:
>
> 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 
>  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
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Modulo Operator %%

2019-08-15 Thread Isiah Meadows
An operator is far more concise than a function call, and is likely to
see greater use. It also aligns better with peoples' intuition on what
the "modulus" is, avoiding subtle bugs like in `isOdd = x => x % 2 ===
1` (example from
https://en.wikipedia.org/wiki/Modulo_operation#Common_pitfalls - try
passing a negative to it). And given this one is high value (see
above) and *very* low cost (it can literally desugar to `(x % y + y) %
y`), I feel it does meet that bar.

> It would be interesting to hear the feedback of those that use regularly 
> powers, whether the benefit was clear (personally, I almost never use either 
> `Math.pow()` or `**`, so that I can’t say anything).

It has enough benefit I've seen CoffeeScript users default to `%%` and
only using `%` when they explicitly want the dividend-dependent
semantics. And engines with a native `%%`, if they can detect the
operands are always non-negative, can optimize it to `%` pretty
easily. It's better *enough* that you'd likely start seeing some
partially legitimate FUD spread about the standard `%`.

One other added benefit of using divisor-dependent modulo is that `x
%% (2**n)`, where `x` and `n` are integers and `n >= 0`, could always
be safely rewritten to `x & (2**n - 1)` while still preserving
semantics, but `x % (2**n)` does *not* have this property. For
example:

- `-1 %% (2**1)` → `-1 %% 1` → `1`
- `-1 & (2**1 - 1)` → `-1 & 1` → `1`
- `-1 % (2**1)` → `-1 % 2` → `-1`

BTW, I literally tested all three of these in Chrome's devtools
console, using my `x %% y` → `(x % y + y) % y` desugaring.

As for a native implementation and the spec, I'd recommend just doing
`copysign(fmod(x, y), y)` instead to retain precision.

> At least one disadvantage of an operator over a function, is that you have to 
> think about precedence. The problem is exacerbated in JS, because (following 
> some other languages) the unary minus has an uncanny high precedence level, 
> confusingly very different than the one of the binary minus; so that, after 
> having designed `**`, it was realised at the last minute that `-a**b` would 
> be dumbly interpreted as `(-a)**b` instead of `-(a**b)` or `0-a**b`, as 
> anybody who would be likely to actually use the operator would expect. (That 
> particular issue was resolved in a hurry by making the parenthesis-left form 
> a syntax error.)

I doubt this would happen with `%%`. It's similar enough to the
existing `%` in concept that most would expect it to have the same
precedence. With `**`, there was a very unique issue with it: there
were people actually *reading* it both ways, and even a language
(Python) that interprets `-a ** b` and `-a**b` *differently* in light
of that (as `(-a) ** b` and `-(a ** b)` respectively). That's not a
concern at all with most operators, so it doesn't apply to most new
operator proposals.

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
On Thu, Aug 15, 2019 at 2:40 AM Claude Pache  wrote:
>
>
>
> Le 12 août 2019 à 22:00, Matthew Morgan  a écrit :
>
> > JS needs a modulo operator. It currently has the remainder operator `%` 
> > which works in most cases except for negative values. I believe the the 
> > `%%` would work great and be easy to remember.
> >
> > let x = (-13) %% 64;
> > is equivalent to
> > let x = ((-13 % 64) + 64) % 64;
>
>
> Is there a strong advantage of an `%%` operator over a `Math.mod()` function? 
> There is the precedent of the `**` operator implemented as alternative of 
> `Math.pow()` few years ago. It would be interesting to hear the feedback of 
> those that use regularly powers, whether the benefit was clear (personally, I 
> almost never use either `Math.pow()` or `**`, so that I can’t say anything).
>
> At least one disadvantage of an operator over a function, is that you have to 
> think about precedence. The problem is exacerbated in JS, because (following 
> some other languages) the unary minus has an uncanny high precedence level, 
> confusingly very different than the one of the binary minus; so that, after 
> having designed `**`, it was realised at the last minute that `-a**b` would 
> be dumbly interpreted as `(-a)**b` instead of `-(a**b)` or `0-a**b`, as 
> anybody who would be likely to actually use the operator would expect. (That 
> particular issue was resolved in a hurry by making the parenthesis-left form 
> a syntax error.)
>
> —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


Re: Modulo Operator %%

2019-08-14 Thread Isiah Meadows
For syntactic precedent, CoffeeScript and R both have `%%` for a
modulus returning the sign of the divisor, where `a %% b` is
equivalent to `(a % b + b) % b`. So JS wouldn't be the first here.

Most languages Wikipedia lists in their comparison
(https://en.wikipedia.org/wiki/Modulo_operation) use a function for
this kind of modulus operation, not an operator. That itself seems
worth noting.

-

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


On Tue, Aug 13, 2019 at 10:27 AM Michael Haufe  wrote:
>
> I would prefer the syntax be ‘a mod b’ consistent with my wishlist item:
>
>
>
> <https://esdiscuss.org/topic/new-operator>
>
> <https://esdiscuss.org/topic/still-waiting-for-integer-division>
>
>
>
> In regards to semantics:
>
>
>
> <https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote.pdf>
>
>
>
>
>
>
>
> From: es-discuss  On Behalf Of Cyril Auburtin
> Sent: Tuesday, August 13, 2019 5:07 AM
> Cc: es-discuss 
> Subject: Re: Modulo Operator %%
>
>
>
> agreed, let's make a proposal
>
>
>
> On Tue, Aug 13, 2019 at 12:06 AM kdex  wrote:
>
> I would welcome such an operator as well. I find myself implementing a `mod`
> function from time to time, expressing it in terms of the remainder operator.
>
> As for syntax, I don't see `%%` posing any syntactical ambiguities, so I'll
> second it.
>
> On Monday, August 12, 2019 10:00:09 PM CEST Matthew Morgan wrote:
> > JS needs a modulo operator. It currently has the remainder operator `%`
> > which works in most cases except for negative values. I believe the the
> > `%%` would work great and be easy to remember.
> >
> > let x = (-13) %% 64;
> > is equivalent to
> > let x = ((-13 % 64) + 64) % 
> > 64;___
> 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-29 Thread Isiah Meadows
Have you...read Annex B? It's not as large as you might think.

It's worth noting `let[x] = [1]` *was* successfully changed from
setting `let[x]` to `1` to setting `x` to `1`, without breaking the
Web. (ES5 code didn't and couldn't change
`Array.prototype[Symbol.iterator]`.) About the only major additions I
can think of that had to be renamed were `Array.prototype.flat` (many
libraries implemented an incompatible `flatten` method) and
`Array.prototype.includes` (Mootools implemented
`Array.prototype.contains` differently and it broke a lot of users on
old versions of it who wouldn't migrate).

-

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

On Sun, Jul 28, 2019 at 10:46 PM Ranando King  wrote:
>
> On one hand, I agree with Jordan. Don't grief the language due to a bad 3rd 
> party API. Whether we accept it or not, a browser's API is a 3rd party API 
> with respect to Javascript. Otherwise, node would have to include that API to 
> be spec compliant.
>
> On the other hand, let's be a little more pragmatic about it. If that 
> busted-up Web API wasn't important, ES wouldn't be so highly constrained in 
> its changes vs what's running in browsers.
>
> On Sun, Jul 28, 2019 at 1:10 AM Jordan Harband  wrote:
>>
>> The existence of `document.all` (which is now specified in Annex B of the JS 
>> spec) doesn't make `typeof` broken, it makes web browsers broken.
>>
>> On Sat, Jul 27, 2019 at 3:42 PM Michael Haufe  
>> wrote:
>>>
>>> Congratz. It was document.all.
>>>
>>> "In case you're wondering, I've never seen anyone return or store 
>>> `document.all` ever."
>>>
>>> Before W3C standard you could (and some people did):
>>>
>>> function elements() {
>>> if(document.all) {
>>> return document.all
>>> } else if(document.layers) {
>>> return document.layers
>>> } else {
>>> throw "You must use IE4+ or NS 4.7!"
>>> }
>>> }
>>>
>>> This is actually the wrong way to use document.layers, but it was not 
>>> uncommon to see. Later when the W3C was standardizing, you managed the 
>>> three pathways by passing the id to the function.
>>>
>>> You can see examples of this on comp.lang.javascript, and through a search 
>>> engine by looking for "return document.all" or "return document.layers". 
>>> There are also some legacy books showing the practice.
>>>
>>> /Michael
>>>
>>>
>>> -Original Message-
>>> From: Isiah Meadows 
>>> Sent: Saturday, July 27, 2019 4:42 PM
>>> To: Michael Haufe 
>>> Cc: Jordan Harband ; es-discuss@mozilla.org
>>> Subject: Re: Proposal: Typeof Trap
>>>
>>> `document.all`, and that's only required for web browsers to implement
>>> - it's in Annex B. Some newer JS engines targeting non-browser platforms 
>>> (like Moddable's XS and I believe Nashorn as well) don't even implement it, 
>>> and it leads to a slightly simpler runtime.
>>>
>>> And it's only there thanks to a bunch of people relying on `if
>>> (document.all) doSomething()` for detecting legacy crap while others at the 
>>> same time just assuming it's there without checking for it first, almost 
>>> always on ancient web pages. Oh, and people were also calling it via 
>>> `document.all(nameOrIndex)` instead of `document.all[nameOrIndex]`, so the 
>>> HTML spec also has it implementing `[[Call]]`.
>>>
>>> - HTML spec: 
>>> https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#the-htmlallcollection-interface
>>> - ES spec: https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot
>>>
>>> In case you're wondering, I've never seen anyone return or store 
>>> `document.all` ever.
>>>
>>> -
>>>
>>> Isiah Meadows
>>> cont...@isiahmeadows.com
>>> www.isiahmeadows.com
>>>
>>>
>>> On Sat, Jul 27, 2019 at 5:20 PM Michael Haufe  
>>> wrote:
>>> >
>>> > More than one case:
>>> >
>>> >
>>> >
>>> > 
>>> >
>>> > var foo = f()
>>> >
>>> > typeof foo // object
>>> >
>>> > foo instanceof Object // false
>>> >
>>> >
>>> >
>>> > var bar = g()
>>> >
>>> > typeof bar //undefined
>>> >
>>> > bar instanceof Object //true
>>> >
>>> > bar() //
>>> 

Re: Proposal: Typeof Trap

2019-07-27 Thread Isiah Meadows
`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/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: Re: Removing the space in `a+ +b`?

2019-07-11 Thread Isiah Meadows
The idea is to introduce a grammar hack that notices `a++b` and
evaluates it with identical semantics to `a+ +b`. C++ used a similar
trick to allow `Foo>` in addition to `Foo< Bar >` for nested
template application, because it previously conflicted with `>>`. For
instance, consider `Foo> name(arg);`: it used to be parsed as
`(Foo < Bar) < (T >> name(arg));`, but they made a breaking change to
make it parse as a variable declaration of type `Foo>` instead,
invoking the type's constructor with `arg`. I was suggesting a similar
hack, just in this case taking advantage of something that is
currently invalid.

BTW, I'm no longer behind my suggestion, and was never strongly in
favor of it to begin with.

-

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

On Tue, Jul 9, 2019 at 2:50 PM ViliusCreator
 wrote:
>
> Lexer already sees `++` as operator, not `+` operator**s**. It can be hard to 
> implement something like that.
>
> ___
> 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: Removing the space in `a+ +b`?

2019-06-29 Thread Isiah Meadows
Just an update to you all: I'm only very weakly for this, and I'm okay
to rescind this suggestion.

-

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

On Fri, Jun 28, 2019 at 5:01 PM Waldemar Horwat  wrote:
>
> On 6/28/19 8:41 AM, Isiah Meadows wrote:
> > Currently, the production `a+ +b` requires a space to disambiguate it from 
> > the increment operator. However, `a++b` is not itself valid, as the postfix 
> > increment cannot be immediately followed by a bare identifier on the same 
> > line, nor can a prefix operator be preceded by one on the same line. Could 
> > the grammar be amended to include this production and make it evaluate 
> > equivalently to `a+ +b`
> >
> > AdditionExpression :: AdditionExpression `++` [no LineTerminator here] 
> > UnaryExpression
>
> Maybe it could, but the extra complexity really doesn't seem worth it, 
> particularly since you'd need the unusual line terminator restriction to 
> avoid breaking existing code.  Other uses of + don't have line terminator 
> restrictions.
>
>  Waldemar
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Removing the space in `a+ +b`?

2019-06-28 Thread Isiah Meadows
Currently, the production `a+ +b` requires a space to disambiguate it from
the increment operator. However, `a++b` is not itself valid, as the postfix
increment cannot be immediately followed by a bare identifier on the same
line, nor can a prefix operator be preceded by one on the same line. Could
the grammar be amended to include this production and make it evaluate
equivalently to `a+ +b`

AdditionExpression :: AdditionExpression `++` [no LineTerminator here]
UnaryExpression
-- 
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Proposal: Selector/Select Expression

2019-06-28 Thread Isiah Meadows
Note: the wildcard syntax `?.foo` would itself not require this. It'd
require a space after the `?` in ternaries if the Elvis operator proposal
`a ?? b` comes along (and a grammatical edit isn't made to clarify `??.`
gets parsed as `? ?.`), but it would not otherwise be ambiguous.

On Fri, Jun 28, 2019 at 11:25 Isiah Meadows  wrote:

> Agreed in that it's not ambiguous - you have to disambiguate it with a
> space for the same reason you have to use `a+ +b` instead of `a++b` in
> minified code to avoid ambiguity when specifying `a + +b`. So `a?.b:.c`
> would be invalid, but `a? .b:.c` is not.
>
> On Thu, Jun 27, 2019 at 16:48 Bob Myers  wrote:
>
>> Not exactly, since the optional chaining operator is `?.` with no space
>> in between.
>>
>> On Thu, Jun 27, 2019 at 1:37 PM Simon Farrugia 
>> wrote:
>>
>>> Also, without a leading token, a selector expr with the optional
>>> chaining operator inside a ternary operator would be ambiguous.
>>>
>>> ```
>>>
>>> const contactSelector = true ? .contacts.email : .contacts.phone;
>>>
>>> ```
>>>
>>>
>>> --
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
-- 
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Proposal: Selector/Select Expression

2019-06-28 Thread Isiah Meadows
If missing, the expectation is that it's return `undefined` just like how
`a.foo` returns `undefined` if `a` has no property `"foo"`. It's just
shorthand for `x => x.foo` and similar.

On Thu, Jun 27, 2019 at 20:30 guest271314  wrote:

> How can the Selector/Select Expression be used with
> `Array.prototype.find()`? What happens when the property is not defined?
>
> For example using the same code for more than one browser
>
> ```
> const stream = [canvasStream, videoTrack].find(({requestFrame: _}) => _);
> ```
>
> the property `requestFrame` is either defined or not defined at
> ```canvasStream``` or ```videoTrack``` depending on the implementation.
> Although the assigned variable can be reduced to 1 character at
> destructuring assignment, there is still the redundancy of writing ```_```
> again on the right side of ```=>```.
>
> If the property is not found, is the result ```undefined```?
>
> What is the least amount characters necessary using Selector/Select
> Expression with ```find()```?
>
> ```
> const stream = [canvasStream, videoTrack].find(=.requestFrame);
> ```
>
> ?
>
> On Thu, Jun 27, 2019 at 8:48 PM Bob Myers  wrote:
>
>> Not exactly, since the optional chaining operator is `?.` with no space
>> in between.
>>
>> On Thu, Jun 27, 2019 at 1:37 PM Simon Farrugia 
>> wrote:
>>
>>> Also, without a leading token, a selector expr with the optional
>>> chaining operator inside a ternary operator would be ambiguous.
>>>
>>> ```
>>>
>>> const contactSelector = true ? .contacts.email : .contacts.phone;
>>>
>>> ```
>>>
>>>
>>> ___
>> 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


Re: Re: Proposal: Selector/Select Expression

2019-06-28 Thread Isiah Meadows
Agreed in that it's not ambiguous - you have to disambiguate it with a
space for the same reason you have to use `a+ +b` instead of `a++b` in
minified code to avoid ambiguity when specifying `a + +b`. So `a?.b:.c`
would be invalid, but `a? .b:.c` is not.

On Thu, Jun 27, 2019 at 16:48 Bob Myers  wrote:

> Not exactly, since the optional chaining operator is `?.` with no space in
> between.
>
> On Thu, Jun 27, 2019 at 1:37 PM Simon Farrugia 
> wrote:
>
>> Also, without a leading token, a selector expr with the optional chaining
>> operator inside a ternary operator would be ambiguous.
>>
>> ```
>>
>> const contactSelector = true ? .contacts.email : .contacts.phone;
>>
>> ```
>>
>>
>> --
-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal Request

2019-06-27 Thread Isiah Meadows
Suggest it here, or if you prefer, you can also suggest it in IRC at
#tc39 on Freenode. People from TC39 are usually present here, and you
can also find them elsewhere, too. You can find more info here:
https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md#new-feature-proposals

-

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

On Wed, Jun 26, 2019 at 7:24 AM Joseph Akayesi  wrote:
>
> Requesting to send a proposal for a new feature in ES. Where can I share the 
> proposal?
> ___
> 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: Selector/Select Expression

2019-06-27 Thread Isiah Meadows
Generalize this far enough, and you wind up with something not far
from this: https://github.com/tc39/proposal-partial-application

-

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

On Wed, Jun 26, 2019 at 5:44 AM Michael Luder-Rosefield
 wrote:
>
> The more I read this proposal, the more I feel the ideal solution is a 
> preceding 'wildcard' character, to stand-in for a generic argument. If it 
> wasn't in (widespread!) use, I'd suggest an underscore: ```const f = _.prop 
> ```
>
> Since it is, though, we need another one. How about a double-colon, seeing as 
> it can represent property access on other languages? ```const f = ::prop ```, 
> ```const g = ::[compProp] ```, ```const h =  ::?optProp ```
>
> On Sun, 23 Jun 2019, 11:43 Simon Farrugia,  wrote:
>>
>> I was expecting that someone brings up the brackets property accessor at 
>> some point.
>> I would argue that there is a bit of syntactic inconsistency since usually 
>> when using the bracket accessors it is not preceded by a dot.
>> ```
>> const getEmail = user => user["contacts"].email; // No dot between user & 
>> ["contacts"].
>> const getEmail = .["contacts"].email;
>> ```
>> Having said that, the currently proposed Optional Chaining operator (Stage 
>> 2) does exactly that and more:
>> ```
>> obj?.prop   // optional static property access
>> obj?.[expr] // optional dynamic property access
>> func?.(...args) // optional function or method call
>> ```
>> So I'd say that there is consistency with what is currently being proposed.
>>
>> Regarding the Optional Chaining operator, which precedes the dot. How would 
>> that work?
>>
>> It would have to be something like this, if allowed.
>> ```
>>
>> const getEmail = user => user?.contacts.email;
>> const getEmail = ?.contacts.email;
>>
>> ```
>>
>> It does look odd at first, but it’s quite simple is you think about it. We 
>> are just omitting the initial part of the expression.
>>
>>
>>
>> More Examples with Optional Chaining operator:
>>
>> ```
>>
>> // With optional dynamic property access.
>>
>> const getUserEmail = user => user?.["contacts"].email;
>> const getUserEmail = ?.["contacts"].email;
>>
>>
>>
>> // With optional function or method call.
>>
>> const getJohnsEmail = getUserContacts =>  getUserContacts?.("John").email;
>> const getJohnsEmail = ?.("john").email;
>>
>> ```
>>
>>
>>
>> The beauty of what is being proposed is that there is nothing new to learn 
>> or any new weird operator introduced.
>>
>> Any weirdness one might find with the expressions above will already have 
>> been introduced by the Optional Chaining operator.
>>
>> The only thing this does is to allow you to omit the initial (redundant) 
>> part of the expression.
>>
>>
>>
>> ___
>> 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: Feature Request

2019-06-27 Thread Isiah Meadows
I've weakly suggested this in the past (sorry, buried in old list
discussions and IRC), but I haven't come up with something that 1.
doesn't have nearly the overhead of web workers, and 2. doesn't have
nearly the footguns of C's direct thread-based model that's mostly
emulated by practically every remotely major software programming
language not using CSP or actors/processes. The first is difficult to
avoid without avoiding message passing altogether, hence why
`SharedArrayBuffer` appeared in the first place. The second is
difficult to avoid if you want to minimize message passing overhead,
especially without immutable objects (which can usually be sent
without copy between threads of the same parent process).

Given Erlang's parallel programming model has proven itself to stand
the test of time (it's hardly changed since the 80s) and that others
(such as Ruby and some Java circles) are planning to adapt it, I feel
it might be worth waiting for this stage-0 proposal to make it in in
some form or another first, *then* pushing for language-level support
of parallelism: https://github.com/rricard/proposal-const-value-types/

-

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

-

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


On Tue, Jun 25, 2019 at 9:51 AM Robert Parham  wrote:
>
>
> Are there any threading proposals? If not, would anyone be interested in 
> creating one?
>
> Webworkers are great, but require separate files that just aren't always 
> convenient to maintain. I've
> created this wrapper for webworkers that allows users to create in-line 
> disposable threads, somewhat
> similar to threads in Java.
>
> https://gist.github.com/Pamblam/683d5ae429448adfa6d6e7fb30de39b2
>
> If we could get something similar implemented natively that would be very 
> cool.
>
> Robert "Gordie" Parham
> pamblam.com
> 813.616.0819
>
>
>
>
> ___
> 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-19 Thread Isiah Meadows
I get yet again that the forest here is being missed for the trees.

@guest271314 This isn't specific to any one IDE, and isn't even
specific to static tools. As mentioned before, this has applicability
to assertion libraries (like a userland version of Power Assert) as
well as other things. It's almost exclusively just quality-of-life
improvements to developers, but it's not specific to IDEs or even
static tooling.

-

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

On Mon, Jun 17, 2019 at 8:28 PM guest271314  wrote:
>
>
> > You have ignored the context from Jordan’s email (emphasis added):
>
>
>
> >> 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 })`.
>
>
> No, did not _ignore_ the context of the email.
>
>
> Simply have no reference point for relying on an external tool, that is, 
> essentially a text editor, to write and dynamically "refactor" code. Here, 
> the code will be tested outside of the text editor in short order once 
> composed.
>
>
> Was able to rename text at Mousepad and record the entire process within 20 
> seconds without needing to use ```nameof``` and without encountering any 
> issues such as mispelling the variable name or the text editor trying to 
> independently determine what the words am typing mean. The text editor is 
> just - a text editor.
>
>
> Perhaps other JavaScript users who rely on "refactoring tools" and "rename 
> refactoring" in an IDE can relate. Not able to gather the significance of 
> ```nameof``` here - as in each case the user has to write the name of the 
> variable anyway. To each their own.
>
>
> > VSCode is a popular editor that supports JavaScript *and* is a refactoring 
> > tool. Rename refactoring was the subject I was responding to.
>
>
>
>
>
> Was not previously aware or did not realize that the _individual choice_ to 
> use a particular text editor was a substantial reason to ask for change to 
> the entire JavaScript language in order for specific users to be able to 
> interact with an entirely different language.
>
>
> If VSCode is particularly "popular" why cannot VSCode be specified and 
> implemented by and for the users who rely on the text editor to interpret 
> what the users' intent is when writing code.
>
>
> In that case  ```mkvmerge``` should be specified as a JavaScript method. 
> ```webm``` is a "popular" (cannot help but to recollect "Popularity" 
> https://brendaneich.com/2008/04/popularity/) video container that is a subset 
> of the Matroska container, where if that method were specified in JavaScript 
> a user would be able to do ```mkvmerge({w: true, o: "int_all.webm":  i: 
> ["int.webm", "int1.webm", "intN.webm"]})``` instead of ```$ mkvmerge -w 
> -o int_all.webm int.webm + int1.webm``` at ```terminal```.
>
>
>
>
> On Mon, Jun 17, 2019 at 11:29 PM Ron Buckton  
> wrote:
>>
>> > How is VSCode related to JavaScript?
>>
>>
>>
>> You have ignored the context from Jordan’s email (emphasis added):
>>
>>
>>
>> >> 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 })`.
>>
>>
>>
>> VSCode is a popular editor that supports JavaScript *and* is a refactoring 
>> tool. Rename refactoring was the subject I was responding to.
>>
>>
>>
>> There are a number of reasons VSCode has implemented rename refactoring in 
>> this fashion. Not the least of which is that an editor cannot fully 
>> understand user intent. Let us say, for example, you are working with Gulp:
>>
>>
>>
>> ```
>>
>> const cwd /*1*/ = ".";
>>
>> gulp.src("*.js", { cwd /*2*/ });
>>
>> ```
>>
>>
>>
>> If you were to rename `cwd` at (1) and it *also* renamed the `cwd` property 
>> at (2), you would have introduced an error in the call because a `cwd` 
>> option to gulp has a special meaning. Since the editor doesn’t know the 
>> intent of the user may be to rename *both* symbols, it remains conservative 
>> and choses only to rename the binding and its references, producing:
>>
>>
>>
>> ```
>>
>> const currentDir = ".";
>>
>> gulp.src("*.js", { cwd: currentDir });
>>
>> ```
>>

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

2019-06-19 Thread Isiah Meadows
Because the declaration itself is hoisted. The TDZ only delays
*initialization*, not *declaration*.

- For `var`, the declaration is hoisted *and* it's automatically
initialized to `undefined` before executing any body code.
- For `function foo() { ... }`, the declaration is hoisted *and* the
value is automatically initialized to a new function object
encapsulating the function's body before executing any body code.
- For all other types, the declaration is hoisted, but it is *not*
possible to initialize it yet. It's initialized to `undefined` for
`let value;` when that statement is executed, the relevant function
object for `class Foo`, the RHS value for `let value = expr`/`const
value = expr`, and so on. (Most of the complexity is in destructured
bindings and default parameters, but it's not black magic, I promise.)
- Keep in mind it's possible to get a reference to an uninitialized
variable, even though it's not possible to access any value yet.

This mechanism already exists today, and `nameof` would just leverage
that mechanism. The static value would be computed *after* the
variable would have been linked (either at the global scope or after
the declaration exists), and only after falling back to the global
scope would the value fall back to a dynamic lookup and test.

-

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

On Sun, Jun 16, 2019 at 8:15 PM 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
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Sun, Jun 16, 2019 at 12:00 AM guest271314  wrote:
>> >
>> > ```
>> > const x = nameof y
>> > const y = 1;
>> > ```
>> >
>> > At line 1 adjacent to ```nameof``` how does the user even know that there 
>> > is a variable that will be declared named ```y```?
>> >
>> > What is the output of ```x``` where there is no variable named ```y``` 
>> > later declared?
>> >
>> > ```
>> > const x = nameof y
>> > const z = 1;
>> > ```
>> >
>> > On Sun, Jun 16, 2019 at 12:03 AM Ron Buckton  
>> > wrote:
>> >>
>> >> > What should occur where the code is
>> >>
>> >> It would be "y" in all 3 places.
>> >>
>> >> > ... is a proposal for _more_ than only getting the _name_ of an 
>> >> > _declared_ and _initialized_ variable?
>> >>
>> >> It is a proposal for getting the name of a _declared_ variable. Whether 
>> >> it is _initialized_ does not matter.
>> >>
>> >> > Should a ```RefefenceError``` _not_ be thrown simple because 
>> >> > ```nameof``` is used?
>> >>
>> >> No, an error is not thrown. ECMAScript is much more nuanced. Block scoped 
>> >> variables from 'let' or 'const' exist and can be *referenced* (via 
>> >> closure or export, currently) anywhere within the same block scope, even 
>> >> before they are initialized. Until they have been *initialized* (the line 
>> >> of code contain the declaration has been reached and evaluated), they 
>> >> exist in a "Temporal Dead Zone" (TDZ). Attempting to *dereference* them 
>> >> (i.e. access or store a value) while in this TDZ is what results in the 
>> >> ReferenceError.
>> >>
>> >> At no point does the `nameof` operator *dereference* the v

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

2019-06-16 Thread Isiah Meadows
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
cont...@isiahmeadows.com
www.isiahmeadows.com

On Sun, Jun 16, 2019 at 12:00 AM guest271314  wrote:
>
> ```
> const x = nameof y
> const y = 1;
> ```
>
> At line 1 adjacent to ```nameof``` how does the user even know that there is 
> a variable that will be declared named ```y```?
>
> What is the output of ```x``` where there is no variable named ```y``` later 
> declared?
>
> ```
> const x = nameof y
> const z = 1;
> ```
>
> On Sun, Jun 16, 2019 at 12:03 AM Ron Buckton  
> wrote:
>>
>> > What should occur where the code is
>>
>> It would be "y" in all 3 places.
>>
>> > ... is a proposal for _more_ than only getting the _name_ of an _declared_ 
>> > and _initialized_ variable?
>>
>> It is a proposal for getting the name of a _declared_ variable. Whether it 
>> is _initialized_ does not matter.
>>
>> > Should a ```RefefenceError``` _not_ be thrown simple because ```nameof``` 
>> > is used?
>>
>> No, an error is not thrown. ECMAScript is much more nuanced. Block scoped 
>> variables from 'let' or 'const' exist and can be *referenced* (via closure 
>> or export, currently) anywhere within the same block scope, even before they 
>> are initialized. Until they have been *initialized* (the line of code 
>> contain the declaration has been reached and evaluated), they exist in a 
>> "Temporal Dead Zone" (TDZ). Attempting to *dereference* them (i.e. access or 
>> store a value) while in this TDZ is what results in the ReferenceError.
>>
>> At no point does the `nameof` operator *dereference* the variable, so no 
>> error need be thrown.
>>
>> From: guest271314
>> Sent: Saturday, June 15, 4:29 PM
>> Subject: Re: Re: What do you think about a C# 6 like nameof() expression for
>> To: Ron Buckton
>> Cc: es-discuss@mozilla.org
>>
>>
>>
>>
>> What should occur where the code is
>>
>> ```
>> const x = nameof y
>> await new Promise(resolve => setTimeout(resolve, 10)); // should x be 
>> "y" here?
>> await new Promise(resolve => setTimeout(resolve, 20)); // should x be 
>> "y" here?
>> await Promise.all([new Promise(resolve => setTimeout(resolve, 30)), 
>> ...doStuff()]); // should x be "y" here?
>> const y = 1;
>> ```
>>
>> ?
>>
>> The immediately invoked arrow function example (where a 
>> ```RefeferenceError``` is thrown) appears to demonstrate that to output the 
>> expected result of ```nameof``` within the context of the code example
>>
>> ```
>> const x = nameof y
>> const y = 1;
>> ```
>>
>> is a proposal for _more_ than only getting the _name_ of an _declared_ and 
>> _initialized_ variable?
>>
>> Should a ```RefefenceError``` _not_ be thrown simple because ```nameof``` is 
>> used?
>>
>> On Sat, Jun 15, 2019 at 11:16 PM Ron Buckton  
>> wrote:
>>
>> ```
>> const x = nameof y
>> const y = 1;
>> ```
>>
>> `x` would have the value “y”. It would not matter if `y` were initialized or 
>> had yet been reached during execution. It does not deviate from the purpose 
>> of `let` or `const`, because you are not accessing the value of the 
>> identifier.
>>
>> Also consider that this is legal ECMAScript in a module:
>>
>> ```
>> export { y }
>> const y = 1;
>> ```
>>
>> The binding for `y` exists within the same block scope, it just has not yet 
>> been initialized. Exporting it via `export { y }`, closing over it via `() 
>> => y`, or accessing it via `nameof y` would all be the same. In all three 
>> cases you are accessing the *binding* of `y`, not the *value* of `y`. Even 
>> in the `() => y` case, you don’t access the *value* of `y` until you execute 
>> the function.
>>
>> From: guest271314 
>> Sent: Saturday, June 15, 2019 3:57 PM
>> To: Ron Buckton 
>> Cc: es-discuss@mozilla.org
>> Subject: Re: Re: What do you think about a C# 6 like nameof() expression for
>>
>> > 

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

2019-06-15 Thread Isiah Meadows
I've got a few code bases where I do a lot of stuff like `func(person,
"person")`, and it'd be pretty useful to avoid the duplication.

I'd prefer something more direct like `nameof binding`, `nameof
binding.key`, and `nameof binding[key]`, where it returns the expression at
that parameter position as the "name", with a more convoluted fallback
algorithm to handle destructuring and local references sensibly. (It should
only consider parse-time data, and it should always strip whitespace and
unnecessary parentheses to keep it on a single line.) The required stack
space for this is just a single object pointer, and it's not like you can
do weird things with `eval` with it.

For security, there is the concern of unexpected passing of data through
parameters (think: `getSensitive("sensitive string")` as a parameter), but
this can be addressed on the minifier side via a directive and on the
language side by blocking all name sharing cross-realm (making them just
canonical strings derived from values instead).

On Fri, Jun 14, 2019 at 09:05 Stas Berkov  wrote:

> Can we revisit this issue?
>
>
> In C# there is `nameof`, in Swift you can do the same by calling
>
> ```
>
> let keyPath = \Person.mother.firstName
>
> NSPredicate(format: "%K == %@", keyPath, "Andrew")
>
> ```
>
> Let's introduce `nameof` in ES, please.
>
>
> Devs from TypeScript don't want to introduce this feature in TypeScript
> unless it is available in ES (
> https://github.com/microsoft/TypeScript/issues/1579 )
>
> This feature is eagarly being asked by TypeScript community.
>
>
> I understand there are couple issues related to `nameof` feature in ES.
> They are: minification and what to do if user already has `nameof` function.
>
>
> Minification.
>
> 1. If your code to be minimized be prepared that variable names will also
> change.
>
> 2. (just a possibility) Minimizer can have option to replace
> `nameof(someVar)` with result of `nameof` function.
>
>
>
> What if user already has `nameof` function.
>
> 1. To maintain status quo we can user `nameof` function having priority
> over newly introduced language feature.
>
> 2. OR we can use `typeof` syntax, e.g. `nameof msg.userName` (// returns
> "userName" string)
> ___
> 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


Re: Proposal: rest operator in middle of array

2019-06-07 Thread Isiah Meadows
For your maintainability argument: adding extra arguments to those
functions is something I almost never do. And you'd have the same
exact issue with final rest parameters, just in a different position
(in the middle as opposed to in the end).

For debuggability, I don't see how it'd be a major issue unless you
already have an excessive number of *positional* parameters. In my
experience, the debuggability issues arise approximately when there's
just too many positional parameters, and factoring out the rest
parameter to an array doesn't really help this situation much. (That's
when object destructuring comes in handy.)

So not convinced either is any different than what it's like today.

Also, you aren't obligated to use a feature just because it exists - I
hardly ever use proxies, for instance, and I rarely need maps beyond
what objects give me, so I don't normally use them unless I need to
have reference types or mixed types as keys.

-

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

On Thu, Jun 6, 2019 at 2:22 PM kai zhu  wrote:
>
> -1 for maintainability and debuggability
>
> 1. maintainability
> if you want to extend the function with additional args,
> then you'll have to retroactively modify all existing calls to avoid 
> off-by-one argcount:
>
> ```js
> // if extending function with additional args
> function pad(targetLength, ...opts, data) ->
> function pad(targetLength, ...opts, data, meta)
>
> // then must retroactively append null/undefined to all existing calls
> pad(1, opt1, opt2, "data") ->
> pad(1, opt1, opt2, "data", null)
> ```
>
>
>
> 2. debuggability
> when debugging, it takes longer for human to figure out which arg is what:
>
> ```js
> // function pad(targetLength, ...opts, data)
> pad(aa, bb, cc, dd);
> pad(aa, bb, cc, dd, ee);
>
> // vs
>
> // function pad(targetLength, opts, data)
> pad(aa, [bb, cc], dd);
> pad(aa, [bb, cc, dd], ee);
> ```
>
>
>
> On Thu, Jun 6, 2019 at 11:54 AM Ethan Resnick  wrote:
>>
>> Long-time mostly-lurker on here. I deeply appreciate all the hard work that 
>> folks here put into JS.
>>
>> I've run into a couple cases now where it'd be convenient to use a rest 
>> operator at the beginning or middle of an array destructuring, as in:
>>
>> ```
>> const [...xs, y] = someArray;
>> ```
>>
>> Or, similarly, in function signatures:
>>
>> ```
>> function(...xs, y) { }
>> ```
>>
>> The semantics would be simple: exhaust the iterable to create the array of 
>> `xs`, like a standard rest operator would do, but then slice off the last 
>> item and put it in `y`.
>>
>> For example, I was working with some variable argument functions that, in FP 
>> style, always take their data last. So I had a function like this:
>>
>> ```
>> function match(...matchersAndData) {
>>   const matchers = matchersAndData.slice(0, -1);
>>   const data = matchersAndData[matchersAndData.length - 1];
>>   // do matching against data
>> }
>> ```
>>
>> Under this proposal, the above could be rewritten:
>>
>> ```
>> function reduce(...matchers, data) { /* ... */ }
>> ```
>>
>> Another example: a function `pad`, which takes a target length and a string 
>> to pad, with an optional padding character argument in between:
>>
>> ```
>> function pad(targetLength, ...paddingCharAndOrData) {
>>   const [paddingChar = " "] = paddingCharAndOrData.slice(0, -1);
>>   const data = paddingCharAndOrData[paddingCharAndOrData.length - 1];
>>
>>   // pad data with paddingChar to targetLength;
>> }
>> ```
>>
>> With this proposal, that could be rewritten:
>>
>> ```
>> function pad(targetLength, ...opts, data) {
>>   const [paddingChar = " "] = opts;
>>   // pad data with paddingChar to targetLength;
>> }
>> ```
>>
>> I'm curious if this has been considered before, and what people think of the 
>> idea.
>>
>> Obviously, if `...a` appeared at the beginning or middle of a list, there 
>> would have to be a fixed number of items following it, so a subsequent rest 
>> operator in the same list would not be allowed.
>>
>> Thanks
>>
>> ___
>> 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: syntactic sugar for extracting fields from objects

2019-06-05 Thread Isiah Meadows
Nit: 2A will reject thanks to TDZ semantics with `name` in the RHS
where it's defined in the LHS of the same statement. (Think of the
function body's lexical context as being in a block where parameters
are in a parent block context. The block variable shadows the parent
variable for the whole block and just initially starts as unset.) So
that error *will* get caught fairly quickly.

But aside from that:

I agree 1A is a bit too noisy, especially in the parameter side.

1B could be simplified a bit. Have you considered leveraging the
existing object rest+spread and just standard property accesses? This
is technically shorter than your suggestion and is much less
cluttered. (I do see a frequent pattern of premature destructuring
when it's shorter, easier, and simpler *not* to.)

```
return {...state.user.{firstName, lastName}, url: state.common.currentPageURL}
```

2A could be fixed to work like this, which is technically shorter than
your example:

```
const resp = await sendToServer({name})
return {ok: true, payload: {name: resp.name}}
```

And likewise, you could simplify 2B to this:

```
const resp = await sendToServer({name})
return {ok: true, payload: resp.{name}}
```

-

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

On Tue, May 28, 2019 at 3:13 PM Григорий Карелин  wrote:
>
> Here are another examples, where "destructuring picking" I suggest whould be 
> helpful.
> ==1A Now (redux related)
> ```
> function mapStateToProps({user: {firstName, lastName}, common: 
> {currentPageURL: url}}) {
>   return {firstName, lastName, url};
> }
> ```
> ==1B Proposal
> ```
> function mapStateToProps(state) {
>   return {{firstName, lastName from state.user}, {currentPageURL as url from 
> state.common}};
> }
> ```
>
> Shorter!
>
> ==2A Now
> ```
> async function saveNewUserName(name) {
>   const {name} = await sendToServer({name});
>
>   return {ok: true, payload: {name}}; // oh wait, which name is it again? 
> Argument or response?
> }
> ```
> == 2B Proposal
> ```
> async function saveNewUserName(name) {
>   const resp = await sendToServer({name});
>
>   return {ok: true, {name from response}};
> }
> ```
> No accidental shadowing.
>
> I know, I know, you can achieve all that without new syntax, via naming your 
> variables properly and using long explicit expressions. But I think some 
> sugar won't hurt.
> After all, remember destructuring? There's no reason to use it other than 
> it's cool and short and expressive.
>
>
> вт, 28 мая 2019 г. в 21:49, guest271314 :
>>>>
>>>> ```
>>>> let obj = {otherData: "other data"};
>>>> ({firstName:obj.firstName, lastName:obj.lastName} = user.profile);
>>>> ```
>>>>
>>>> I don't understand this.
>>
>>
>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assigning_to_new_variable_names
>>
>>> He's looking for a terser
>>
>>
>> Is the proposal to golf destructuring assignment?
>>
>> The proposed destructuring assignment syntax example is 25 characters less 
>> than the non-destructing assignment example, which is terser.
>>
>> One observation about the proposed syntax is that the values set at the 
>> target object would be set from the identifier on the left side of 
>> ```from``` which is similar to
>>
>> ```
>> var o = {x:1};
>> console.log(o.x = 2); // 2
>> ```
>>
>> though how will the property name be set at the object at target object 
>> instead of `{"2":2}`? How does the engine know when the expected result is 
>> ```{"x":2}``` and not ```{"2":2}```? Certainly such functionality can be 
>> designed, for example, using the proposed key word ```from```.
>>
>> If more terse code is one of the features that would be achieved, why are 
>> the wrapping `{}` around ```from`` necessary?
>>
>> > moire elegant way to do it,
>>
>> "elegant" is subjective
>>
>> > which hopefully would be moire semantic, less bug-prone, more 
>> > type-checkable (for typed variants of the language), more reminiscent of 
>> > existing syntax such as deconstruction, and potentially more optimizable 
>> > by engines.
>>
>> What is bug prone about the code examples at OP?
>>
>> This proposal would resolve the issue of currently, in general, having to 
>> write the property name twice.
>>
>>
>>
>> On Tue, May 28, 2019 at 2:47 PM Bob Myers  wrote:
>>>>
>>>> ```
>>>> let obj = {otherData: "other data"};
>>>&g

Re: RegExp `x` flag

2019-06-05 Thread Isiah Meadows
1. Very. Just strip the extra whitespace and replace it with the
non-`/x` version.
2. Whitespace is negligible in parsing performance, and regexps have a
fairly simple grammar to begin with. (It can be done with a single
character of lookahead easily and the only thing that can nest more
than a single level is parentheses.) 90% of the actual time spent on
them is on compilation and `/x` would have zero effect on that.

The issue of detection is actually pretty trivial: a `/` is assumed to
be division any time you can continue an expression, and regexps are
only consumed when no binary operator could potentially be expected.
It's a rather obscure edge case often left out of ASI posts, one I've
yet to even hear about being used, although I could contemplate it
being used in code bases which use `cond && foo()` instead of `if
(cond) foo()` and `cond || foo()` instead of `if (!cond) foo()`.

`new RegExp(multilineString)` *is* a valid fallback, something I
already use today quite a bit, but I'd prefer to use one or the other
consistently for static regexps.

-

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

On Tue, Jun 4, 2019 at 12:36 AM kai zhu  wrote:
>
> 1. is this minifier-friendly?
> 2. is parsing-impact minimal enough to not affect load-times?  
> regexp-detection/bounding is among the most expensive/complex part of 
> javascript-parsing.
>
> those 2 nits aside, i'm on the fence.  regexp-spaghetti is a valid painpoint, 
> and jslint's author has expressed desire for multiline regexp [1].  otoh, 
> there is a good-enough solution by falling-back to constructor-form to 
> improve readability:
>
> ```js
> // real-world spaghetti-regexp code in jslint.js
> const rx_token = 
> /^((\s+)|([a-zA-Z_$][a-zA-Z0-9_$]*)|[(){}\[\],:;'"~`]|\?\.?|=(?:==?|>)?|\.+|[*\/][*\/=]?|\+[=+]?|-[=\-]?|[\^%]=?|&[&=]?|\|[|=]?|>{1,3}=?|<
> // vs
>
> /*
>  * break JSON.stringify(rx_token.source)
>  * into multiline constructor-form for readability
>  */
> const rx_token = new RegExp(
> "^("
> + "(\\s+)"
> + "|([a-zA-Z_$][a-zA-Z0-9_$]*)"
> + "|[(){}\\[\\],:;'\"~`]"
> + "|\\?\\.?"
> + "|=(?:==?|>)?"
> + "|\\.+"
> + "|[*\\/][*\\/=]?"
> + "|\\+[=+]?"
> + "|-[=\\-]?"
> + "|[\\^%]=?"
> + "|&[&=]?"
> + "|\\|[|=]?"
> + "|>{1,3}=?"
> + "|< + "|!(?:!|==?)?"
> + "|(0|[1-9][0-9]*)"
> + ")(.*)$"
> );
> ```
>
> [1] github jslint-issue #231 - ignore long regexp's (and comments)
> https://github.com/douglascrockford/JSLint/pull/231#issuecomment-421881426
>
>
>
> On Mon, Jun 3, 2019 at 10:27 PM Jacob Pratt  wrote:
>>
>> Even if this flag were restricted to constructors instead of both 
>> constructors and literals, it could be worthwhile.
>>
>> On Mon, Jun 3, 2019, 23:19 Isiah Meadows  wrote:
>>>
>>> Let me clarify that previous message: I mean "newline restriction" in
>>> the sense that newlines are not permitted in regexp literals. A `/x`
>>> flag would make removing it practically required for it to have any
>>> utility.
>>>
>>> -
>>>
>>> Isiah Meadows
>>> cont...@isiahmeadows.com
>>> www.isiahmeadows.com
>>>
>>> On Mon, Jun 3, 2019 at 11:14 PM Isiah Meadows  
>>> wrote:
>>> >
>>> > I would personally love this (as well as interpolations in regexp
>>> > literals). I do have a concern about whether removing the newline
>>> > restriction creates ambiguities with division, but I suspect this is
>>> > *not* the case.
>>> >
>>> > -
>>> >
>>> > Isiah Meadows
>>> > cont...@isiahmeadows.com
>>> > www.isiahmeadows.com
>>> >
>>> > On Mon, Jun 3, 2019 at 10:03 PM Jacob Pratt  wrote:
>>> > >
>>> > > Has there been any previous discussion of adding the `x` flag to JS? It 
>>> > > exists in other languages, and can make relatively complicated regex 
>>> > > _much_ easier to read. It also allows for comments, which are 
>>> > > incredibly helpful when trying to understand some regexes.
>>> > >
>>> > > For prior art, XRegExp has this flag (though I've no idea to figure out 
>>> > > how frequently it's used), as do a few other languages.
>>> > >
>>> > > Quick overview: https://www.regular-expressions.info/freespacing.html
>>> > >
>>> > > Language references:
>>> > > Python: https://docs.python.org/3/library/re.html#re.X
>>> > > Rust: https://docs.rs/regex/1.1.6/regex/
>>> > > XRegExp: http://xregexp.com/xregexp/flags/#extended
>>> > > .NET: 
>>> > > https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference#regular-expression-options
>>> > >
>>> > > 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
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: RegExp `x` flag

2019-06-03 Thread Isiah Meadows
Let me clarify that previous message: I mean "newline restriction" in
the sense that newlines are not permitted in regexp literals. A `/x`
flag would make removing it practically required for it to have any
utility.

-----

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

On Mon, Jun 3, 2019 at 11:14 PM Isiah Meadows  wrote:
>
> I would personally love this (as well as interpolations in regexp
> literals). I do have a concern about whether removing the newline
> restriction creates ambiguities with division, but I suspect this is
> *not* the case.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
> On Mon, Jun 3, 2019 at 10:03 PM Jacob Pratt  wrote:
> >
> > Has there been any previous discussion of adding the `x` flag to JS? It 
> > exists in other languages, and can make relatively complicated regex _much_ 
> > easier to read. It also allows for comments, which are incredibly helpful 
> > when trying to understand some regexes.
> >
> > For prior art, XRegExp has this flag (though I've no idea to figure out how 
> > frequently it's used), as do a few other languages.
> >
> > Quick overview: https://www.regular-expressions.info/freespacing.html
> >
> > Language references:
> > Python: https://docs.python.org/3/library/re.html#re.X
> > Rust: https://docs.rs/regex/1.1.6/regex/
> > XRegExp: http://xregexp.com/xregexp/flags/#extended
> > .NET: 
> > https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference#regular-expression-options
> >
> > 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: RegExp `x` flag

2019-06-03 Thread Isiah Meadows
I would personally love this (as well as interpolations in regexp
literals). I do have a concern about whether removing the newline
restriction creates ambiguities with division, but I suspect this is
*not* the case.

-

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

On Mon, Jun 3, 2019 at 10:03 PM Jacob Pratt  wrote:
>
> Has there been any previous discussion of adding the `x` flag to JS? It 
> exists in other languages, and can make relatively complicated regex _much_ 
> easier to read. It also allows for comments, which are incredibly helpful 
> when trying to understand some regexes.
>
> For prior art, XRegExp has this flag (though I've no idea to figure out how 
> frequently it's used), as do a few other languages.
>
> Quick overview: https://www.regular-expressions.info/freespacing.html
>
> Language references:
> Python: https://docs.python.org/3/library/re.html#re.X
> Rust: https://docs.rs/regex/1.1.6/regex/
> XRegExp: http://xregexp.com/xregexp/flags/#extended
> .NET: 
> https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference#regular-expression-options
>
> 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: how many async-modules can js-app practically load?

2019-06-03 Thread Isiah Meadows
That would be pure ES6 running in Chrome natively, before I introduced
Webpack or Rollup to generate the bundle. Transitioning to those is as
simple as:

1. Installing the relevant build tool.
2. Creating the relevant config file.
3. Changing the HTML file to load the bundle instead of the entry point.

I generally use either a bundler in both dev + prod or just a bunch of
ES6 modules in dev + prod - I don't mix them, because it makes it
harder to maintain in the future. (Native for dev, Rollup for prod got
unwieldy within literally just the entry point. Having to switch
between entry points is itself enough to get in the way of things.)

-

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

On Fri, May 31, 2019 at 1:40 PM kai zhu  wrote:
>
> > Oh, and yes, I've loaded upwards of 50-100 modules in development. 20
> modules is *easy* to achieve in single-page apps.
>
> was that with some combination of babel/rollup/webpack or pure-es6?
> if i want to develop a pure-es6 webapp (no babel), how would i transition 
> from development-mode (20 es-module files) -> production-mode (1 rollup file)?
>
>
> On Fri, May 31, 2019 at 10:47 AM Isiah Meadows  wrote:
>>
>> If it's bundled by Rollup or Webpack into a single bundle, it's
>> equivalent to a single `

Re: how many async-modules can js-app practically load?

2019-05-31 Thread Isiah Meadows
If it's bundled by Rollup or Webpack into a single bundle, it's
equivalent to a single 

Re: how many async-modules can js-app practically load?

2019-05-24 Thread Isiah Meadows
There's two main reasons why it scales:

1. Modules are strongly encapsulated while minimizing global pollution.
2. The resolution algorithm applies the same logic no matter how many
modules are loaded.

It's much easier for it to scale when you write the code unaware of
how many modules you might be loading and unaware of how deep their
dependency graph is. Fewer assumptions here is key. It's an
engineering problem, but a relatively simple one.

If you want a short example of how sync module resolution works, you
can take a look at this little utility I wrote:
https://github.com/isiahmeadows/simple-require-loader. That doesn't
asynchronously resolve modules, but it should help explain the process
from a synchronous standpoint. Asynchronous loading differs only in
that it takes more code to express the same logic and you have to take
into account concurrent requests (and you need to cache the request,
not the result), but it's otherwise the same from 1km away.

-

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

On Thu, May 23, 2019 at 10:49 AM kai zhu  wrote:
>
> actually, i admit i don't know what i'm talking about.  just generally 
> confused (through ignorance) on how large-scale es-module dependencies 
> resolve when loaded/imported asynchronously.
>
> On Wed, May 22, 2019 at 10:42 PM Logan Smyth  wrote:
>>
>> Can you elaborate on what loading state you need to keep track of? What is 
>> the bottleneck that you run into? Also to be sure, when you say async-load, 
>> do you mean `import()`?
>>
>> On Wed, May 22, 2019, 20:17 kai zhu  wrote:
>>>
>>> i don't use es-modules.
>>> but with amd/requirejs, I start having trouble with module-initializations 
>>> in nodejs/browser at ~5 async modules (that may or may not have 
>>> circular-references).  10 would be hard, and 20 would be near inhuman for 
>>> me.
>>>
>>> can we say its somewhat impractical for most applications to load more than 
>>> 50 async modules (with some of them having circular-references)?  and 
>>> perhaps better design/spec module-loading mechanisms with this usability 
>>> concern in mind?
>>>
>>> p.s. its also impractical for me to async-load 5 or more modules without 
>>> using globalThis to keep track of each module's loading-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: Re: Indexing HTML Attributes and Unique Indexes

2019-05-24 Thread Isiah Meadows
You'd have better luck asking for this feature in
https://discourse.wicg.io. ES Discuss is about the JS language itself
and the related ECMAScript spec, not the Web APIs that are implemented
in most browsers, usually separately to the JS implementations
themselves.

-

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

On Thu, May 23, 2019 at 10:05 AM Randy Buchholz  wrote:
>
> Full Table Scans and Unique indexes are database concepts (that's the DBA 
> reference). When a database searches for a record based on a column value, it 
> might look at every record in the table to find the matches - scan the entire 
> (full) table, in the order the records were inserted or stored. To speed this 
> up, we can create indexes on table columns or column groups. These are like 
> ordered maps or hash tables. To find a record, more efficient searches can be 
> done against the indexes to find the records. Indexes can also act as 
> constraints. A "Unique Index" is a constraint that checks a table to see if a 
> value exists before inserting it in the table and adding it to the index. 
> Indexing has a trade-off. It slows inserting, but improves searching. While 
> understanding that databases and browsers are worlds apart, a foundational 
> part of database engines is searching, just like it is in DOM manipulation. 
> Indexing can provide orders of magnitude performance improvements when 
> reading/search
 in
>  g in databases. It seemed worth seeing if the concept translated across 
> technologies.
>
> Without any optimizations, an attribute search on a document would look at 
> each node, and then at each attribute of the node to find a match - Full 
> Table Scan. This makes searches very slow. At an absurd extreme, we could 
> index everything, making startup very slow and eating memory, but making some 
> searches very fast.  The balanced approach is to implement "indexing" 
> ourselves (using any of the mentioned approaches) to get the best level.
>
> About the code/HTML, it is dynamic and real-time. It is loaded over 
> WebSockets, and the elements are talking to the backend in real-time over the 
> sockets. I'm using an original (Trygve Reenskaug) MVC approach. Essentially, 
> each Web Component is an MVC component, with the HTML/elements and code 
> accessed only through the controller. I am looking at the incoming code for 
> cases where several searches ae being performed on the same attribute (or 
> element). I give these a generated `id`,  create indexes on them, and expose 
> them as properties on the controller. The underlying framework uses a set of 
> common attributes that are searched on a lot, but only for a small set of 
> elements. These are also indexed. So at the cost of slower startup (offset to 
> some degree by doing some of this in a Web Worker and/or server-side), I can 
> read and write "Form Fields" quickly.
>
> Many language features are implemented to wrap or optimize common or 
> repetitive use cases, or to move code to a more efficient part of the 
> architecture. Indexing can do both. Without doing things server-side or in 
> Workers, the indexing consumes UI cycles. Adding an indexing "hint" could 
> allow all or part of this code to be moved back into the "system" or C++ 
> layer. (e.g., into `querySelect` internals supported by low-level map stores) 
> Or to parsing (like I'm doing), taking some of the repetitive work off the UI 
> and developers hands.
>
> ___
> 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-20 Thread Isiah Meadows
My bad. I should've known that. :-)

(I've looked *way* too deeply into the React/Redux ecosystem to have
any sort of excuse on this one.)

-

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

On Wed, May 15, 2019 at 11:39 PM Jordan Harband  wrote:
>
> (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. `

Re: Proposal: Add new 'Matrix' object

2019-05-15 Thread Isiah Meadows
Check out the old (and retracted) SIMD.js proposal that aimed to bring SIMD
support to JS and the related offshoot that attempted to cover WebAssembly
interop as well.

https://github.com/tc39/ecmascript_simd
https://github.com/stoklund/portable-simd/blob/master/README.md

Also, WebAssembly has a proposal, spearheaded from that work with JS, to
try to bring SIMD support to it. The WebAssembly proposal is considerably
lower level, but has broad implementor interest.

https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md

Hardware SIMD and matrices may seem like two entirely different things, but
a large area of overlap exists between small matrix math and CPU vector
instructions. Those instruction sets were designed with coordinate, vector,
and small matrix math in mind. For instance:

- 2x2 matrix multiplication is maybe a dozen or so SSE instructions in
modern Intel x86-64 assembly.
- Scalar matrix multiplication is only a single "multiply vector by scalar"
instruction.
- 2x2 discriminant is a swizzle, a multiply, clear top two lanes, and
horizontal subtract

And even with larger data sets, vector instructions can and do help.
(Consider BLAS.)

On Sun, May 12, 2019 at 05:51 Ed Saleh  wrote:

> Hello,
>
> Matrices are widely used today in in Computer Science, Engineering, and
> AI. I am proposing a new object type of `Matrix([ []... ])` which would
> make working with matrices easier, easily doing operations such matrices
> `multiplication` and `addition`.
>
> Thank you,
> ___
> 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


Re: Proposal: native XML object support.

2019-05-15 Thread Isiah Meadows
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


Re: Proposal: Symbol.inObject well-known symbol to customize the "in" operator's behavior

2019-05-12 Thread Isiah Meadows
This example could be fixed by passing `{}` as the proxy target.

On Fri, May 10, 2019 at 01:23 Claude Pache  wrote:

>
>
> Le 9 mai 2019 à 23:17, Tom Barrasso  a écrit :
>
> If this Symbol were seriously considered I believe it would expand the
> meaning of the in operator as you’re correct, this is definitely not it’s
> current intention.
>
>
> The `in` operator has a well-defined meaning, that *by design* you can’t
> ignore even with the fanciest proxy. (And no, there is no hope for
> introducing a new mechanism that allows to overcome those limitations,
> since they are by design.)
> Consider for example the following proxy around a String object:
>
> ```js
> function conflateInAndIncludes(str) {
> return new Proxy(Object(str), {
> has(target, key) { return str.includes(key) }
> })
> }
>
> var FrankensteinFood = conflateInAndIncludes("food");
>
> "foo" in FrankensteinFood // true, yeah!
> "bar" in FrankensteinFood // false, yeah!
> "length" in FrankensteinFood // TypeError: proxy can't report a
> non-configurable own property '"length"' as non-existent
> ```
>
>
> —Claude
> _______
> 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


Re: Proposal: Symbol.inObject well-known symbol to customize the "in" operator's behavior

2019-05-09 Thread Isiah Meadows
There's several ways proxies can change the result of `in`:

- Directly via `handler.has(target, key)` (returns boolean)
- Indirectly via `handler.getOwnPropertyDescriptor(target, key)` (returns
existing descriptor or `undefined` if missing)
- Indirectly via `handler.getPrototypeOf(target)' (returns relevant
prototype)

The proxy trap `has` is almost a direct substitute for your
`Symbol.inObject` in most cases, provided you're okay with keys getting
stringified.

On Thu, May 9, 2019 at 17:17 Tom Barrasso  wrote:

> Thanks interesting, I hadn’t realized it was possible to “trap” the in
> operator using Proxy. I may be wrong, but I don’t think Proxy is capable of
> operating on the prototype chain. Specifically, I don’t think you can
> change the behavior of the in operator for all Strings (which I’m sure many
> would prefer).
>
> If this Symbol were seriously considered I believe it would expand the
> meaning of the in operator as you’re correct, this is definitely not it’s
> current intention.
>
> Tom
>
> On Thu, May 9, 2019 at 4:39 PM Claude Pache 
> wrote:
>
>>
>>
>> Le 9 mai 2019 à 20:52, Tom Barrasso  a écrit :
>>
>> Like Symbol.hasInstance but for the "in" operator.
>> This symbol would work for both native and user-defined objects.
>>
>> **Example implementation** prototyping native object:
>>
>> ```js
>> String.prototype[Symbol.inObject] =
>>   function(searchString) {
>> return this.includes(searchString)
>> }
>> ```
>>
>>
>> **Example implementation* *for user-defined object:
>>
>> ```js
>> function range(min, max) => ({
>> [Symbol.inObject]: (prop) => {
>> return (prop >= min && prop <= max)
>> }
>> })
>> ```
>>
>>
>> **Example usage**:
>>
>> ```js
>> ("foo" in "food")// true
>> (14 in range(1, 25)) // true
>> ```
>>
>>
>> Those two examples seem to give to the `in` operator a meaning that it
>> was not intended to have. The `in` operator is specifically meant to check
>> whether a given property exists in a given object.
>>
>> Also, there already exists a way to customise the behaviour of the `in`
>> operator, namely by using a Proxy.
>>
>> —Claude
>>
> ___
> 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


Re: Re: Actual WeakSet Use Cases

2019-04-28 Thread Isiah Meadows
You can with private properties. Verified this in Chrome's console.
(Chrome is currently shipping private properties by default.)

```js
class A { constructor(arg) { return arg } }
class B extends A {
#tag
static isB(value) {
try {
value.#tag
return true
} catch {
return false
}
}
}

var object = Object.freeze({foo: true})
new B(object)
console.log(B.isB(object)) // logs `true`
```

This may seem very odd, but it's consistent with the concept of
private fields being sugar for weak maps.

-

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

On Tue, Apr 23, 2019 at 9:32 AM Michał Wadas  wrote:
>
> You can't do "branding" by properties on frozen objects.
>
> On Tue, 23 Apr 2019, 13:44 Andy Earnshaw,  wrote:
>>
>> This is pretty much what I used it for in a previous job role. We loaded and 
>> unloaded various iframes, registering APIs and custom elements inside them, 
>> adding the `window` object to a WeakSet so the initialisation only ran once.
>>
>> On Tue, 23 Apr 2019 at 10:26, Andrea Giammarchi 
>>  wrote:
>>>
>>> WeakSet can be very useful in general to avoid *any* object to be 
>>> visited/setup twice, not just those coming from user-land classes.
>>>
>>> Circular references, mixins, DOM nodes one-off events handling, and so on 
>>> and so fort.
>>>
>>> On Mon, Apr 22, 2019 at 8:26 PM #!/JoePea  wrote:
>>>>
>>>> (I edited the broken format of my previous post)
>>>>
>>>> What other use cases are there?
>>>>
>>>> On Mon, Apr 22, 2019 at 11:20 AM #!/JoePea  wrote:
>>>>>
>>>>> > WeakSets are perfect for branding and are how I would expect web 
>>>>> > platform class branding to be explained.
>>>>> >
>>>>> > ```js
>>>>> > const foos = new WeakSet();
>>>>> >
>>>>> > class Foo {
>>>>> >   constructor() {
>>>>> > foos.add(this);
>>>>> >   }
>>>>> >
>>>>> >   method() {
>>>>> > if (!foos.has(this)) {
>>>>> >   throw new TypeError("Foo.prototype.method called on an 
>>>>> > incompatible object!");
>>>>> > }
>>>>> >   }
>>>>> > }
>>>>> > ```
>>>>>
>>>>> Just curious, is that effectively the same as what the (current) [private 
>>>>> fields proposal](https://github.com/tc39/proposal-class-fields) offers?
>>>>>
>>>>> ```js
>>>>> class Foo {
>>>>>   #isFoo = true
>>>>>
>>>>>   method() {
>>>>> if (this.#isFoo) {
>>>>>   throw new TypeError("Foo.prototype.method called on an incompatible 
>>>>> object!");
>>>>> }
>>>>>   }
>>>>> }
>>>>> ```
>>>>>
>>>>> - 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
>
> ___
> 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: Symbol.inspect

2019-04-05 Thread Isiah Meadows
Yeah, I agree that until the ECMAScript spec defines any I/O APIs, it
doesn't belong in the spec. The spec is great for things that involve
pure data processing, but anything beyond that should be left to
embedders ("hosts" in the spec) to define.

I do feel that a separate spec dependent on ES should exist for stuff
that goes above and beyond simple data processing but is still broadly
useful in standard mobile/desktop/browser/server runtimes, like:

- Workers
- Web requests, specifically just the `fetch(string, opts?)` part +
associated response APIs
- Native cryptography APIs
- WebAssembly integration
- Off-screen GPU access with permitted CPU fallback, useful for image
processing and large-scale data processing on server-side and
client-side

This would be things the *host* would implement, ideally as standard
library modules, not the *engine*. Each of these would be optional,
but the HTML spec should require hosts to implement most modules
within it.

I've filed 
https://github.com/tc39/proposal-javascript-standard-library/issues/47
to elaborate on this further.

-----

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


On Thu, Apr 4, 2019 at 9:18 PM Logan Smyth  wrote:
>
> Symbols seems like a good way to do this, but since the ECMA spec doesn't 
> define anything about IO, I don't think this would be their responsibility. 
> This seems more like something the console API spec would expose, e.g. 
> `console.inspect`, where the `Symbol.XX` namespace would be reserved for 
> ECMAScript-builtin symbols.
>
> On Thu, Apr 4, 2019 at 5:44 PM Sultan  wrote:
>>
>> Like Symbol.iterator, a Symbol.inspect symbol for use in implementing 
>> cross-platform console display introspection.
>>
>> Currently node has something akin to this with a magic inspect method on 
>> objects.
>>
>> This would pave a cow path for how different platforms can afford this 
>> ability to consumers without each inventing their own heuristic, i.e in the 
>> browser i might have an exotic object that i want console.error to display a 
>> toString payload instead of the objects shape.
>> ___
>> 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: Let async generators directly await an incoming promise

2019-04-01 Thread Isiah Meadows
Filed https://github.com/tc39/ecma262/issues/1497 to track this.
Sounds to me like a spec bug.

-

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

-

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


On Mon, Apr 1, 2019 at 7:00 AM Simo Costa  wrote:
>
> Currently the following illustrative syntax is forbidden:
> ```js
> obj = {
> async*[Symbol.asyncIterator]() {
> const res = await yield;
> // do stuff with res
>  }
> }
> ```
> Used in this way (simple example):
> ```js
> const ait = [Symbol.asyncIterator]();
>
> ait.next();
> ait.next(p); // p is a Promise
> ```
>
> We cannot directly write `await yield`. Is there any particular reason?
> We have to write:
> ```js
> obj = {
> async*[Symbol.asyncIterator]() {
> const p = yield;
> const res = await p;
> // do stuff with res
>  }
> }
> ```
>
>
>
>
> Mail priva di virus. www.avast.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 For A New Alternative Keyword To “this” For Classes

2019-03-18 Thread Isiah Meadows
UX workflows aren't all of JS. Classes exist for many more reasons than
that, and 99% of my classes are for abstracting non-trivial business logic
and ensuring *those* are easily testable, not directly UI/UX.

-

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


On Sun, Mar 17, 2019 at 2:35 AM kai zhu  wrote:

> *rant warning*
>
> -1 because classes generally have little-value in UX-workflow programming.
>
> the example class RequestManager (given in this discussion), realistically
> has little reusability-value -- its no better than employing a throwaway
> static-function (both are equally likely to get rewritten each time
> UX-workflow features are added.).
>
> for example, a common feature-request is adding visual-progress-bar.
>  there is no "simple" way to extend RequestManager to do this, other than
> significant-refactoring of the base-class (and risk breaking
> class-dependencies downstream).
>
> some other common UX feature-requests that would likely invalidate
> "reusability" of your class-based design include:
>
> 1. needing to upload a binary-file (social-images, receipt-signatures,
> screenshots, etc...)
> 2. needing to upload multiple binary-files in parallel (keeping track of
> timeouts of each)
> 3. needing to upload multiple binary-files in parallel (keeping track of
> timeouts of each),
> and then download their thumbnail-previews from server to visually
> confirm uploads were correct
> 4. needing to make parallel http-requests from 3rd-party sources and
> "joining" the response-data
> 5. needing the sign-up-page to additionally pre-validate
> email / username / mobile-number / credit-card / etc... before
> form-submission to server
>
> many frontend-engineers with experience "extending" products with
> additional UX-workflow features, know its rarely as simple as modifying
> some class-methods and be done with it -- it oftentimes require rewriting
> nearly every-piece-of-code that touches the given workflow needing
> enhancement.
>
> p.s. -- here's a "simple" fully-working UX-example [1] on how to add
> visual-progress-bar to http-requests.  if i had to additionally add some of
> the other UX-features mentioned above, it would likely entail me completely
> rewriting the throwaway static-function, rather than waste time trying to
> extend it.
>
> [1] https://jsfiddle.net/kaizhu256/t9ubdenf/
>
> ```html
> 
> /* jslint utility2:true */
> /* csslint ignore:start */
> *,
> *:after,
> *:before {
> box-sizing: border-box;
> }
> /* csslint ignore:end */
> body {
> background: #eee;
> font-family: Arial, Helvetica, sans-serif;
> font-size: small;
> }
> input {
> width: 100%;
> }
> textarea {
> font-family: Consolas, Menlo, monospace;
> font-size: smaller;
> overflow: auto;
> width: 100%;
> }
> 
>
> 
>
> ajax-request
> {
> "method": "GET",
> "url": "https://api.github.com/orgs/octokit/repos;,
> "headers": {
> "accept": "application/vnd.github.v3+json"
> },
> "data": "hello world!"
> }
>
> submit ajax-request
>
> ajax-response
> 
>
> 
> /*jslint browser*/
> (function () {
> "use strict";
> var local;
> local = {};
> window.local = local;
>
> local.ajax = function (opt, onError) {
> /*
>  * simple, throwaway ajax-function that can be easily rewritten
>  * to accomodate new [async] ux-features
>  */
> var resHandler;
> var xhr;
> opt.headers = opt.headers || {};
> opt.method = opt.method || "GET";
> xhr = new XMLHttpRequest();
> // open url
> xhr.open(opt.method, opt.url);
> // set req-headers
> Object.entries(opt.headers).forEach(function (entry) {
> xhr.setRequestHeader(entry[0], entry[1]);
> });
> // send data
> xhr.send(opt.data);
> // init request-handling
> resHandler = function (evt) {
> /*
>  * this function will handle ajax-response
>  */
> switch (evt.type) {
> case "abort":
> case "error":
> // decrement ajaxProgressCounter
> local.ajaxProgressCounter = Math.max(
> local.ajaxProgressCounter - 1,
> 0
> );
> onError(new Error(evt.type), xhr);
> break;
> case "load":
>

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

2019-03-13 Thread Isiah Meadows
Assuming Babel can get ahold of unmodified builtins, even if it's only
during `@babel/runtime` initialization, it could still break that wrapper.
`core-js` itself uses this trick extensively to dodge otherwise observable
side effects in all of its wrappers. 

(Babel *might* be invoking `wm.get(this)` and `wm.set(this)`, but it should
really be binding those on initialization where possible.)
On Tue, Mar 12, 2019 at 14:36 Ranando King  wrote:

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

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

2019-03-12 Thread Isiah Meadows
@Ranando Minor nit: class fields can be purely implemented in terms of
`defineProperty` (for public) and weak maps (for private - what's used
today for private data). Private methods could be implemented in terms of
weak sets/maps and an object with methods outside the class's scope.
Private static properties could just verify `this === Type`.

So no, those don't quite reify classes, either. (If something can be fully
transpiled or polyfilled, it doesn't create or reify any new primitives.)

On Tue, Mar 12, 2019 at 09:51 Ranando King  wrote:

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


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

2019-03-12 Thread Isiah Meadows
@John May I suggest you play around a little with Lua? That language is
prototype-based like JS, with several similar idioms, but it's a lot
simpler, without `new`, property descriptors, or the like. Like JS, it also
has a keyword `self` equivalent to JS `this` and inheritance is purely
prototype-based. Unlike JS, it has no sugar for small functions nor does it
have sugar for class-like constructs - it's like ES5 in that respect. Once
you understand how prototypes work and how they're fundamentally different
from classes, it will help you understand why method references, in the way
you're describing them, don't make sense in that model.
On Tue, Mar 12, 2019 at 09:51 Ranando King  wrote:

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


Re: Name-spaced cross-realm objects

2019-03-11 Thread Isiah Meadows
Not a huge fan. This explicit encapsulation break could be done via an
explicit bootstrapper that can send values across realms, and scenarios on
the same realm can just use global state. Also, the utility seems a bit low
IMHO.
On Tue, Mar 12, 2019 at 00:39 Sultan  wrote:

> The following is currently possible with setTimeout from the browser
>
> const i = setTimeout(() => {})
>
> Where "i" is a number from 0 incrementing towards infinity.
>
> This however has the issue that it is entirely global, and as the title of
> the post suggests the idea is to strike a middle ground between global and
> name-spaced; That is the ability to create/access your own name-spaced
> state similar to Symbol.for. As an example – a name-spaced incrementing
> number:
>
> // a.js
> const fn = UID.for('namespace')
>
> assert(fn() === 0)
> assert(fn() === 1)
>
> // b.js
>
> const fn = UID.for('namespace')
>
> assert(fn() === 2)
> assert(fn() === 3)
>
> This however would be implemented in user-land on top of a more general
> proposal for creating cross realm name-spaced objects:
>
> // a.js
> const obj = Object.for('namespace')
>
> // b.js
> const obj = Object.for('namespace')
>
> Where both objects "obj" in the files a.js and b.js would point to the
> same object.
>
> Disclaimer: I'm aware all of the above can be implemented with global
> state if you disregard the cross-realm requirement.
> ___
> 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-11 Thread Isiah Meadows
I've done a little engine work, and inline caches work by inline type maps
based on the callee site. This *can* be used to reconstruct values +
receivers, but only when the value is constant. It is not sufficient to
ensure identity remains the same, and engines would still need a weak map
to link methods to instances (as opposed to prototypes).

It's worth noting not even Java or Ruby offers this - their method
references/objects (like our bound functions) are *not* memoized - they're
linked to classes, not instances. Python is the exception here in
auto-binding instance methods, not the norm.
On Mon, Mar 11, 2019 at 15:37 Bergi  wrote:

> Hi John!
> > I think the js run-time already has that information at hand, so as
> > long as we don't implement this as pure syntactical sugar, there would
> > not be a need to keep an extra reference to anything, because it would
> > be already there. The run-time will know which instance the invoked
> > method belongs to.
>
> Well no, you're wrong here: the runtime does not have this information
> at hand. In your example (simplified)
> ```
> var reqManager = new RequestManager();
> function addEventListener(f) {
>  console.log(f);
>  f(event);
> }
> addEventListener(reqManager.responseHandler);
> ```
> the `addEventListener` function will not know that the function `f` you
> passed was a method of the `reqManager` instance. It cannot distinguish
> that call from
> ```
> addEventListener(RequestManager.prototype.responseHandler);
> ```
> or
> ```
> var g = otherReqManager.responseHandler;
> addEventListener(g);
> ```
>
> It is exactly the same function that is passed in all three cases. There
> is no instance bound to `f`, and `f(event)` will not invoke it as a
> method (with a receiver/`this` value).
>
> Best regards,
>   Bergi
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: 1) Number (integer or decimal) to Array 2) Array to Number (integer or decimal)

2019-03-11 Thread Isiah Meadows
JS numbers are specified to be in terms of IEEE-754 doubles, so tenths,
hundredths, and so on cannot be precisely represented. [1] So there is no
way to increase precision here beyond the above that Tab showed, assuming
each of those operations are accurate to the bit.

[1]:
https://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/
On Sun, Mar 10, 2019 at 13:26 guest271314  wrote:

> So this would help with precision?
>
>
> To an appreciable degree, yes, without the scope of JavaScript
> floating-point number implementation.
>
> The gist of the proposal is to formalize, standardize, or whatever term
> specification writers want to use, the *naming* of each method or operation
> which can get and set each discrete digit of a number - without using
> String methods.
>
> For input
>
> 1234.567
>
> Each digit has a formal name which developers can get and set, whether in
> an array, object or number format.
>
> On Sun, Mar 10, 2019 at 5:17 PM Michael Theriot <
> michael.lee.ther...@gmail.com> wrote:
>
>> So this would help with precision?
>>
>> On Sunday, March 10, 2019, guest271314  wrote:
>>
>>> (If you really wanted this as an integer, it's not well-founded; .567
 isn't exactly representable as a double, so JS doesn't know that you
 "meant" it to have only three digits after the decimal point, and thus
 want 567 as the answer. You'll instead get some very very large
 integer that *starts with* 567, followed by a bunch of zeros, followed
 by some randomish digits at the end.)
>>>
>>>
>>> The code at the first post solves that problem.
>>>
>>> But the question is still "what would someone use this information for?"
>>>
>>>
>>> That question has been answered several times in the posts above. This
>>> users' motivation was and is the ability to manipulate JavaScript
>>> floating-point numbers  (which could be considered "broken", as you
>>> described above) in order to solve mathematical problems (in this case,
>>> directly calculating the *n*th lexicographic permutation) with the
>>> number or decimal being represented as an array, without having to be
>>> concerned with not getting the same value when the array is converted back
>>> to a number.
>>>
>>> Felipe Nascimento de Moura mentioned several other applications.
>>>
>>> The work has already been done. This proposal is essentially to
>>> standardize the naming conventions. Whether a Number method is used
>>>
>>> i.getTensMethod
>>>
>>> or an array is used
>>>
>>>arr["integer"] // 1234
>>>
>>> or an object where values are arrays is used
>>>
>>> o["fraction"] // .567
>>>
>>> Having mentioned Intl.NumberFormat earlier in the thread, if the issue
>>> devoting resources to a *new *proposal, Intl.NumberFormate can be
>>> extended; e.g. a rough draft in code
>>>
>>> function formatNumberParts(args) {
>>>   return Object.assign({sign:0, fraction:[0], integer:[0]},
>>> ...args.filter(({type}) => type === "integer" || type === "fraction" ||
>>> type === "minusSign").map(({type, value}) => ({[type === "minusSign" ?
>>> "sign" : type]: type !== "minusSign" ? [...value].map(Number) : -1})));
>>> }
>>>
>>> let number = -123;
>>>
>>> let formatter = new Intl.NumberFormat('en-US');
>>>
>>> let res = formatter.formatToParts(number);
>>>
>>> formatNumberParts(res);
>>>
>>> If the concern is that the proposal would not be useful, consider what
>>> you would *name* various uses of Math.trunc and remainder operator used
>>> at your message?
>>>
>>>
>>> On Sun, Mar 10, 2019 at 3:58 PM Tab Atkins Jr. 
>>> wrote:
>>>
 On Sat, Mar 9, 2019 at 11:10 AM Felipe Nascimento de Moura
  wrote:
 >
 > Personally, I don't think it would be THAT useful...
 > but...I think there is something behind this proposal that makes
 sense.
 >
 > I do believe it could be useful for developers to have an easier
 access to number parts or characteristics.
 > Perhaps something like:
 >
 > const i = 1234.567;

 Can you provide a scenario in which these would do something useful,
 such that it would be worth adding them over just using the math
 operations that already exist?

 > console.log( i.float ); // 567

 i % 1

 (If you really wanted this as an integer, it's not well-founded; .567
 isn't exactly representable as a double, so JS doesn't know that you
 "meant" it to have only three digits after the decimal point, and thus
 want 567 as the answer. You'll instead get some very very large
 integer that *starts with* 567, followed by a bunch of zeros, followed
 by some randomish digits at the end.)

 > console.log( i.abs ); // 1234

 Math.trunc(i)

 > console.log( i.thousands ); // 1

 Math.trunc(i / 1000)

 > console.log( i.million ); // 0

 Math.trunc(i / 1e6)

 > console.log( i.hundred ); // 2

 Math.trunc(i / 100) % 10

 > console.log( 

Re: Proposal: 1) Number (integer or decimal) to Array 2) Array to Number (integer or decimal)

2019-03-07 Thread Isiah Meadows
> What part of the proposal, in your view, did not read "it'd be nice if ..." 
> number to array <--> array to number specification and standardization?

I think you missed my point in the first sentence. I'm saying the
first thing on your mind when creating proposals *shouldn't* be "it'd
be nice if ...". Please re-read that first sentence and you'll get
what I'm saying.

> Not sure what you mean by "toy problems"? Do you mean only concepts that meet 
> *your* "toy" interests? Scale is irrelevant. The real world problem is 
> standardization of number to array, array to number conversion in JavaScript.

1. Scale *is* mostly irrelevant here, even in my criticism. The only
requirement here is that it's in code you'd actually write when
building something. Code golf challenges aren't sufficient, since JS
doesn't optimize for that. It needs to be something genuinely useful,
useful enough to merit the added engine complexity as a result.
2. Not everyone agrees the problem even exists - in fact, most of us
don't. "Number to array" is as simple as defining a `Symbol.iterator`
method on `Number.prototype` and using `[...num]`. "Array to number"
is just `+[...values]`, which evaluates to
`Number(String([...values]))`.

-

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

On Thu, Mar 7, 2019 at 7:29 PM guest271314  wrote:
>>
>> @guest When making a language proposal, the first thing that should be on 
>> your mind isn't , but the problems you're trying to solve. And these 
>> problems can't just be simple toy problems like a code golf challenge - they 
>> have to be real-world problems in code you write for sites, apps, libraries, 
>> and so on. If it's so niche as to be useless outside a simple challenge, 
>> you're unlikely to get any sort of support for adding it.
>> Also, when making a language proposal, it's your responsibility to persuade 
>> others of its usefulness. It's not others' responsibility to dispute it - 
>> they could just as easily ignore it and your proposal won't have a chance to 
>> be merged into the spec. You have to be the one to explain why it should be 
>> added.
>
>
>  What part of the proposal, in your view, did not read "it'd be nice if ..." 
> number to array <--> array to number specification and standardization?
>
> Not sure what you mean by "toy problems"? Do you mean only concepts that meet 
> *your* "toy" interests? Scale is irrelevant. The real world problem is 
> standardization of number to array, array to number conversion in JavaScript. 
> The use case for this user has been stated several times above: manipulation 
> of numbers as arrays with the standardization of what to expect - in 
> JavaScript code output - when array is converted back to number or decimal to 
> the maximum JavaScript can produce. That is obviously not a compelling reason 
> for users here. So what? Made the proposal anyway, without having any 
> expectation as to the outcome.
>
>
>
> On Fri, Mar 8, 2019 at 12:19 AM Isiah Meadows  wrote:
>>
>> @guest When making a language proposal, the first thing that should be
>> on your mind isn't "it'd be nice if ...", but the problems you're
>> trying to solve. And these problems can't just be simple toy problems
>> like a code golf challenge - they have to be real-world problems in
>> code you write for sites, apps, libraries, and so on. If it's so niche
>> as to be useless outside a simple challenge, you're unlikely to get
>> any sort of support for adding it.
>>
>> Also, when making a language proposal, it's your responsibility to
>> persuade others of its usefulness. It's not others' responsibility to
>> dispute it - they could just as easily ignore it and your proposal
>> won't have a chance to be merged into the spec. You have to be the one
>> to explain why it should be added.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Thu, Mar 7, 2019 at 7:09 PM guest271314  wrote:
>> >
>> > That still leaves determining how many digits there are after the decimal 
>> > point and where the number added sums to greater than 10 carrying over the 
>> > remainder to the adjacent digits, if needed, which is simpler using array 
>> > methods where the .length after the index where the single decimal is 
>> > located in the array will provide the 10's, 100's, etc.
>> >
>> > If alternative solutions provide the expected results, without 
>> > standardization, simply disregard this proposal. The proposal is intended 
>> > to standard

Re: Proposal: 1) Number (integer or decimal) to Array 2) Array to Number (integer or decimal) (guest271314)

2019-03-07 Thread Isiah Meadows
That proposal wasn't about ranges, even though it might look like it
was. It's about a special type of numeric array conversion that's
really about a particular sequence that isn't all that special in the
context of programming. [1] It also links to an SO question that
almost reads like a homework/"gimme teh codez" question. [2]

[1]: https://oeis.org/A217626
[2]: https://stackoverflow.com/q/54433007/2693146

-----

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

On Thu, Mar 7, 2019 at 6:28 PM Bob Myers  wrote:
>
> There is already a very well thought out list, although to my knowledge it 
> has never been officially blessed, at https://esdiscuss.org/topic/ranges.
>
> Quoting:
>
> It seems odd that after all these years of discussions and meta-discussions 
> about ES feature proposals, some people are still saying things like:
>
> there really needs to be
> I'd really like
> I'd love to have
>
> often without addressing a single one of the relevant questions:
>
> Is it sugar? Is it "mere" syntactic sugar (which is not disqualifying in and 
> of itself), or something that requires (or benefits from) being baked into 
> the language?
> How much sugar? If it is wholly or partially syntactic sugar, what the degree 
> of syntactic optimization?
> Frequency of benefit? What is the frequency of the use case?
> Expected improvement? If it is something that would benefit from being baked 
> into the language, what is the degree of the benefit (eg, in terms of 
> performance)?
> Userland implementable? Can it be implemented in userland code? If so, what's 
> the downside of that?
> Implementable? Does it present potentially difficult or intractable 
> implementation challenges?
> Consistent? Is it consistent with existing syntactic and semantic practices 
> in the languages?
> Holistic? Does it fill in some obvious logical gap in the current language 
> design?
> Understandable? Does it place an unsustainable new "cognitive burden" on 
> learners and users of the language?
> Library? Is is something that would be better provided as part of some kind 
> of future standard library?
> Intrusive? Does it take over real estate that might be useful for future 
> features no one has thought of yet, the obvious example being using special 
> characters?
> Readability? Is it something that results in a distinct improvement in 
> readability or visible semantic correctness of code?
> Prior art? Has this or a similar feature already been proposed, and if so 
> what was the reaction, and how is your proposal different from that, or from 
> a similar features existing in other languages?
>
> I'm sure there are cases where simply throwing out an informal idea and 
> seeing how people react is useful to get a discussions started, but most 
> reactions will be that the proposal does not meet one or more of the above 
> criteria, so proposers could save themselves and other people lots of time in 
> advance by explaining HOW their proposal satisfies these points, not all of 
> which are relevant to every proposal, but those which are.
>
> Bob
>>>
>>> It would be useful to have a FAQ somewhere with a version of the above 4 
>>> rules that is better worked out and justified, so we could point to that. 
>>> (From whatever public-facing forum is selected for the future; this one is 
>>> dead.)
>
> ___
> 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: 1) Number (integer or decimal) to Array 2) Array to Number (integer or decimal)

2019-03-07 Thread Isiah Meadows
@guest When making a language proposal, the first thing that should be
on your mind isn't "it'd be nice if ...", but the problems you're
trying to solve. And these problems can't just be simple toy problems
like a code golf challenge - they have to be real-world problems in
code you write for sites, apps, libraries, and so on. If it's so niche
as to be useless outside a simple challenge, you're unlikely to get
any sort of support for adding it.

Also, when making a language proposal, it's your responsibility to
persuade others of its usefulness. It's not others' responsibility to
dispute it - they could just as easily ignore it and your proposal
won't have a chance to be merged into the spec. You have to be the one
to explain why it should be added.

-----

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

On Thu, Mar 7, 2019 at 7:09 PM guest271314  wrote:
>
> That still leaves determining how many digits there are after the decimal 
> point and where the number added sums to greater than 10 carrying over the 
> remainder to the adjacent digits, if needed, which is simpler using array 
> methods where the .length after the index where the single decimal is located 
> in the array will provide the 10's, 100's, etc.
>
> If alternative solutions provide the expected results, without 
> standardization, simply disregard this proposal. The proposal is intended to 
> standardize the conversion from number to array and array to number.
>
> Consider the examples at the proposal, where several generator functions can 
> be used in parallel to adjust both 128.625 and 1.074 through and beyond 
> 1.144, where for example, input is "abcdefghi", we ignore the values and 
> permute only the indexes as a whole number and match the multiples of 9 which 
> meet the necessary criteria.
>
> In any event, do with the proposal as you will.
>
> On Thu, Mar 7, 2019 at 11:55 PM Gus Caplan  wrote:
>>
>> this seems like a solution in search of a problem.
>>
>> if you want to add a number in a specific place, you can just multiply it by 
>> that place. e.g. increasing the tenths place by 2 is n + (2 / 10), and 
>> increasing the tens place is n + (2 * 10).
>>
>> On Thu, Mar 7, 2019 at 5:42 PM guest271314  wrote:
>>>
>>> FWIW the original requirement included a self-imposed restriction of 
>>> converting the input to a String at any point during the procedure, in part 
>>> to illustrate the ("broken") JavaScript Number/Math implementations.
>>>
>>> If you have a "simpler" implementation to the requirement, then post your 
>>> answer at SO. Am banned for 5 years - a few days, though will still be able 
>>> to view your answer. Or, post a gist.
>>>
>>> Yes, to settle the matter of a lot of users having a need for such an 
>>> implementation, can only speak for self. Have tried to solve the linked 
>>> OEIS A217626 oeis.org/A217626 for several years now - directly. That is, 
>>> specifically, using only a multiple of the number 9 to get *any* nth 
>>> permutation. That is how arrived at making this proposal here.
>>>
>>> On Thu, Mar 7, 2019 at 11:31 PM J Decker  wrote:
>>>>
>>>>
>>>>
>>>> On Thu, Mar 7, 2019 at 2:55 PM guest271314  wrote:
>>>>>
>>>>> Cannot get into "a large number of users" heads. Again, am not interested 
>>>>> in overcoming conjecture. If the proposal does not meet you folks' 
>>>>> criteria, so be it.
>>>>>
>>>>> On Thu, Mar 7, 2019 at 10:46 PM Steve Fink  wrote:
>>>>>>
>>>>>> Any addition to the JavaScript language needs to (1) be motivated by a 
>>>>>> use case encountered by a large number of users, (2) cannot be 
>>>>>> implemented in a straightforward and reliable way by a library, (4) is 
>>>>>> implementable by a JS implementation without undue trouble, and (4) does 
>>>>>> not conflict with other parts of the language.
>>>>>>
>>>>>> For your proposal:
>>>>>>
>>>>>> (1) - absolute fail
>>>>>> (2) - arguable
>>>>>> (3) - uncertain, depends on exact semantics
>>>>>> (4) - pass
>>>>>>
>>>>>> Unless you can somehow prove that a large numbers of users give a rat's 
>>>>>> hindquarters about things that this would enable, this is a nonstarter.
>>>>>>
>>>>>> It would be useful to have a FAQ somewhere with a version of the above 4 
>>>>>&g

Re: Proposal: Duration

2019-03-04 Thread Isiah Meadows
Alexandre: I feel it's only *related* to dates and times:

- Dates and times refer to absolute points.
- Durations would refer to distances between two dates and/or times.

However, I do feel this should be discussed in
https://github.com/tc39/proposal-temporal. And down this vein, I've
created https://github.com/tc39/proposal-temporal/issues/109 just now.

Naveen: If you look at that proposal and particularly the issue I
filed, you can see date handling isn't as simple as it looks. There's
an entire database dedicated to localizing just times [1] (source:
[2]), and numeric date handling is a mess all on its own, [3] even if
you just stick with *just* the Gregorian calendar. [4] About the only
portable way to handle a date is to just do a bunch of UTC offsets to
the start of January 1, 1970, but even that has glitches in the form
of leap seconds. [5]

Or to put it simply: Date handling is hard.

[1]: https://www.iana.org/time-zones
[2]: https://github.com/eggert/tz
[3]: https://en.wikipedia.org/wiki/Calendar_date
[4]: https://en.wikipedia.org/wiki/Gregorian_calendar
[5]: https://en.wikipedia.org/wiki/Leap_second

-

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


On Mon, Mar 4, 2019 at 4:30 PM Mark Davis ️  wrote:
>
> Sadly, time is not that simple. Most people using calendars consider the 
> duration between January 15 and March 15 to be exactly 2 months. But such 
> intervals are a different number of days, hence milliseconds.
>
> Mark
>
>
> On Mon, Mar 4, 2019 at 11:21 AM Naveen Chawla  wrote:
>>
>> I don't like it. Duration is just milliseconds for me.
>>
>> On Mon, 4 Mar 2019 at 18:47 Alexandre Morgaut  
>> wrote:
>>>
>>> Here a proposal to make ECMAScript natively support a Duration Object
>>>
>>> I talked about it a long time ago (2011) on the WHATWG mailing list in the 
>>> context of the Timers API: 
>>> https://lists.w3.org/Archives/Public/public-whatwg-archive/2011Feb/0533.htm
>>>
>>> l think that such a proposal would better take place in the core of the 
>>> language and having worked on a framework date time APIs I tried to give 
>>> this approach a better look.
>>>
>>> ECMAScript natively support Dates since its very first version
>>> It started to support the ISO 8601 string format in edition 5
>>> (15.9.1.15 Date Time String Format )
>>>
>>> Durations like Dates can be very tricky, especially with I18n in mind, but 
>>> the ECMA standard already had to be handled most of the Duration tricky 
>>> part for the Date Object in EMCA 262 & ECMA 402.
>>>
>>> Duration, sometimes called TimeInterval, is a common concept supported by 
>>> most languages or associated standard libs.
>>>
>>> In very short, Duration object would:
>>> - support the ISO syntax in its contructor: new Duration('P6W') // for  
>>> Period 6 Weeks
>>> - allow to handle Date diff operations
>>> - allow to be interpreted by setTimeout() & setInterval()
>>>
>>> Please find below a draft exposing the concept
>>> I'd be very happy if someone from TC39 would be interested to champion it
>>> https://github.com/AMorgaut/proposal-Duration
>>>
>>> Regards,
>>>
>>> Alexandre.
>>> ___
>>> 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: switch expressions

2019-03-03 Thread Isiah Meadows
By "simulating", I meant doing something that was functionally
equivalent. If you wanted a direct equivalent, just replace all
instances of `{keyN: true, print: function () { ... }}` with `new
class { constructor() { this.keyN = true } print() { ... } }` in the
benchmarks, and you've got something that's *exactly* equivalent. And
no, that won't be any faster, because in either case, with object
literals or with immediately-invoked classes, the engine is working
with a different set of type maps for each type, so the only variable
here is whether `print` is own or prototype and whether the prototype
is `Object.prototype` or a unique object. If anything, the class
variant would be slower because of the indirection.

Here's a couple fixed benchmarks with clearer test names:

- 4 types: http://jsben.ch/4VeWy
- 12/16 types: http://jsben.ch/wplTp

In both cases, method dispatch is about 10-20% slower than the
corresponding `switch`/`case`, and is only marginally (< 5%) faster
than dynamic string property dispatch. I've gotten these results
running both benchmark suites about 10 times each and even in the one
statistical outlier I had where everything ran slower, method dispatch
still was listed as slower than switch/case across the board and
roughly equal to dynamic string property dispatch.

One last thing: could you *please* quit arguing semantics?

-

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

On Sat, Mar 2, 2019 at 4:57 PM Naveen Chawla  wrote:
>
> It "simulates" then does it for real, hence slower than just doing it (there 
> is no need to simulate if we have the paradigm we are are trying to benchmark 
> ready for us to just use). I'd be curious to see a direct benchmark 
> comparison, but don't have time to set it up right now.
>
> On Sat, 2 Mar 2019, 2:08 pm Isiah Meadows,  wrote:
>>
>> IIUC the "object dispatch integer"/"object dispatch string" benchmarks
>> are the things you were referring to. Those simulate what the engine
>> would see with virtual dispatch and completely different type maps,
>> just without the source overhead of creating an entire class just for
>> a little benchmark.
>>
>> And also, engines *won't* be able to optimize them generally, because
>> there could be infinitely many type maps, and after about 200 or so
>> types, the `switch` statement ends up *much* slower.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Sat, Mar 2, 2019 at 3:43 AM Naveen Chawla  wrote:
>> >
>> > I don't think those benchmarks test exactly what we are talking about. 
>> > They have a dictionary/array look up followed by method dispatch, vs 
>> > switch case and execute. Removing the look up it would be: `x.doStuff()` 
>> > vs `switch(x.type)...`. Make sense? Don't have time to do it right now.
>> >
>> > Logically I think the JS engine can make them perform identically, so even 
>> > if benchmarks show something today, I would not be concerned for the 
>> > future and so would prefer to opt for the paradigm that offers the best 
>> > manageability, which I think is inheritance by a significant margin, in 
>> > the cases mentioned. Other types of cases could of course be a whole 
>> > different story.
>> >
>> > On Sat, 2 Mar 2019, 5:24 am Isiah Meadows,  wrote:
>> >>
>> >> > It would be unthinkable for it to use pattern matching or explicit code 
>> >> > branchinI'm g instead of method inheritance for type disambiguation 
>> >> > during render
>> >>
>> >> But it frequently does internally. For example:
>> >>
>> >> - Calculating object projections:
>> >> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1243-L1351
>> >> - Rendering object *lists*:
>> >> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1353-L1411
>> >> - Setting the rendering mode and controlling basic rendering:
>> >> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L802-L874
>> >>
>> >> Obviously, it exposes a data-oriented, object oriented API. And it
>> >> does appear it's not *exclusively* conditionals:
>> >>
>> >> - It invokes an dynamic `render` method for "immediate render
>> >> objects": 
>> >> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L636-L644
>> >> - In `renderBufferDirect`, it does virtual method dispatch on `render`
>> >> based on one of two possible types, but it otherwise uses c

Re: Proposal: switch expressions

2019-03-02 Thread Isiah Meadows
IIUC the "object dispatch integer"/"object dispatch string" benchmarks
are the things you were referring to. Those simulate what the engine
would see with virtual dispatch and completely different type maps,
just without the source overhead of creating an entire class just for
a little benchmark.

And also, engines *won't* be able to optimize them generally, because
there could be infinitely many type maps, and after about 200 or so
types, the `switch` statement ends up *much* slower.

-

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

On Sat, Mar 2, 2019 at 3:43 AM Naveen Chawla  wrote:
>
> I don't think those benchmarks test exactly what we are talking about. They 
> have a dictionary/array look up followed by method dispatch, vs switch case 
> and execute. Removing the look up it would be: `x.doStuff()` vs 
> `switch(x.type)...`. Make sense? Don't have time to do it right now.
>
> Logically I think the JS engine can make them perform identically, so even if 
> benchmarks show something today, I would not be concerned for the future and 
> so would prefer to opt for the paradigm that offers the best manageability, 
> which I think is inheritance by a significant margin, in the cases mentioned. 
> Other types of cases could of course be a whole different story.
>
> On Sat, 2 Mar 2019, 5:24 am Isiah Meadows,  wrote:
>>
>> > It would be unthinkable for it to use pattern matching or explicit code 
>> > branchinI'm g instead of method inheritance for type disambiguation during 
>> > render
>>
>> But it frequently does internally. For example:
>>
>> - Calculating object projections:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1243-L1351
>> - Rendering object *lists*:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1353-L1411
>> - Setting the rendering mode and controlling basic rendering:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L802-L874
>>
>> Obviously, it exposes a data-oriented, object oriented API. And it
>> does appear it's not *exclusively* conditionals:
>>
>> - It invokes an dynamic `render` method for "immediate render
>> objects": 
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L636-L644
>> - In `renderBufferDirect`, it does virtual method dispatch on `render`
>> based on one of two possible types, but it otherwise uses conditionals
>> for everything:\*
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L707-L876
>> - It uses a fair bit of functional programming in `compile`:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1009-L1054
>>
>> However, I'm finding exceptions in its core and renderers, and it
>> doesn't appear virtual dispatch is *that* broadly and pervasively
>> used, even though it uses methods a lot.
>>
>> \* This seems like overkill when the diff between the two renderers in
>> question [1] [2] consist of an extra method + 2 extra variables [3]
>> [4], a few changed method invocations [5] [6], and the rest just due
>> to a different name and a useless `var`.
>>
>> [1]: 
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLBufferRenderer.js
>> [2]: 
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js
>> [3]: 
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L15-L22
>> [4]: 
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L61
>> [5]: 
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L26
>> [6]: 
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L53
>>
>> > I'm curious where you got the idea that method invocation is "far" slower 
>> > than explicit code branching?
>>
>> - In C++: https://stackoverflow.com/a/8866789
>> - JS benchmark with 4 variants (typed method dispatch is polymorphic):
>> http://jsben.ch/fbJQH
>> - JS benchmark with 12 variants (typed method dispatch is
>> megamorphic): http://jsben.ch/aWNDN
>>
>> And in my experience, the speed difference in real-world
>> performance-critical code is not unlike that microbenchmark and is
>> sometimes even more drastic, especially if it's a linked list instead
>> of just a simple array lookup.
>>
>> I'd like to emphasize I'm specifically referring to the case where the
>> engine can't reliably assume a

Re: Proposal: switch expressions

2019-03-01 Thread Isiah Meadows
> It would be unthinkable for it to use pattern matching or explicit code 
> branching instead of method inheritance for type disambiguation during render

But it frequently does internally. For example:

- Calculating object projections:
https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1243-L1351
- Rendering object *lists*:
https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1353-L1411
- Setting the rendering mode and controlling basic rendering:
https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L802-L874

Obviously, it exposes a data-oriented, object oriented API. And it
does appear it's not *exclusively* conditionals:

- It invokes an dynamic `render` method for "immediate render
objects": 
https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L636-L644
- In `renderBufferDirect`, it does virtual method dispatch on `render`
based on one of two possible types, but it otherwise uses conditionals
for everything:\*
https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L707-L876
- It uses a fair bit of functional programming in `compile`:
https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1009-L1054

However, I'm finding exceptions in its core and renderers, and it
doesn't appear virtual dispatch is *that* broadly and pervasively
used, even though it uses methods a lot.

\* This seems like overkill when the diff between the two renderers in
question [1] [2] consist of an extra method + 2 extra variables [3]
[4], a few changed method invocations [5] [6], and the rest just due
to a different name and a useless `var`.

[1]: 
https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLBufferRenderer.js
[2]: 
https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js
[3]: 
https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L15-L22
[4]: 
https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L61
[5]: 
https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L26
[6]: 
https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L53

> I'm curious where you got the idea that method invocation is "far" slower 
> than explicit code branching?

- In C++: https://stackoverflow.com/a/8866789
- JS benchmark with 4 variants (typed method dispatch is polymorphic):
http://jsben.ch/fbJQH
- JS benchmark with 12 variants (typed method dispatch is
megamorphic): http://jsben.ch/aWNDN

And in my experience, the speed difference in real-world
performance-critical code is not unlike that microbenchmark and is
sometimes even more drastic, especially if it's a linked list instead
of just a simple array lookup.

I'd like to emphasize I'm specifically referring to the case where the
engine can't reliably assume a single method receiver, i.e. when it
*has* to fall back to dynamic dispatch.

-

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

On Fri, Mar 1, 2019 at 6:25 AM Naveen Chawla  wrote:
>
> The entire renderers, cameras, meshes etc. hierarchy uses method inheritance 
> and many of those methods are called during scene rendering (which is 
> performance sensitive as it happens per frame). It would be unthinkable for 
> it to use pattern matching or explicit code branching instead of method 
> inheritance for type disambiguation during render, because it would explode 
> the code as well as making it error prone due to initial cases potentially 
> unintentionally swallowing up cases intended for later code branches (or 
> unintentionally repeating code branches if the pattern-matching proposal 
> doesn't have "else" behaviour, of which I'm not sure, but it if does, it 
> suffers from the first problem anyway).
>
> I'm curious where you got the idea that method invocation is "far" slower 
> than explicit code branching?
>
> On Thu, 28 Feb 2019 at 18:49 Isiah Meadows  wrote:
>>
>> I'm looking at Three.js's code base, and I'm not seeing any method
>> overriding or abstract methods used except at the API level for
>> cloning and copying. Instead, you update properties on the supertype.
>> As far as I can tell, the entirety of Three.js could almost be
>> mechanically refactored in terms of components instead of inheritance,
>> without substantially modifying the API apart from a few extra
>> `.geometry`/etc. property accesses when calling supertype methods.
>> It's data-driven and almost ECS. (It uses `.isObject3D`,
>> `.isPerspectiveCamera`, and similar brand checks, but those don't
>> *need* to be inherited to work.)
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.

Re: Loose idea on "try import"

2019-03-01 Thread Isiah Meadows
Personally, I find this a *bad* idea. Top-level `await` in modules
would solve this problem far more quickly and efficiently.

-

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

On Fri, Mar 1, 2019 at 3:35 PM Ben Wiley  wrote:
>
> Has anyone seen anything like this done in another language (with static 
> imports)? If so we could learn something maybe. I know you can conditionally 
> import in Python but that's basically the same thing as .catch()ing dynamic 
> import()s in JavaScript (except done synchronously).
>
> Ben
>
> Le ven. 1 mars 2019 15 h 26, Herby Vojčík  a écrit :
>>
>> On 1. 3. 2019 18:35, Michał Wadas wrote:
>> > I don't think so, because:
>> >
>> >   * Using promises to import module is not always desirable
>> >   * This mechanism doesn't impact ability to statically analyze modules
>> > if ifs are excluded - it can only increase resolution time.
>>
>> Yeah, if 'if's are excluded. That version with those ifs was what was
>> concerning. That actually needs runtime to do the work. I suppose until
>> it doesn't need the runtime, it's all ok.
>>
>> >
>> > On Fri, Mar 1, 2019 at 1:56 PM Herby Vojčík > > <mailto:he...@mailbox.sk>> wrote:
>> >
>> > On 1. 3. 2019 12:04, Michał Wadas wrote:
>> >  > Syntax:
>> >  >
>> >  > try import fs from 'fs'
>> >  > else import fs from 'fs-polyfill'
>> >  > else import fs from 'another-fs-polyfill'
>> >  > else do nothing; // Not sure about syntax
>> >  >
>> >  >
>> >  > try import {watchDirectory} from 'fs'
>> >  > else import {watchDirectory} from 'fs-polyfill'
>> >  > else if(process.os === 'ExoticSystem') import
>> > {watchDirectory} from
>> >  > 'another-fs-polyfill'
>> >  > else throw Error('Your OS doesn\'t support watching
>> > directories');
>> >
>> > I am not an expert, but afaict ES module system was created to be
>> > statically analysable and this bring uncertainity.
>> >
>> > For that probably dynamic import() is there; and your usage should
>> > await
>> > for a promise that tries to load one then the other etc.
>> >
>> > Herby
>> >
>> >  > Usages:
>> >  >
>> >  >   * Optional dependencies
>> >  >   * Polyfills
>> >  >
>> >  > Problems:
>> >  >
>> >  >   * This can prevent loading modules before execution if presence of
>> >  > modules can't be proved statically
>> >  >   * else-if requires execution before loading module - can be 
>> > dropped
>> >  >
>> >  >
>> >  > I don't have enough time and knowledge about modules to write actual
>> >  > proposal.
>> >
>>
>> ___
>> 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-28 Thread Isiah Meadows
I'm looking at Three.js's code base, and I'm not seeing any method
overriding or abstract methods used except at the API level for
cloning and copying. Instead, you update properties on the supertype.
As far as I can tell, the entirety of Three.js could almost be
mechanically refactored in terms of components instead of inheritance,
without substantially modifying the API apart from a few extra
`.geometry`/etc. property accesses when calling supertype methods.
It's data-driven and almost ECS. (It uses `.isObject3D`,
`.isPerspectiveCamera`, and similar brand checks, but those don't
*need* to be inherited to work.)

-

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

On Thu, Feb 28, 2019 at 12:40 PM Naveen Chawla  wrote:
>
> I'm not sure that pattern matching handles deep levels of inheritance more 
> elegantly than inheritance itself.
>
> If there is a conceptual type hierarchy, then the ability to call "super", 
> combine it with specialized functionality, etc. is a lot more manageable 
> using localized, separated logic where you don't feel forced to read "other 
> patterns" to understand whether your target functionality will resolve 
> correctly. And hence, a lower chance of bugs.
>
> As for performance, I'd have to see modern benchmarks. But it's not 
> necessarily clear that pattern matching will be particularly fast either. 
> I've done game programming with method overriding (Three.js uses it too 
> throughout) and there is no notable performance hit from doing so. So I'm not 
> clear where you have got this information from.
>
> On Thu, 28 Feb 2019 at 17:06 Isiah Meadows  wrote:
>>
>> > Using a "switch" here forces you to group classes of objects together and 
>> > then you don't get the 2nd, 3rd, 4th etc. levels of specialization that 
>> > you might later want.
>>
>> Sometimes, this is actually *desired*, and most cases where I could've
>> used this, inheritance was not involved *anywhere*. Also, in
>> performance-sensitive contexts (like games, which *heavily* use
>> `switch`/`case`), method dispatch is *far* slower than a simple
>> `switch` statement, so that pattern doesn't apply everywhere.
>>
>> BTW, I prefer https://github.com/tc39/proposal-pattern-matching/ over
>> this anyways - it covers more use cases and is all around more
>> flexible, so I get more bang for the buck.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Thu, Feb 28, 2019 at 9:23 AM Naveen Chawla  wrote:
>> >
>> > Hi David!
>> >
>> > Your last example would, I think, be better served by classes and 
>> > inheritance, than switch.
>> >
>> > Dogs are house animals which are animals
>> > Cheetas are wild cats which are animals
>> >
>> > Each could have overridden methods, entirely optionally, where the method 
>> > gets called and resolves appropriately.
>> >
>> > The input argument could be the class name, from which it is trivial to 
>> > instantiate a new instance and get required results.
>> >
>> > Using a "switch" here forces you to group classes of objects together and 
>> > then you don't get the 2nd, 3rd, 4th etc. levels of specialization that 
>> > you might later want.
>> >
>> > All thoughts on this are welcome. Do let me know
>> >
>> > On Thu, 28 Feb 2019 at 14:06 David Koblas  wrote:
>> >>
>> >> Naveen,
>> >>
>> >> Thanks for your observation.  The example that I gave might have been too 
>> >> simplistic, here's a more complete example:
>> >>
>> >> ```
>> >>
>> >> switch (animal) {
>> >> case Animal.DOG, Animal.CAT => {
>> >> // larger block expression
>> >> // which spans multiple lines
>> >>
>> >> return "dry food";
>> >>   }
>> >> case Animal.TIGER, Animal.LION, Animal.CHEETA => {
>> >> // larger block expression
>> >> // which spans multiple lines
>> >>
>> >> return "fresh meat";
>> >>   }
>> >> case Animal.ELEPHANT => "hay";
>> >> default => { throw new Error("Unsupported Animal"); };
>> >> }
>> >>
>> >> ```
>> >>
>> >> While you give examples that would totally work.  Things that bother me 
>> >> about the approach are, when taken to something more com

Re: Proposal: switch expressions

2019-02-28 Thread Isiah Meadows
> While the pattern-matching proposal does cover a much richer matching, it 
> still doesn't target the issue of being a statement vs an expression.  Part 
> of my initial motivation is that the evaluation of the switch returns a 
> value, which pattern-matching doesn't resolve.

That's still something a lot of people *want* to see end up in the
proposal - in fact,
https://github.com/tc39/proposal-pattern-matching/issues/116 was filed
by a TC39 committee member. I wouldn't dismiss the possibility of
pattern matching *expressions* before then.

-

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

On Thu, Feb 28, 2019 at 12:28 PM David Koblas  wrote:
>
> Isiah,
>
> While the pattern-matching proposal does cover a much richer matching,
> it still doesn't target the issue of being a statement vs an
> expression.  Part of my initial motivation is that the evaluation of the
> switch returns a value, which pattern-matching doesn't resolve.
>
> Very much enjoying the discussion,
> David
>
> On 2/28/19 12:07 PM, Isiah Meadows wrote:
> >> Using a "switch" here forces you to group classes of objects together and 
> >> then you don't get the 2nd, 3rd, 4th etc. levels of specialization that 
> >> you might later want.
> > Sometimes, this is actually *desired*, and most cases where I could've
> > used this, inheritance was not involved *anywhere*. Also, in
> > performance-sensitive contexts (like games, which *heavily* use
> > `switch`/`case`), method dispatch is *far* slower than a simple
> > `switch` statement, so that pattern doesn't apply everywhere.
> >
> > BTW, I prefer https://github.com/tc39/proposal-pattern-matching/ over
> > this anyways - it covers more use cases and is all around more
> > flexible, so I get more bang for the buck.
> >
> > -
> >
> > Isiah Meadows
> > cont...@isiahmeadows.com
> > www.isiahmeadows.com
> >
> > On Thu, Feb 28, 2019 at 9:23 AM Naveen Chawla  wrote:
> >> Hi David!
> >>
> >> Your last example would, I think, be better served by classes and 
> >> inheritance, than switch.
> >>
> >> Dogs are house animals which are animals
> >> Cheetas are wild cats which are animals
> >>
> >> Each could have overridden methods, entirely optionally, where the method 
> >> gets called and resolves appropriately.
> >>
> >> The input argument could be the class name, from which it is trivial to 
> >> instantiate a new instance and get required results.
> >>
> >> Using a "switch" here forces you to group classes of objects together and 
> >> then you don't get the 2nd, 3rd, 4th etc. levels of specialization that 
> >> you might later want.
> >>
> >> All thoughts on this are welcome. Do let me know
> >>
> >> On Thu, 28 Feb 2019 at 14:06 David Koblas  wrote:
> >>> Naveen,
> >>>
> >>> Thanks for your observation.  The example that I gave might have been too 
> >>> simplistic, here's a more complete example:
> >>>
> >>> ```
> >>>
> >>>  switch (animal) {
> >>>  case Animal.DOG, Animal.CAT => {
> >>>  // larger block expression
> >>>  // which spans multiple lines
> >>>
> >>>  return "dry food";
> >>>}
> >>>  case Animal.TIGER, Animal.LION, Animal.CHEETA => {
> >>>  // larger block expression
> >>>  // which spans multiple lines
> >>>
> >>>  return "fresh meat";
> >>>}
> >>>  case Animal.ELEPHANT => "hay";
> >>>  default => { throw new Error("Unsupported Animal"); };
> >>>  }
> >>>
> >>> ```
> >>>
> >>> While you give examples that would totally work.  Things that bother me 
> >>> about the approach are, when taken to something more complex than a quick 
> >>> value for value switch you end up with something that looks like this.
> >>>
> >>> ```
> >>>
> >>>  function houseAnimal() {
> >>>
> >>>  // larger block expression
> >>>  // which spans multiple lines
> >>>
> >>>  return "dry food";
> >>>  }
> >>>
> >>>  function wildCatFood() {
> >>>
> >>>// larger block expression
> >>>// whi

Re: Proposal: switch expressions

2019-02-28 Thread Isiah Meadows
> Using a "switch" here forces you to group classes of objects together and 
> then you don't get the 2nd, 3rd, 4th etc. levels of specialization that you 
> might later want.

Sometimes, this is actually *desired*, and most cases where I could've
used this, inheritance was not involved *anywhere*. Also, in
performance-sensitive contexts (like games, which *heavily* use
`switch`/`case`), method dispatch is *far* slower than a simple
`switch` statement, so that pattern doesn't apply everywhere.

BTW, I prefer https://github.com/tc39/proposal-pattern-matching/ over
this anyways - it covers more use cases and is all around more
flexible, so I get more bang for the buck.

-

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

On Thu, Feb 28, 2019 at 9:23 AM Naveen Chawla  wrote:
>
> Hi David!
>
> Your last example would, I think, be better served by classes and 
> inheritance, than switch.
>
> Dogs are house animals which are animals
> Cheetas are wild cats which are animals
>
> Each could have overridden methods, entirely optionally, where the method 
> gets called and resolves appropriately.
>
> The input argument could be the class name, from which it is trivial to 
> instantiate a new instance and get required results.
>
> Using a "switch" here forces you to group classes of objects together and 
> then you don't get the 2nd, 3rd, 4th etc. levels of specialization that you 
> might later want.
>
> All thoughts on this are welcome. Do let me know
>
> On Thu, 28 Feb 2019 at 14:06 David Koblas  wrote:
>>
>> Naveen,
>>
>> Thanks for your observation.  The example that I gave might have been too 
>> simplistic, here's a more complete example:
>>
>> ```
>>
>> switch (animal) {
>> case Animal.DOG, Animal.CAT => {
>> // larger block expression
>> // which spans multiple lines
>>
>> return "dry food";
>>   }
>> case Animal.TIGER, Animal.LION, Animal.CHEETA => {
>> // larger block expression
>> // which spans multiple lines
>>
>> return "fresh meat";
>>   }
>> case Animal.ELEPHANT => "hay";
>> default => { throw new Error("Unsupported Animal"); };
>> }
>>
>> ```
>>
>> While you give examples that would totally work.  Things that bother me 
>> about the approach are, when taken to something more complex than a quick 
>> value for value switch you end up with something that looks like this.
>>
>> ```
>>
>> function houseAnimal() {
>>
>> // larger block expression
>> // which spans multiple lines
>>
>> return "dry food";
>> }
>>
>> function wildCatFood() {
>>
>>   // larger block expression
>>   // which spans multiple lines
>>
>>   return "fresh meat";
>> }
>>
>>
>> const cases = {
>>   [Animal.DOG]: houseAnimal,
>>   [Animal.CAT]: houseAnimal,
>>   [Animal.LION]: wildCatFood,
>>   [Animal.TIGER]: wildCatFood,
>>   [Animal.CHEETA]: wildCatFood,
>> }
>>
>> const food = cases[animal] ? cases[animal]() : (() => {throw new 
>> Error("Unsuppored Animal")})();
>>
>> ```
>>
>> As we all know once any language reaches a basic level of functionality 
>> anything is possible.  What I think is that JavaScript would benefit by 
>> having a cleaner approach.
>>
>> On 2/28/19 4:37 AM, Naveen Chawla wrote:
>>
>> Isn't the best existing pattern an object literal?
>>
>> const
>> cases =
>> {
>>  foo: ()=>1,
>>  bar: ()=>3,
>>  baz: ()=>6
>> }
>> ,
>> x =
>> cases[v] ?
>> cases[v]() :
>> 99
>> ;
>>
>> What does any proposal have that is better than this? With optional chaining 
>> feature:
>>
>> const
>> x =
>> {
>>  foo: ()=>1,
>>  bar: ()=>3,
>>  baz: ()=>6
>> }[v]?.()
>> ||
>> 99
>> ;
>>
>> Do let me know your thoughts guys
>>
>>
>> On Thu, 28 Feb 2019 at 06:04 kai zhu  wrote:
>>>
>>> This is unmaintainable --
>>>
>>> const x = v === 'foo' ? 1 : v === 'bar' ? 3 : v === 'baz' ? 6 : 99;
>>>
>>> i feel proposed switch-expr

Re: Proposal: switch expressions

2019-02-26 Thread Isiah Meadows
You're not alone in wanting pattern matching to be expression-based:

https://github.com/tc39/proposal-pattern-matching/issues/116

-

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

-

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


On Tue, Feb 26, 2019 at 1:34 PM David Koblas  wrote:
>
> Jordan,
>
> Thanks for taking time to read and provide thoughts.
>
> I just back and re-read the pattern matching proposal and it still fails on 
> the basic requirement of being an Expression not a Statement.  The problem 
> that I see and want to address is the need to have something that removes the 
> need to chain trinary expressions together to have an Expression.
>
> This is unmaintainable --
>
> const x = v === 'foo' ? 1 : v === 'bar' ? 3 : v === 'baz' ? 6 : 99;
>
> This is maintainable, but is less than ideal:
>
>let x;
>
>switch (v) {
>case "foo":
>  x = 1;
>  break;
>case "bar":
>  x = 3;
>  break;
>case "baz":
>  x = 6;
>  break;
>default:
>  x = 99;
>  break;
>}
>
> Pattern matching does shorten the code, but you have a weird default case and 
> also still end up with a loose variable and since pattern matching is a 
> statement you still have a initially undefined variable.
>
>let x;
>
>case (v) {
>  when "foo" -> x = 1;
>  when "bar" -> x = 3;
>  when "baz" -> x = 6;
>  when v -> x = 99;
>}
>
> Let's try do expressions, I'll leave people's thoughts to themselves.
>
>const x = do {
>  if (v === "foo") { 1; }
>  else if (v === "bar") { 3; }
>  else if (v === "baz") { 6; }
>  else { 99; }
>}
>
> Or as another do expression variant:
>
>const x = do {
>  switch (v) {
>case "foo": 1; break;
>case "bar": 3; break;
>case "baz": 6; break;
>default: 99; break;
>  }
>}
>
> And as I'm thinking about switch expressions:
>
>const x = switch (v) {
>  case "foo" => 1;
>  case "bar" => 3;
>  case "baz" => 6;
>  default => 99;
>}
>
> What I really like is that it preserves all of the normal JavaScript syntax 
> with the small change that a switch is allowed in an expression provided that 
> all of the cases evaluate to expressions hence the use of the '=>' as an 
> indicator.  Fundamentally this is a very basic concept where you have a state 
> machine and need it switch based on the current state and evaluate to the new 
> state.
>
>const nextState = switch (currentState) {
>   case ... =>
>}
>
>
>
> On 2/25/19 4:00 PM, Jordan Harband wrote:
>
> 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

Re: Proposal: throw null operator

2019-02-24 Thread Isiah Meadows
Not sure what the benefit is over just `if (value != null) throw value`,
especially for this niche of a use case.
On Sun, Feb 24, 2019 at 09:46 IdkGoodName Vilius <
viliuskubilius...@gmail.com> wrote:

> I am proposing a syntatic sugar, which would check if throw value is not
> null, or not undefined. It would make less typing and no if, for throw
> statements. Syntax is simple. Here's an example of it:
> ```js
> throw? e
> ```
> This is basically equivalent to:
> ```js
> if(e !== null && e !== undefined) throw e
> ```
> What's the purpose of that? Well, in some node js modules, error as null,
> or undefined is sometimes passed.
> Example of that is:
> ```js
> const {exec} = require('child_process')
> exec('...', {cwd: '...'}, (err, stdout, stderr) => {
> if(err !== null) throw err
> })
> ```
>
>
> 
>  Virus-free.
> www.avast.com
> 
> <#m_-3729250569814530580_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: switch statement multiple

2019-02-15 Thread Isiah Meadows
It's being considered, just indirectly through a more powerful feature:
https://github.com/tc39/proposal-pattern-matching
On Fri, Feb 15, 2019 at 23:02 Juan Pablo Garcia  wrote:

> I think it would be great if the switch statement allows multiple argument
>
> Example
> Switch(a,b)
> Case: 1,true
> Case: 1,false
> Case: 2,true
> 
>
>
> Switch (true, true)
> Case: isPremium,  true
> Case: isBasic, hasCredit
> Case: isBasic, !hasCredit
>
>
> Maybe case: default, true
>
> Look forward to read yours views.
>
>
>
> I used to code in cobol and was very useful the sintax
> COBOL example:
> Evaluate a also b
> When 1 also true
> When any also false
> ___
> 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-14 Thread Isiah Meadows
They don't optimize this. Also, in an earlier reply, I mentioned I'm
not a fan of that kind of hack, especially considering the obvious
`Reflect.ownKeys(x).length === 0` doesn't work when `x` is
`null`/`undefined`, while `for ... of` does.

-Isiah meadowscont...@isiahmeadows.comwww.isiahmeadows.com
On Thu, Feb 14, 2019 at 5:43 AM Herby Vojčík  wrote:
>
> On 14. 2. 2019 7:54, Jordan Harband wrote:
> > `Reflect.ownKeys(x || {}).length === 0`?
>
> This seems to reify key list. That gist of the OP is probably to be able
> to be able to tell fast enough if it's empty.
>
> Or are JS engines actually doing this fast (like returning "virtual"
> keys list for which they can tell .length fast and only actually reify
> the keys themselves lazily)?
>
> Herby
>
> > On Wed, Feb 13, 2019 at 10:31 PM Isiah Meadows  > <mailto:isiahmead...@gmail.com>> 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 <mailto:cont...@isiahmeadows.com>
> > www.isiahmeadows.com <http://www.isiahmeadows.com>
> > ___
> > es-discuss mailing list
> > es-discuss@mozilla.org <mailto: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-14 Thread Isiah Meadows
I meant `true` for those - I had my conditions flipped. My bad.

-

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

On Thu, Feb 14, 2019 at 8:55 AM Andrea Giammarchi
 wrote:
>
> > 1. If `value` is either `null` or `undefined`, it gracefully falls back to 
> > `false` instead of throwing an error.
>
> I am having hard time logically thinking of an empty void as false:
>
> Object.isEmpty(void 0) is false ?
>
> I think keys(o || {}).length === 0 is a more explicit, ambiguity free, 
> alternative.
>
> isEmpty(null) === false when typeof null is still object also doesn't feel 
> too right.
>
>
> On Thu, Feb 14, 2019 at 7:31 AM 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


Proposal: `Object.isEmpty(value)`

2019-02-13 Thread Isiah Meadows
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


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 Isiah Meadows
I presume you've *never* written non-trivial server-side logic in
Node. I find myself using classes *far* more often in Node than in the
browser simply because it's more than just passing strings and object
bags around. You've got caching, process management, and even
sometimes task queues. The traditional MVC architecture doesn't need
classes to implement in Node (and the corresponding idioms don't use
them, either), but it's all the machinery around it that result in all
the server-side classes.

Also, I'd like to note a few things:

- Some functional languages, notably OCaml, support classes with
classical inheritance. Inheritance *does* actually help from time to
time.
- JS is not opinionated on the matter - it supports both styles. In
fact, it lacks some of the utilities for pure POJO passing and
manipulation, while classes are mostly complete. In reality, it's
slightly biased *in favor* of classes, something several people have
been complaining about (me included).
- I'm *very* well used to passing POJOs around to static functions -
it's called functional programming.

> its not a design-flaw.  the flaw is you trying to shoehorn “classical” 
> inheritance-based design-patterns on a language better suited to use 
> static-functions to baton-pass json-data (over class-instance).
___
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 Isiah Meadows
I get that, but it's usually part of the API subclassing contract that
the superclass *explicitly* depends on certain parts of the subclass.
Abstract classes immediately come to mind, and I'd say it's no more
leaking than any inherited method. It's not giving them any more
access to information than they would've gotten from an explicit `if
(new.target === Subclass) this.init()` call at the end (which is
basically what I want mod the exposed method).

-

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

On Sat, Feb 9, 2019 at 4:53 PM Jordan Harband  wrote:
>
> 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: A way to fire logic at the end of completion of the current class method (regardless of super call order).

2019-02-09 Thread Isiah Meadows
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


Re: returning non-Promise values from async functions and running them synchronously (or Promise.sync() idea)

2019-02-03 Thread Isiah Meadows
I agree that sometimes-sync is always a nightmare, and I've
experienced this pain personally from a library API that once did
this. (I did succeed in getting it to eventually change.) I'm willing
to draw exception for things like APIs that wrap both sync and async
iterators, but those literally provide two separate entry points in
the form of `Symbol.iterator` vs `Symbol.asyncIterator` methods.

-

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

On Mon, Feb 4, 2019 at 1:43 AM Jordan Harband  wrote:
>
> Typically, APIs that are sometimes sync and sometimes async are called 
> "zaļgo" - 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"
>>> &qu

Re: idea: Array.prototype.remove

2019-02-03 Thread Isiah Meadows
The proposed `remove` here is actually in-place. And this really is
not unlike this proposal of mine [1], which is also in place.

The reason it belongs in the standard library is because you can
optimize it *way* better using vector instructions and it's among one
of the most common cases for `.filter` - how often have you done
`array.filter(x => x !== value)`? With my `Array.prototype.delete`,
you could do `array.slice().delete(value, true)` for practically the
same thing (it's 3 extra characters), just done a bit faster thanks to
not needing the overhead.

- For deleting a single value* from a dense array, you could optimize
it much like `array.indexOf` followed by `array.copyWithin` +
`array.length -= 1` if the value exists.
- For deleting multiple values* from a dense array, you'd do it
similarly, just you'd keep a separate offset that you'd increment on
each hit, subtracting that for the stores.
- In each case, your search would be a mix of SIMD with horizontal
reductions, things most modern processors make easy.

* With a few exceptions, of course. Doubles in V8 and 32-bit
SpiderMonkey are one of them, since they are boxed and compared by
their contents. Multi-character strings are another big exception.

The reason I called mine `delete` instead of `remove` is to align with
`Set.prototype.delete` and `Map.prototype.delete`, which operate
similarly.

[1]: 
https://github.com/isiahmeadows/es-stdlib-proposals/blob/master/proposals/array/delete.md

-

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

On Mon, Feb 4, 2019 at 1:40 AM Jordan Harband  wrote:
>
> 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
___
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 Isiah Meadows
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


Re: Proposal: Default object method

2019-01-28 Thread Isiah Meadows
Nit: you may need to reset the function's prototype. Also, `create` should
probably be static. ;-)
On Mon, Jan 28, 2019 at 01:46 Ranando King  wrote:

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

Re: NumberFormat maxSignificantDigits Limit

2019-01-24 Thread Isiah Meadows
For all here interested, you might want to follow this Twitter
conversation I started. My theory is a subtle spec bug that copied the
number instead of recalculating the formula.

https://twitter.com/isiahmeadows1/status/108851744948878

-

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

-

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


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

Re: NumberFormat maxSignificantDigits Limit

2019-01-20 Thread Isiah Meadows
I feel this is probably best asked at https://github.com/tc39/ecma402,
since it seems to imply a potential spec bug.

-

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


On Sun, Jan 20, 2019 at 2:31 PM Anders Rundgren <
anders.rundgren@gmail.com> wrote:

> On 2019-01-20 20:18, Ethan Resnick wrote:
> > Hi,
> >
> > Apologies if es-discuss is the wrong venue for this; I've tried first
> poring through the specs and asking online to no avail.
> >
> > My question is: why is the limit for the `maximumSignificantDigits`
> option in the `NumberFormat` API set at 21? This seems rather arbitrary —
> and especially odd to me given that, iiuc, all Numbers in JS, as 64 bit
> floats, can only encode up to 17 significant decimal digits. Is this some
> sort of weird historical artifact of something? Should the rationale be
> documented anywhere?
>
> I don't know for sure but if you input this in a browser debugger it will
> indeed respond with the same 21 [sort of] significant digits
> 0
>
> rgds,
> Anders
> >
> > Thanks!
> >
> > Ethan
> >
> > ___
> > es-discuss mailing list
> > es-discuss@mozilla.org
> > https://mail.mozilla.org/listinfo/es-discuss
> >
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Proposal: enhanced case clause

2019-01-20 Thread Isiah Meadows
I'd say the best way is to just file an issue.

-

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


On Sun, Jan 20, 2019 at 3:59 AM Sm In  wrote:

> Thank you for answer, I've checked thart proposal before.
> As I know, proposal-pattern-matching contains guards(which checkes value's
> property)
>
> Yes, this proposal's new sementic seems duplicate pattern match's guard.
> But, As I know, the guard can be associcated with only one pattern.
> here is an example from proposal-pattern-matching:
>
> ```js
>
> const res = await fetch(jsonService)case (res) {
>   when {status: 200, headers: {'Content-Length': s}} -> {
> console.log(`size is ${s}`)
>   }
>   when {status: 404} -> {
> console.log('JSON not found')
>   }
>   when {status} if (status >= 400) -> {
> throw new RequestError(res)
>   }
> }
>
> ```
>
> Okay, looks fine, but how about when we want to send different error when
> error code is 5xx?
> do I have to do this?
>
> ```js
>
> const res = await fetch(jsonService)case (res) {
>   when {status: 200, headers: {'Content-Length': s}} -> {
> console.log(`size is ${s}`)
>   }
>   when {status: 404} -> {
> console.log('JSON not found')
>   }
>   when {status} if (status >= 400 && status < 500) -> {
> throw new RequestError(res)
>   }
>   when {status} if (status >= 500) -> {
> throw new InternalServerError(res)
>   }
> }
>
> ```
>
> Humm, this looks odd, we duplicate `when {status}` twice!
> so, I can say: "pattern matching is good at checking value's structure.
> checking it's property is small option."
>
> I don't know which one is better choice, pushing this proposal or add this
> problem as issue to proposal-pattern-matching(they have [some plans](
> https://github.com/tc39/proposal-pattern-matching/blob/latest/TO_INFINITY_AND_BEYOND.md)
> for future, and this can be merged into there).
> and creating genenral syntax or creating specific syntax in order to solve
> problem.
>
> please help me to figure out in this problem :))
> ___
> 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: RegExp.prototype.count

2019-01-19 Thread Isiah Meadows
Nit: you should use `.spilt(/\n/g)` to get all parts.

I like the benchmarks here. That's much appreciated, and after further
investigation, I found a *giant* WTF:
https://jsperf.com/regexp-counting-2/8

TL;DR: for string character counting, prefer `indexOf`.

For similar reasons to that JSPerf thing, I'd like it to be on the
String prototype rather than the RegExp prototype, as in
`str.count(/\n/)`.

-

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

On Sun, Jan 20, 2019 at 12:33 AM kai zhu  wrote:
>
> benchmarked @isiah’s while-loop test-case vs str.split vs str.replace for 
> regexp counting on jsperf.com [1], and the results were surprising (for me).
>
> benchmarks using 1mb random ascii-string from fastest to slowest.
> 1. (fastest - 1,700 runs/sec) regexp-counting with 
> ```largeCode.split(/\n/).length - 1```
> 2. (40% slower - 1000 runs/sec) regexp-counting with ```while-loop (/n/g)```
> 3. (60% slower - 700 runs/sec) regexp-counting with 
> ```largeCode.replace((/[^\n]+/g), "").length```
>
> looks like the go-to design-pattern for counting-regexp is 
> ```str.split().length - 1```
>
> [1] regexp counting 2
> https://jsperf.com/regexp-counting-2
>
> On 13 Jan 2019, at 9:15 PM, Isiah Meadows  wrote:
>
> If performance is an issue, regular expressions are likely to be too slow to 
> begin with. But you could always do this to count the number of lines in a 
> particular string:
>
> ```js
> var count = 0
> var re = /\n|\r\n?/g
> while (re.test(str)) count++
> console.log(count)
> ```
>
> Given it's already this easy to iterate something with a regexp, I'm not 
> convinced it's necessary to add this property/method.
> On Sat, Jan 12, 2019 at 17:29 kai zhu  wrote:
>>
>> a common use-case i have is counting newlines in largish (> 200kb) 
>> embedded-js files, like this real-world example [1].  ultimately meant for 
>> line-number-preservation purposes in auto-lint/auto-prettify tasks (which 
>> have been getting slower due to complexity).
>>
>> would a new RegExp count-method like ```(/\n/g).count(largeCode)``` be 
>> significantly more efficient than existing ```largeCode.split("\n").length - 
>> 1``` or ```largeCode.replace((/[^\n]+/g), "").length```?
>>
>> -kai
>>
>> [1] calculating and reproducing line-number offsets when linting/autofixing 
>> files
>> https://github.com/kaizhu256/node-utility2/blob/2018.12.30/lib.jslint.js#L7377
>> https://github.com/kaizhu256/node-utility2/blob/2018.12.30/lib.jslint.js#L7586
>>
>> ___
>> 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


PSA: You can find existing proposals at https://github.com/tc39/proposals

2019-01-19 Thread Isiah Meadows
Not TC39, so don't read this as official communication.

I've lately been seeing the occasional suggestion that's already been
considered by TC39 and accepted, so I just wanted to give a public
service announcement that you can find all the various existing
proposals TC39 has considered (Stage 1-4), as well as many conceptual
proposals that members have created and championed but haven't yet
brought before the committee (Stage 0), here:
https://github.com/tc39/proposals

That repository includes a few interesting things proposed in the last
few months on this list, such as:

- Upgraded `switch`: https://github.com/tc39/proposal-pattern-matching
- Stack trace analysis: https://github.com/tc39/proposal-error-stacks
- Placeholder syntax: https://github.com/tc39/proposal-partial-application
- Python `with` syntax: https://github.com/tc39/proposal-using-statement

So before you propose something, please check there first. You might
find it's already being considered, and if your proposal would differ
significantly from theirs and you feel yours is better, it's best to
give feedback in that proposal's repo, so it's more likely to get
noticed and heard by the appropriate audience.

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: [Symbol.equals]

2019-01-18 Thread Isiah Meadows
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.com> 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_-3789658945863370968_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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


  1   2   3   4   5   6   7   8   9   10   >