Re: Since JSDoc seems cerebrally dead...

2020-11-11 Thread Jacob Bloom
This SO answer provides a typing for Object.assign that appears to
basically do the right thing: https://stackoverflow.com/a/51603499 -- but
none of the above libraries use this kind of solution, which leads me to
think it might not be totally robust

On Wed, Nov 11, 2020 at 1:27 PM Jordan Harband  wrote:

> Of course there's a way - it's just that TS's built-in types don't
> consistently go the extra mile, and often resort to `any`. See
> https://github.com/DefinitelyTyped/DefinitelyTyped/blob/5344bfc80508c53a23dae37b860fb0c905ff7b24/types/object-assign/index.d.ts,
> or
> https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/lodash/common/object.d.ts#L32-L52,
> for two examples of `Object.assign`, as an example.
>
> On Wed, Nov 11, 2020 at 8:51 AM Michaël Rouges 
> wrote:
>
>> Some other cases, not covered, even in JSDoc nor TS
>>
>> There is no way to describe the result, to the IDE's intellisense, for
>> those ES5/ES2015 features:
>> `Object.create(prototype, descriptors)`
>> https://github.com/microsoft/TypeScript/blob/master/lib/lib.es5.d.ts#L192
>> `Object.assign(obj, ...mixins)`
>> https://github.com/microsoft/TypeScript/blob/master/lib/lib.es2015.core.d.ts#L313
>>
>> I really love JS, but if there is no way to help the IDE to understand
>> complex things, it's like to code with a Notepad.exe
>>
>> Any TC feelings about that, please?
>>
>> Michaël Rouges - https://github.com/Lcfvs - @Lcfvs
>>
>>
>> Le dim. 18 oct. 2020 à 05:27, #!/JoePea  a écrit :
>>
>>> That would be interesting indeed. Encouraging documentation is great I
>>> think.
>>> #!/JoePea
>>>
>>> On Sat, Oct 17, 2020 at 3:38 AM Michaël Rouges 
>>> wrote:
>>> >
>>> > Yeah, I prefer the JSDoc solution too for the same reasons... but
>>> JSDoc is really slow to evolve,
>>> > always several years behind the standard, a lot of solutions to
>>> describe our code are more relevant
>>> > to **tricks**, generally found on the JSDoc issues, than something
>>> formal.
>>> >
>>> > The coverage isn't the same... really, I'm dreaming about a standard
>>> annotation for each ES feature,
>>> > covering all the usages. **when that feature is released**.
>>> >
>>> >
>>> > Michaël Rouges - https://github.com/Lcfvs - @Lcfvs
>>> >
>>> >
>>> > Le sam. 17 oct. 2020 à 03:29, #!/JoePea  a écrit :
>>> >>
>>> >> Would official syntax be worth it (JSDoc being officially
>>> standardized)?
>>> >>
>>> >> Maybe it's a matter of time: Perhaps now that JSDoc is useful for type
>>> >> checking (thanks to TypeScript and its ability to type check plain
>>> >> JavaScript that is annotated with JSDoc) it may be closer to reality.
>>> >>
>>> >> I prefer JSDoc type annotation in plain .js files over writing .ts
>>> >> files, because it means I can write type-checked code that has great
>>> >> intellisense in modern editors like VS Code, without needing any build
>>> >> steps and with end users being able to consume those source files
>>> >> directly in any way they want (possibly also without build tools).
>>> >> However, JSDoc can not currently do everything that regular TypeScript
>>> >> syntax can do (there's some open issues regarding that in the
>>> >> TypeScript repo).
>>> >>
>>> >> #!/JoePea
>>> >>
>>> >> On Wed, Oct 14, 2020 at 11:53 AM kai zhu  wrote:
>>> >> >
>>> >> > > Sorry but my question isn't about providing a tool to generate
>>> our documentations but to have a standard syntax to describe our code
>>> (signatures). ;)
>>> >> >
>>> >> > not standard-practice, but my style is to have documentation of
>>> functions inside the function (rather than above it).
>>> >> > simplifies doc-generation by calling function's `.toString()`
>>> (rather than having to parse the parse the entire script):
>>> >> >
>>> >> > ```js
>>> >> > let html;
>>> >> > let local;
>>> >> > local = {};
>>> >> > local.foo1 = function (aa, bb) {
>>> >> > /*
>>> >> >  * this function will blah blah blah
>>> >> >  */
>>> >> > return aa + bb;
>>> >> > };
>>> >> > local.foo2 = function (cc, dd) {
>>> >> > /*
>>> >> >  * this function will yada yada yada
>>> >> >  */
>>> >> > return cc + dd;
>>> >> > };
>>> >> >
>>> >> > // auto-generate doc for functions in namespace 
>>> >> > html = "\n\n";
>>> >> > Object.entries(local).sort().forEach(function ([
>>> >> > name, obj
>>> >> > ]) {
>>> >> > if (typeof obj === "function") {
>>> >> > obj.toString().replace((
>>> >> >
>>>  /function\b.*?(\([\S\s]*?\))\s*?\{\n?(\s*?\/\*[\S\s]*?\*\/)/
>>> >> > ), function (ignore, signature, comment) {
>>> >> > html += "function " + name + " " + signature.trim()
>>> + "\n";
>>> >> > html += "\n" + comment + "\n\n";
>>> >> > html += "\n";
>>> >> > });
>>> >> > }
>>> >> > });
>>> >> > html += "\n";
>>> >> > console.log(html);
>>> >> > ```
>>> >> >
>>> >> > output
>>> >> > ```html
>>> >> > 
>>> >> >
>>> >> > function foo1 (aa, bb)
>>> >> > 
>>> >> > /*
>>> >> >  * this function will blah blah blah
>>> >> >  */
>>> >> > 
>>> >> >

Re: Default values for nulls

2020-10-13 Thread Jacob Bloom
I'd find it more readable to allow an assignment operator, with the
semantic "do this transformation, using the passed value as the previous
value"

```
function (x ??= 123) {} // If passed null or undefined, x = 123
function (x &&= 123) {} // If passed a truthy value, x = 123
function (x += 123) {} // Regardless of type, add 123 to x
```

That said, I can see how allowing the arithmetic-assignment (and
concat-assignment) operators could lead hard-to-debug code that uses some
"I am very smart" shortcuts, so I'd opt to start with the
logical-assignment operators

On Tue, Oct 13, 2020 at 9:08 AM Naveen Chawla  wrote:

> What about allowing any expression then?
>
> x || 4
> x/4
> x + 4
> x + w //maybe allow only "previous" parameter values as scope
> x + a //SyntaxError: 'a' undefined in parameters scope
>
> On Tue, 13 Oct 2020 at 14:39, Michael Luder-Rosefield <
> rosyatran...@gmail.com> wrote:
>
>> I know I am not the only one who has had several perfectly good use-cases
>> for default values disallowed, because the value coming in was `null`, not
>> `undefined`.
>>
>> I cannot be the only one who has let bugs slip in because of failing to
>> consider this case.
>>
>> So, if we can find a non-confusing and simple way to alter the spec to
>> allow for handling this, I imagine it would be considered useful and wanted.
>>
>> The obvious candidate is the nullish coalescing operator, which is
>> already part of the spec. Unfortunately, it is currently invalid to
>> indicate default values with it. I can't see any reason against changing
>> this.
>>
>> ```
>> function foo1 (x = 4) {
>>   console.log(x);
>> }
>>
>> // currently causes SyntaxError
>> function foo2 (x ?? 4) {
>>   console.log(x);
>> }
>>
>> foo1(null); // null
>> foo1(undefined) // 4
>>
>> foo2(null); // 4
>> foo2(undefined) // 4
>>
>> // currently causes SyntaxError
>> // should give x === null, y === 4
>> const { x = 2, y ?? 4 } = { x: null, y: null };
>> ```
>> --
>> Dammit babies, you've got to be kind.
>> ___
>> es-discuss mailing list
>> es-discuss@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: Flags enums

2020-08-26 Thread Jacob Bloom
For what it's worth, TypeScript has Enums built-in and I find myself using
string literal types instead:

```typescript
type CollisionType = 'CIRCLE' | 'CUBIC_BEZIER_CURVE' | 'RIGID_BODY';

function handleCollision(type: CollisionType) {
  if (type === 'CIRCLE') {
// ...
  } else if (type === 'SQUARE') { // Tooling errors on this line
// ...
  }
}
```

In VSCode (and I assume other IDEs that support TypeScript) you can even do
this in vanilla JS with structured JSDoc comments and the tooling will type
check for you:

```javascript
// @ts-check

/** @typedef {'CIRCLE' | 'CUBIC_BEZIER_CURVE' | 'RIGID_BODY'} CollisionType
*/

/**
 * @param {CollisionType} type
*/
function handleCollision(type) {
  if (type === 'CIRCLE') {
// ...
  } else if (type === 'SQUARE') { // Tooling errors on this line
// ...
  }
}
```

As far as I know, comparing strings is nearly as performant in most JS
engines as comparing numbers or objects because they use a method called
"string interning"

On Wed, Aug 26, 2020 at 2:25 PM Matheus Dias de Souza 
wrote:

>
>
> The com.siteblade.util package contains an approximation of this in
> ECMAScript, with no difference, except the valueOf() method (which returns
> String for working with equality), so it ends up with an additional getter
> ‘number’.
>
>
>
> https://www.npmjs.com/package/com.siteblade.util
>
>
>
> You can use either FlagsEnum or Enum.
>
>
>
> import { Enum } from 'com.siteblade.util';
>
>
>
> const CollisionType = Enum('CollisionType', [
>
> ['CIRCLE'],
>
> ['CUBIC_BEZIER_CURVE', [10]],
>
> ['RIGID_BODY', ['rigidBody', 2]]
>
> ]);
>
>
>
> var type = CollisionType('cubicBezierCurve');
>
> console.log( type == 'cubicBezierCurve' );
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Since JSDoc seems cerebrally dead...

2020-08-17 Thread Jacob Bloom
> This feels like rich territory for a blog post, if someone feels
qualified? Specifically, just running the typescript tool chain for jsdoc
annotations, which are excellent for all the reasons mentioned above
(comments only, vanilla js etc).

Does this count?
https://devblogs.microsoft.com/typescript/how-to-upgrade-to-typescript-without-anybody-noticing-part-1/

On Mon, Aug 17, 2020 at 2:56 PM Dan Peddle  wrote:

> This feels like rich territory for a blog post, if someone feels
> qualified? Specifically, just running the typescript tool chain for jsdoc
> annotations, which are excellent for all the reasons mentioned above
> (comments only, vanilla js etc).
>
> On 17. Aug 2020, at 19:35, Andrea Giammarchi 
> wrote:
>
> 
> Sorry, new link:
> https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
>
> On Mon, Aug 17, 2020 at 8:34 PM Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> TS supports JSDocs already
>>
>> https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#supported-jsdoc
>>
>> On Mon, Aug 17, 2020 at 8:31 PM Bergi  wrote:
>>
>>> Hi,
>>>
>>> > They don't want to add TS to their stack.
>>>
>>> Then what else would they want to add to their stack? Notice one doesn't
>>> necessarily need the TypeScript Compiler to add TypeScript- or Flow-like
>>> type annotations and remove them in a build step - Babel for example
>>> could do that just fine as well.
>>> Or are you asking for a jsdoc-like thing that lives in comments, where
>>> the code can be run without a compilation step?
>>>
>>> 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Any way to detect an async stack trace (like Chrome devtools does)?

2020-07-12 Thread Jacob Bloom
Reading through the issue JoePea linked to, it looks like the difficulties
with standardized async stack traces are twofold:

1. Even with the error stacks proposal, the implementer has total say over
what qualifies as a stack frame
2. The way promises are chained means that some patterns like async loops
would theoretically unroll to very long stack traces, and right now engines
aren't required to keep track of those frames; requiring them to do so
would place a burden on implementers that could quickly lead to slowdowns
and memory issues

What if there was a standard way to mark a Promise as an important stack
frame, which the implementer is free to ignore? Maybe something like
`Promise.prototype.trace()`

On Fri, Jul 10, 2020 at 10:22 PM #!/JoePea  wrote:

> Hello Kai! That example is so meta with its own output showing the
> numbers relative to the code including its own output! :)
>
> That's what I originally wanted to do, but that doesn't give us an
> async stack trace, it only gives a sync stack trace (I presume within
> the current event loop task).
>
> For example:
>
> ```js
> const originalFetch = globalThis.fetch
>
> globalThis.fetch = function(...args) {
>   const stack = new Error().stack
>   console.log(stack)
>   return originalFetch.apply(globalThis, args)
> }
>
> const sleep = t => new Promise(r => setTimeout(r, t))
>
> async function one() {
>   console.log('1')
>   await sleep(10)
>   two()
> }
>
> async function two() {
>   console.log('2')
>   await sleep(10)
>   three()
> }
>
> async function three() {
>   console.log('3')
>   await sleep(10)
>   return await fetch('https://unpkg.com/three@0.118.3')
> }
>
> async function main() {
>   await one()
> }
>
> main()
> ```
>
> Output:
>
> ```
> 1
> 2
> 3
> Error
> at globalThis.fetch (pen.js:5)
> at three (pen.js:27)
> ```
>
> Live example:
>
>
> https://codepen.io/trusktr/pen/b8fd92752b4671268f516ad3804869e4?editors=1010
>
> I opened a request for this over here:
> https://github.com/tc39/proposal-error-stacks/issues/34
>
> #!/JoePea
>
> On Fri, Jul 10, 2020 at 1:21 PM kai zhu  wrote:
> >
> > >  (I want to detect traces in third-party code installed locally).
> >
> > 1. here's 15-line javascript-hack to trace async-fetch-calls from
> 3rd-party-cdn-library
> >
> > ```html
> > 
> > 
> > 
> > test.html
> > 
> > (function () {
> > /*
> >  * 15-line-javascript-hack to trace async-fetch-calls
> >  * enable hack by adding search-query "?modeDebugFetch=1" to web-url
> >  */
> > "use strict";
> > if ((/\bmodeDebugFetch=1\b/).test(location.search)) {
> > let fetch0;
> > fetch0 = globalThis.fetch;
> > globalThis.fetch = function (...argList) {
> > let errStack = new Error().stack;
> > console.error("\n\nfetch-call-arguments:");
> > console.error(JSON.stringify(argList, undefined, 4));
> > console.error("\n\nfetch-call-trace:");
> > console.error(errStack);
> > return fetch0(...argList);
> > };
> > }
> > }());
> > 
> > 
> > https://unpkg.com/http-client/umd/http-client.js";>
> > 
> > (async function foo() {
> > "use strict";
> > let thirdParty = window.HTTPClient;
> > let myFetch = thirdParty.createFetch(
> > thirdParty.base("https://api.stripe.com/v1";),
> > thirdParty.accept("application/json")
> > );
> > let response = await myFetch("/customers/5");
> > console.log(response.jsonData);
> > /*
> > dev-console-output - http://localhost:8081/test.html?modeDebugFetch=1
> > fetch-call-arguments:
> > [
> > "https://api.stripe.com/v1/customers/5";,
> > {
> > "headers": {
> > "Accept": "application/json"
> > },
> > "responseHandlers": [
> > null
> > ]
> > }
> > ]
> > fetch-call-trace:
> > Error
> > at globalThis.fetch (test.html?modeDebugFetch=1:16)
> > at http-client.js:194
> > at http-client.js:127
> > at http-client.js:217
> > at http-client.js:126
> > at http-client.js:154
> > at http-client.js:95
> > at foo (test.html?modeDebugFetch=1:35)
> > at test.html?modeDebugFetch=1:64
> > */
> > }());
> > 
> > 
> > ```
> >
> >
> > 2. here's real-world-hack added to npm-cli.js to debug its http-requests
> >
> > ```diff
> > C:\Program Files\nodejs\node_modules\npm>git diff
> > diff --git a/bin/npm-cli.js b/bin/npm-cli.js
> > index 561dec0..98cafb8 100644
> > --- a/bin/npm-cli.js
> > +++ b/bin/npm-cli.js
> > @@ -2,17 +2,6 @@
> >  ;(function () { // wrapper in case we're in module_context mode
> > +// hack - debug http-request
> > +let httpRequest;
> > +httpRequest = require("https").request.bind(require("https"));
> > +require("https").request = function (...argList) {
> > +   

Re: Proposal: Forced Chaining Operator "!."

2020-04-26 Thread Jacob Bloom
(Sorry for the triple-post, I keep pondering this proposal) Come to think
of it, you could do something pretty similar with the `??=` operator from
the logical assignments proposal:

```javascript
(((table ??= {}).user ??= {}).id ??= {}).type = 'int';
```

The main difference being that it tests for nullishness instead of whether
the LHS is a non-null object, but I think that's within the spirit of the
original proposal. It also lets you set a custom default value (like the
"getsert" function above). The shortfall of course is the accumulating
parentheses

On Sat, Apr 25, 2020 at 8:08 PM Jacob Bloom 
wrote:

> Is the Perl syntax opt-in like the proposed operator? Or does it happen on
> all accesses to nulls? If it's opt-in in JS, then it doesn't seem to me
> that it'd cause too much unexpected behavior, though it could be argued
> that it's ripe for abuse by new devs trying to avoid errors.
>
> Something that might be a more generalized middle ground (and could later
> assist in transpiling the !. operator) is a "getsert" (?) method in the
> standard library that takes a default value and sets it on the parent
> object if that property is currently unset:
>
> ```javascript
> Object.getsert = (obj, identifier, defaultvalue) => {
>   if (!(identifier in obj)) obj[identifier] = defaultvalue;
>   return obj[identifier];
> }
>
> const table = {};
> console.log('before getsert:', table.user); // undefined
> console.log('during getsert:', Object.getsert(table, 'user', 5)); // 5
> console.log('after getsert:', table.user); // 5
> ```
>
> ...I have concerns about such a method's usability though, since a getsert
> is far more verbose than a normal get. It'd be more convenient on
> Object.prototype (e.g. `table.getsert('user', 5)` ), but I assume that's a
> no-go.
>
> Oh also, I think the proposed syntax would collide with
> TypeScript's non-null assertion operator
> https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator
>  --
> I don't know to what degree that's a concern when proposing new JS syntax
>
> On Sat, Apr 25, 2020 at 3:00 PM Joe Eagar  wrote:
>
>>
>> Anyone have ideas on more examples? It’s tempting to make a transpiler
>> plugin to see how it works in practice, but I’d like to see more examples
>> first. Thanks
>>
>> On Sat, Apr 25, 2020 at 1:12 PM Jacob Bloom 
>> wrote:
>>
>>> Maybe it would be less footgunny to support autovivification in a more
>>> class-based way, like Python does?
>>>
>>> ```javascript
>>> class AutoVivArray extends Array {
>>>   [Symbol.getMissing](identifier) {
>>> /* if we're here, identifier is not an ownProperty
>>>  * and is nowhere on the prototype chain */
>>> this[identifier] = new Whatever();
>>> return this[identifier];
>>>   }
>>> }
>>> ```
>>>
>>> Though I can't see how that's much more useful than Proxies besides
>>> saving you a little boilerplate
>>>
>>> On Fri, Apr 24, 2020 at 3:23 PM Thomas Shinnick 
>>> wrote:
>>>
>>>> You are describing Perl's autovivification feature. Also possible (in
>>>> that syntax) for arrays and mixed object/array chains. I liked it, but many
>>>> saw it as a footgun. There was even a compile time module to turn off the
>>>> feature, if the coder wanted more caution. Having mentioned Perl I will
>>>> assume this is DOA?
>>>>
>>>> On Fri, Apr 24, 2020, 14:36 Tobias Buschor 
>>>> wrote:
>>>>
>>>>> Since we now have the "Optional Chaninig Operator" , perhaps a "Forced
>>>>> Chaining Operator" would also be worth considering.
>>>>> I, personally, could use it:
>>>>>
>>>>> let table;
>>>>> table!.user!.id!.type = 'int'
>>>>>
>>>>> will evaluate to:
>>>>>
>>>>> let table;
>>>>> if ( ! ( table instanceOf Object) ) table = {};
>>>>> if ( ! ( table.user instanceOf Object) ) table.user = {};
>>>>> if ( ! ( table.user.id instanceOf Object) ) table.user.id = {};
>>>>> table.user.id.type = 'int';
>>>>>
>>>>> Also to be noted:
>>>>> Sometimes a fallback to `Object.create(null)` or something other might
>>>>> be desirable.
>>>>> But since `{}` is syntactical sugar for
>>>>> `Object.create(Object.prototype)`, this would be consistent.
>>>>>
>>>>> ___
>>>>> es-discuss mailing list
>>>>> es-discuss@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: Forced Chaining Operator "!."

2020-04-25 Thread Jacob Bloom
Is the Perl syntax opt-in like the proposed operator? Or does it happen on
all accesses to nulls? If it's opt-in in JS, then it doesn't seem to me
that it'd cause too much unexpected behavior, though it could be argued
that it's ripe for abuse by new devs trying to avoid errors.

Something that might be a more generalized middle ground (and could later
assist in transpiling the !. operator) is a "getsert" (?) method in the
standard library that takes a default value and sets it on the parent
object if that property is currently unset:

```javascript
Object.getsert = (obj, identifier, defaultvalue) => {
  if (!(identifier in obj)) obj[identifier] = defaultvalue;
  return obj[identifier];
}

const table = {};
console.log('before getsert:', table.user); // undefined
console.log('during getsert:', Object.getsert(table, 'user', 5)); // 5
console.log('after getsert:', table.user); // 5
```

...I have concerns about such a method's usability though, since a getsert
is far more verbose than a normal get. It'd be more convenient on
Object.prototype (e.g. `table.getsert('user', 5)` ), but I assume that's a
no-go.

Oh also, I think the proposed syntax would collide with
TypeScript's non-null assertion operator
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator
--
I don't know to what degree that's a concern when proposing new JS syntax

On Sat, Apr 25, 2020 at 3:00 PM Joe Eagar  wrote:

>
> Anyone have ideas on more examples? It’s tempting to make a transpiler
> plugin to see how it works in practice, but I’d like to see more examples
> first. Thanks
>
> On Sat, Apr 25, 2020 at 1:12 PM Jacob Bloom 
> wrote:
>
>> Maybe it would be less footgunny to support autovivification in a more
>> class-based way, like Python does?
>>
>> ```javascript
>> class AutoVivArray extends Array {
>>   [Symbol.getMissing](identifier) {
>> /* if we're here, identifier is not an ownProperty
>>  * and is nowhere on the prototype chain */
>> this[identifier] = new Whatever();
>> return this[identifier];
>>   }
>> }
>> ```
>>
>> Though I can't see how that's much more useful than Proxies besides
>> saving you a little boilerplate
>>
>> On Fri, Apr 24, 2020 at 3:23 PM Thomas Shinnick 
>> wrote:
>>
>>> You are describing Perl's autovivification feature. Also possible (in
>>> that syntax) for arrays and mixed object/array chains. I liked it, but many
>>> saw it as a footgun. There was even a compile time module to turn off the
>>> feature, if the coder wanted more caution. Having mentioned Perl I will
>>> assume this is DOA?
>>>
>>> On Fri, Apr 24, 2020, 14:36 Tobias Buschor 
>>> wrote:
>>>
>>>> Since we now have the "Optional Chaninig Operator" , perhaps a "Forced
>>>> Chaining Operator" would also be worth considering.
>>>> I, personally, could use it:
>>>>
>>>> let table;
>>>> table!.user!.id!.type = 'int'
>>>>
>>>> will evaluate to:
>>>>
>>>> let table;
>>>> if ( ! ( table instanceOf Object) ) table = {};
>>>> if ( ! ( table.user instanceOf Object) ) table.user = {};
>>>> if ( ! ( table.user.id instanceOf Object) ) table.user.id = {};
>>>> table.user.id.type = 'int';
>>>>
>>>> Also to be noted:
>>>> Sometimes a fallback to `Object.create(null)` or something other might
>>>> be desirable.
>>>> But since `{}` is syntactical sugar for
>>>> `Object.create(Object.prototype)`, this would be consistent.
>>>>
>>>> ___
>>>> es-discuss mailing list
>>>> es-discuss@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: Forced Chaining Operator "!."

2020-04-25 Thread Jacob Bloom
Maybe it would be less footgunny to support autovivification in a more
class-based way, like Python does?

```javascript
class AutoVivArray extends Array {
  [Symbol.getMissing](identifier) {
/* if we're here, identifier is not an ownProperty
 * and is nowhere on the prototype chain */
this[identifier] = new Whatever();
return this[identifier];
  }
}
```

Though I can't see how that's much more useful than Proxies besides saving
you a little boilerplate

On Fri, Apr 24, 2020 at 3:23 PM Thomas Shinnick  wrote:

> You are describing Perl's autovivification feature. Also possible (in
> that syntax) for arrays and mixed object/array chains. I liked it, but many
> saw it as a footgun. There was even a compile time module to turn off the
> feature, if the coder wanted more caution. Having mentioned Perl I will
> assume this is DOA?
>
> On Fri, Apr 24, 2020, 14:36 Tobias Buschor 
> wrote:
>
>> Since we now have the "Optional Chaninig Operator" , perhaps a "Forced
>> Chaining Operator" would also be worth considering.
>> I, personally, could use it:
>>
>> let table;
>> table!.user!.id!.type = 'int'
>>
>> will evaluate to:
>>
>> let table;
>> if ( ! ( table instanceOf Object) ) table = {};
>> if ( ! ( table.user instanceOf Object) ) table.user = {};
>> if ( ! ( table.user.id instanceOf Object) ) table.user.id = {};
>> table.user.id.type = 'int';
>>
>> Also to be noted:
>> Sometimes a fallback to `Object.create(null)` or something other might be
>> desirable.
>> But since `{}` is syntactical sugar for
>> `Object.create(Object.prototype)`, this would be consistent.
>>
>> ___
>> es-discuss mailing list
>> es-discuss@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-12-12 Thread Jacob Bloom
> It seems to me like you are doing block logic without blocks, which I think
> increases the chances of bugs.

I agree. Without curly braces, it's not always clear when the parallel
code is guaranteed to have executed by. The first version of my
proposal did something similar:

```javascript
const a = await|| doSomethingAsync();
const b = await|| doSomethingElseAsync();
const [aValue, bValue] = await async.all;
```

...where `async.all` represents something like
`Promise.all(promises)`. The problem is, if you forget the `await
async.all` then your promises never execute (within the function), so
accidentally using `await||` instead of `await` would have the
opposite of the intended effect.

`async { await|| ... }` sidesteps both of these issues: it makes it
clear when the promises have all settled by, and if `await` isn't
allowed in the curly brackets then it avoids the "wrong operator"
confusion issue as well.

> you're not leveraging the existing parallel execution pattern for async
> functions (which is just to omit the `await`), so it would seem you
> would be increasing learning overhead.

If `await||` (or whatever) is learned in conjunction with `async {}`
blocks, and is only allowed within them, then it just becomes "this is
the syntax for parallelism." And as already stated, you'd need an
explicit marker for which expressions are being awaited in parallel
for any reasonable transpilation.

> `const` and `let` are block-scoped, so this is referring to avoid that block
> notation, and then keep coherent with the possibility to directly infer in
> current scope references without extra segments / blocks.

Yeah, it'd be nice to have a syntax that doesn't create a block scope.
But that strikes me as less important than making it obvious where the
nondeterminism is.

I assume making these braces not create a block scope is unacceptable.
And using an alternative bracket (maybe `async [ await|| foo ]`) would
be too different from everything else in the language and might read
as an array, which discourages using non-expression statements inside
it



On Wed, Nov 27, 2019 at 9:57 AM Naveen Chawla  wrote:
>
> I don't know that an `await.all { ... }` block would be premature, especially 
> since it's straightforward, so I can't see it clashing with anything in the 
> future e.g. on the "observables" front, if that were to become a thing. If 
> the semantics of `await` were to be extended somehow, then identically and 
> naturally would the semantics of `await.all { ... }`.
>
> On Wed, 27 Nov 2019 at 01:43, Isiah Meadows  wrote:
>>
>> Just wanted to drop in and remind people of this by me earlier in the thread:
>> https://esdiscuss.org/topic/proposal-await-all-for-parallelism#content-10
>>
>> The way things are shaping up, it's starting to look like an ad-hoc version 
>> of this proposal of mine:
>> https://github.com/isiahmeadows/non-linear-proposal
>>
>> As I stated earlier, I feel it's premature, especially before we figure out 
>> how observables fit into it all.
>>
>> On Tue, Nov 26, 2019 at 09:48 Naveen Chawla  wrote:
>>>
>>> If I have, as per your examples,
>>>
>>> x1 = await||actionAsync1()
>>> x2 = await||actionAsync2(x1) //x1 is undefined here, only resolved on the 
>>> next "non-parallel-await"
>>>
>>> vs adding a line between the two calls:
>>>
>>> x1 = await||actionAsync1()
>>> let c;
>>> x2 = await||actionAsync2(x1)
>>>
>>> ...does the `let c` automatically break the parallel grouping since it's a 
>>> non-parallel operation (thereby making x1 defined)?
>>>
>>> It seems to me like you are doing block logic without blocks, which I think 
>>> increases the chances of bugs. Also you're not leveraging the existing 
>>> parallel execution pattern for async functions (which is just to omit the 
>>> `await`), so it would seem you would be increasing learning overhead. And, 
>>> you're not really allowing for submitting more sophisticated mixtures of 
>>> serial async, parallel async and synchronous code for "parallel completion" 
>>> guarantee, by requiring that parallel calls be "grouped" together in terms 
>>> of lines of code, almost allowing for nothing beyond the current 
>>> "Promise.all" pattern, logically. I don't think this is satisfying the 
>>> original motivation.
>>>
>>> For a `awail.all { ... }` block, maybe allowing a "return"/"yield" value 
>>> could neaten up the block scope separation, but maybe that could be left to 
>>> the "do" expression if that were adopted. But I don't think it's a big 
>>> sacrifice if neither exist.
>>>
>>>
>>> On Tue, 26 Nov 2019 at 14:14, manuelbarzi  wrote:


> OK I'm even more confused now. x1 is surely not a resolved value until 
> all the next "non parallel await" so is it "undefined" until then?


 as a `const` x1 does not exist until those parallel awaits `await||` (for 
 p1 and p3) are resolved (same for x3). then p2 is resolved after that.

 what it tries to bring is a simplification of syntax.

> 

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

2019-11-21 Thread Jacob Bloom
>>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.

I agree that parallelism is different and should be handled with care,
but I don't think it follows that the best way to reason about
parallelism is the way that `Promise.all` encourages. Making something
more complicated doesn't necessarily mean you'll do a better job of
reasoning about it.

If you think the proposed syntax encourages poorly-reasoned-about
code, I'm open to iterating on it to find a syntax that works with the
developer to handle parallelism in a safe way, and also doesn't
require them to write too much boilerplate code.

On Thu, Nov 21, 2019 at 3:16 PM Naveen Chawla  wrote:
>
> Yes of course, I was responding to your proposal and the subsequent email 
> about it being incompatible with existing JavaScript because "await" on its 
> own accepts non-promises, so wouldn't return an array of results from an 
> array of promises, hence why I proposed await.all etc.
>
> On Thu, 21 Nov 2019 at 18:29, manuelbarzi  wrote:
>>>
>>> I have a solution for that:
>>>
>>> const promises = [...]
>>> await.all promises //returns an array of results
>>> await.race promises //returns a single result
>>
>>
>> well, my proposal is exactly that, but doing `await.all` by default with 
>> just `await`.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


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

2019-11-21 Thread Jacob Bloom
>```javascript
>const promises = [...]
>await.all promises //returns an array of results
>await.race promises //returns a single result
>```

One of the goals of this proposal is to simplify the process of
collecting the promises in an array and then having to get them out of
another array.

>Why not just use a combination of `async`/`await` and `.then`?

That's an okay solution, though we still end up having to maintain
"parallel lists" of promises and values, which I'm hoping to avoid.
But you can sidestep them with something like this, which isn't too
bad:

```javascript
async function initialize() {
let foo, bar, baz;
await Promise.all([
request('foo.json').then(t => foo = t.data),
request('bar.json').then(t => bar = t.data),
request('baz.json').then(t => baz = t.data),
]);
render(foo, bar, baz);
}
```

On Thu, Nov 21, 2019 at 3:29 AM Naveen Chawla  wrote:
>
> I have a solution for that:
>
> const promises = [...]
> await.all promises //returns an array of results
> await.race promises //returns a single result
>
> etc.
>
> On Thu, 21 Nov 2019 at 09:51, manuelbarzi  wrote:
>>
>> AFAIK `await` can only accept an `expression` as a `Promise`, not other 
>> thing: 
>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
>>
>> On Thu, Nov 21, 2019 at 10:46 AM Jacob Bloom  
>> wrote:
>>>
>>> >why not just `await` as already is, but supporting an
>>> >iterable / array of promises, as `Promise.all` already does
>>>
>>> `await` can already accept a non-promise, so I believe that'd be
>>> breaking syntax if `Array.prototype.then` is set. It also requires
>>> collecting the promises in an array, which is what the proposed syntax
>>> is trying to avoid.
>>>
>>> On Thu, Nov 21, 2019 at 2:41 AM Jacob Bloom  
>>> wrote:
>>> >
>>> > >Just FYI, I previously suggested a couple things substantially more
>>> > >flexible than this
>>> >
>>> > Ah, thank you for bringing those proposals to my attention. I looked
>>> > through the archives for relevant discussions but I must've missed
>>> > them.
>>> >
>>> > It seems like we converged on a similar syntax for what you called
>>> > "merging," and the idea that there ought to be a separate syntax for
>>> > iteration. I don't know whether that means that this is the right
>>> > solution or just the most obvious one, but either way it's encouraging
>>> > to know that other people have the same difficulties with the current
>>> > syntax and are thinking about the problem.
>>> >
>>> > >from my experience, committee members are in general
>>> > >very hesitant to add syntax for anything that doesn't pay for
>>> > >itself well
>>> >
>>> > Yeah, I figured the bar would be high for new syntax. I've run into
>>> > the awkwardness of dealing with distinct parallel tasks several times,
>>> > and a few of the people I discussed it with were in the same boat, so
>>> > I wrote up this proposal thinking it might have a wide appeal. The
>>> > proposed syntax desugars via a relatively simple transformation but
>>> > encourages developers to reason about the problem in a completely
>>> > different way that I'd argue is more intuitive. Whether the committee
>>> > agrees and thinks it justifies a new syntax remains to be seen, but
>>> > either way I'm excited to see where this discussion goes (whether it
>>> > leads to the proposed syntax, to some other syntax, or to somewhere
>>> > else entirely).
>>> >
>>> > As a side note: thank you to everyone for the thoughtful questions and
>>> > responses, I had no idea what to expect from this thread and it's gone
>>> > better than I could've hoped for. Thank you for not immediately
>>> > shooting down a proposal that looks similar to other proposals before
>>> > it.
>>> >
>>> > On Wed, Nov 20, 2019 at 7:36 PM Isiah Meadows  
>>> > wrote:
>>> > >
>>> > > 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 ar

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

2019-11-21 Thread Jacob Bloom
>why not just `await` as already is, but supporting an
>iterable / array of promises, as `Promise.all` already does

`await` can already accept a non-promise, so I believe that'd be
breaking syntax if `Array.prototype.then` is set. It also requires
collecting the promises in an array, which is what the proposed syntax
is trying to avoid.

On Thu, Nov 21, 2019 at 2:41 AM Jacob Bloom  wrote:
>
> >Just FYI, I previously suggested a couple things substantially more
> >flexible than this
>
> Ah, thank you for bringing those proposals to my attention. I looked
> through the archives for relevant discussions but I must've missed
> them.
>
> It seems like we converged on a similar syntax for what you called
> "merging," and the idea that there ought to be a separate syntax for
> iteration. I don't know whether that means that this is the right
> solution or just the most obvious one, but either way it's encouraging
> to know that other people have the same difficulties with the current
> syntax and are thinking about the problem.
>
> >from my experience, committee members are in general
> >very hesitant to add syntax for anything that doesn't pay for
> >itself well
>
> Yeah, I figured the bar would be high for new syntax. I've run into
> the awkwardness of dealing with distinct parallel tasks several times,
> and a few of the people I discussed it with were in the same boat, so
> I wrote up this proposal thinking it might have a wide appeal. The
> proposed syntax desugars via a relatively simple transformation but
> encourages developers to reason about the problem in a completely
> different way that I'd argue is more intuitive. Whether the committee
> agrees and thinks it justifies a new syntax remains to be seen, but
> either way I'm excited to see where this discussion goes (whether it
> leads to the proposed syntax, to some other syntax, or to somewhere
> else entirely).
>
> As a side note: thank you to everyone for the thoughtful questions and
> responses, I had no idea what to expect from this thread and it's gone
> better than I could've hoped for. Thank you for not immediately
> shooting down a proposal that looks similar to other proposals before
> it.
>
> On Wed, Nov 20, 2019 at 7:36 PM Isiah Meadows  
> wrote:
> >
> > 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.

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

2019-11-21 Thread Jacob Bloom
>Just FYI, I previously suggested a couple things substantially more
>flexible than this

Ah, thank you for bringing those proposals to my attention. I looked
through the archives for relevant discussions but I must've missed
them.

It seems like we converged on a similar syntax for what you called
"merging," and the idea that there ought to be a separate syntax for
iteration. I don't know whether that means that this is the right
solution or just the most obvious one, but either way it's encouraging
to know that other people have the same difficulties with the current
syntax and are thinking about the problem.

>from my experience, committee members are in general
>very hesitant to add syntax for anything that doesn't pay for
>itself well

Yeah, I figured the bar would be high for new syntax. I've run into
the awkwardness of dealing with distinct parallel tasks several times,
and a few of the people I discussed it with were in the same boat, so
I wrote up this proposal thinking it might have a wide appeal. The
proposed syntax desugars via a relatively simple transformation but
encourages developers to reason about the problem in a completely
different way that I'd argue is more intuitive. Whether the committee
agrees and thinks it justifies a new syntax remains to be seen, but
either way I'm excited to see where this discussion goes (whether it
leads to the proposed syntax, to some other syntax, or to somewhere
else entirely).

As a side note: thank you to everyone for the thoughtful questions and
responses, I had no idea what to expect from this thread and it's gone
better than I could've hoped for. Thank you for not immediately
shooting down a proposal that looks similar to other proposals before
it.

On Wed, Nov 20, 2019 at 7:36 PM Isiah Meadows  wrote:
>
> 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!
> &g

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

2019-11-20 Thread Jacob Bloom
...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


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

2019-11-20 Thread Jacob Bloom
>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


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

2019-11-19 Thread Jacob Bloom
Regarding parallel for-loops: I'd consider that a separate problem.
You'd want parallel for-loops for things like requests to the same
API, where each promise is handled the same way. `await.all` is more
for handling disparate tasks in parallel without having to resort to
thinking in terms of arrays and iteration.

On Tue, Nov 19, 2019 at 10:27 PM Guy Bedford  wrote:
>
> Typically I find I want to loop over an iterator of items and apply a 
> function body of work on them in parallel.
>
> So it would be nice to support full blocks of statements that can do this 
> work in parallel, instead of relying on just expressions or functions to 
> achieve this.
>
> Extending for loops to have a parallel form is another option (I seem to 
> recall something similar brought up before here):
>
> ```
> for await.all (const entry of entries) {
>   await doWork(entry);
> }
> ```
>
> Whether async iteration should be supported or treated as sync or parallel is 
> another question though, and possibly a confusion of the form.
>
> On Tue, 19 Nov 2019 at 23:20, Jordan Harband  wrote:
>>
>> If we have `await.all`, what about `await.race`, `await.allSettled`, 
>> `await.any`?
>>
>> On Tue, Nov 19, 2019 at 7:45 PM Jacob Bloom  wrote:
>>>
>>> To simplify the problem of working with promises in parallel, I
>>> propose this new syntax:
>>>
>>> ```javascript
>>> async function initialize() {
>>>   let foo, bar, baz;
>>>   await.all {
>>> foo = (await request('foo.json')).data;
>>> bar = (await request('bar.json')).data;
>>> baz = (await request('baz.json')).data;
>>>   }
>>>   render(foo, bar, baz);
>>> }
>>> ```
>>>
>>> Each child statement of the curly braces is evaluated in parallel and
>>> execution resumes when they've all resolved.
>>>
>>> **The Problem:** with current syntax, the above function would
>>> probably look something like this:
>>>
>>> ```javascript
>>> async function initialize() {
>>>   const [
>>> { data: foo }, // renaming response.data => foo
>>> { data: bar },
>>> { data: baz },
>>>   ] = await Promise.all([
>>> request('foo.json'),
>>> request('bar.json'),
>>> request('baz.json'),
>>>   ]);
>>>   render(foo, bar, baz);
>>> }
>>> ```
>>>
>>> For this kind of use case, `Promise.all` leads to "parallel lists" of
>>> promises and their return values, which must be kept in sync. Using
>>> those values either requires (sometimes deep) destructuring or
>>> temporary variables.
>>>
>>> This structure is also just fundamentally different from working
>>> serially in async/await and it forces you to reason about the problem
>>> in a specific way. This doesn't appear to be a conscious decision to
>>> force good code practices, it's just a limitation that falls naturally
>>> out of the current syntax. Thus, we have an opportunity to shift some
>>> of the burden back to the language with this new syntax.
>>>
>>> Here's the full proposal:
>>> https://github.com/mrjacobbloom/proposal-await-all -- let me know what
>>> you think!
>>> ___
>>> es-discuss mailing list
>>> es-discuss@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


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

2019-11-19 Thread Jacob Bloom
Regarding the other `Promise` methods, this syntax could certainly
extend to all of them (that's part of the reason I chose this syntax,
to leave that option open).

`await.any` and `await.race` would work analogously to `await.all`,
but since we're no longer dealing with return values there's no good
way to get the value that won the race. This is fine as long as you're
not dependent on that value and only care about executing some code as
soon as the race is won. The best way I can think of to get the
winning value is something like this:

```javascript
async function myFunc() {
  let value1, value2;
  await.any {
value1 = await foo;
value2 = await bar;
  }
  const firstResult = value1 || value2; // could also use ??
}
```

...which isn't any easier than using `Promise.any`.

`await.allSettled` would, in many cases, be the same as `Promise.all`
except it would also swallow errors. I'd have to think more about its
use cases but it could be implemented the same way.

On Tue, Nov 19, 2019 at 9:20 PM Jordan Harband  wrote:
>
> If we have `await.all`, what about `await.race`, `await.allSettled`, 
> `await.any`?
>
> On Tue, Nov 19, 2019 at 7:45 PM Jacob Bloom  wrote:
>>
>> To simplify the problem of working with promises in parallel, I
>> propose this new syntax:
>>
>> ```javascript
>> async function initialize() {
>>   let foo, bar, baz;
>>   await.all {
>> foo = (await request('foo.json')).data;
>> bar = (await request('bar.json')).data;
>> baz = (await request('baz.json')).data;
>>   }
>>   render(foo, bar, baz);
>> }
>> ```
>>
>> Each child statement of the curly braces is evaluated in parallel and
>> execution resumes when they've all resolved.
>>
>> **The Problem:** with current syntax, the above function would
>> probably look something like this:
>>
>> ```javascript
>> async function initialize() {
>>   const [
>> { data: foo }, // renaming response.data => foo
>> { data: bar },
>> { data: baz },
>>   ] = await Promise.all([
>> request('foo.json'),
>> request('bar.json'),
>> request('baz.json'),
>>   ]);
>>   render(foo, bar, baz);
>> }
>> ```
>>
>> For this kind of use case, `Promise.all` leads to "parallel lists" of
>> promises and their return values, which must be kept in sync. Using
>> those values either requires (sometimes deep) destructuring or
>> temporary variables.
>>
>> This structure is also just fundamentally different from working
>> serially in async/await and it forces you to reason about the problem
>> in a specific way. This doesn't appear to be a conscious decision to
>> force good code practices, it's just a limitation that falls naturally
>> out of the current syntax. Thus, we have an opportunity to shift some
>> of the burden back to the language with this new syntax.
>>
>> Here's the full proposal:
>> https://github.com/mrjacobbloom/proposal-await-all -- let me know what
>> you think!
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


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

2019-11-19 Thread Jacob Bloom
To simplify the problem of working with promises in parallel, I
propose this new syntax:

```javascript
async function initialize() {
  let foo, bar, baz;
  await.all {
foo = (await request('foo.json')).data;
bar = (await request('bar.json')).data;
baz = (await request('baz.json')).data;
  }
  render(foo, bar, baz);
}
```

Each child statement of the curly braces is evaluated in parallel and
execution resumes when they've all resolved.

**The Problem:** with current syntax, the above function would
probably look something like this:

```javascript
async function initialize() {
  const [
{ data: foo }, // renaming response.data => foo
{ data: bar },
{ data: baz },
  ] = await Promise.all([
request('foo.json'),
request('bar.json'),
request('baz.json'),
  ]);
  render(foo, bar, baz);
}
```

For this kind of use case, `Promise.all` leads to "parallel lists" of
promises and their return values, which must be kept in sync. Using
those values either requires (sometimes deep) destructuring or
temporary variables.

This structure is also just fundamentally different from working
serially in async/await and it forces you to reason about the problem
in a specific way. This doesn't appear to be a conscious decision to
force good code practices, it's just a limitation that falls naturally
out of the current syntax. Thus, we have an opportunity to shift some
of the burden back to the language with this new syntax.

Here's the full proposal:
https://github.com/mrjacobbloom/proposal-await-all -- let me know what
you think!
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


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

2019-10-11 Thread Jacob Bloom
What about special handling for Maps? Maybe something like

```
const requests = new Map();
requests.set('reqA', fetch('...'));
requests.set('reqB', fetch('...'));
const responses = await Promise.all(requests);
console.log(
  responses.get('reqA'),
  responses.get('reqB'),
);
```

...which would continue to fail for most objects and would encourage
using Map over POJOs for map-like data structures. (Since Maps are
iterable, this may break some existing code but I doubt it)

On Fri, Oct 11, 2019 at 11:28 AM Bradford Smith
 wrote:
>
> Promise.all(Object.values(myObjWithPromiseValues)).then(...)
>
> On Fri, Oct 11, 2019 at 10:22 AM Jordan Harband  wrote:
>>
>> The current API accepts an *iterable*, which means any object that has 
>> `Symbol.iterator`, such as an array or a Set.
>>
>> Throwing when it receives a non-iterable object is an important tool to 
>> catch bugs. If Promise.all was made to accept a non-iterable object as well, 
>> I suspect many bugs would go uncaught.
>>
>> On Fri, Oct 11, 2019 at 10:15 AM Adam Eisenreich  wrote:
>>>
>>> Back when async/await was introduced I struggeled quite a bit with promises 
>>> arrays that have conditional promises. RxJS is moving from array only 
>>> support in theirs operators to objects too, there seems to be an actual 
>>> trend going on. Is there any reason against?
>>> ___
>>> es-discuss mailing list
>>> es-discuss@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>
> ___
> es-discuss mailing list
> es-discuss@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: native XML object support.

2019-05-19 Thread Jacob Bloom
> And things such as E4X already exist.

Building on that, JSX is just a code transformation that can be used
without React. You can swap React out for another compatible library
with a pragma: 
https://babeljs.io/docs/en/next/babel-plugin-transform-react-jsx#pragma
-- JSX + a React-like library that creates vanilla DOM elements could
be used to achieve a lot of the requested functionality


On Sat, May 18, 2019 at 4:01 AM ViliusCreator
 wrote:
>
> XML in JS without React could totally bring usage in Node js, not only JS. 
> For example, you could pass XML object as parameter to website from server 
> and server would change it to right way, so XML object would be turned to 
> HTML element.
> However, in non web-development environment, it would have no usage. Since 
> sometimes Node js is used for general-purpose and not web-development, XML 
> would be practically useless and JSON would be used. And things such as E4X 
> already exist.
> The benefit of XML is that you can do `d `(which is 
> equivalent to
>
> ```json
> {
> ‘//name’: ‘a’,
> ‘//inner’: [‘d ’, {...}],
> b: ‘c’
> }
> ```) and it’s more readable than JSON version of it.`
>
>
> Virus-free. 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