it would be nice to have async-blocks like ``async {some_statements}`` and ``async (some_expression)``
That would create a refactoring hazard if i had the block: { a(); b(); return c(); }
and stuck the async
keyword in front of it - suddenly the
function wouldn't have an early completion in the block, it'd create and
throw away a Promise.
That would create a refactoring hazard if i had the block: `{ a(); b(); return c(); }` and stuck the `async` keyword in front of it - suddenly the function wouldn't have an early completion in the block, it'd create and throw away a Promise. On Tue, Jan 3, 2017 at 12:52 AM, Igor Baklan <io.baklan at gmail.com> wrote: > I looks like it would be nice to have ``async``-block which might be alias > to ``async``-lambda immediate invocation, so that: > > ```js > var promise = async { /*some statements with await*/ }; > ``` > <==> > > ```js > var promise = (async () => { /*some statements with await*/ }) (); > ``` > > and > > ```js > var promise = async ( /*some statements with await*/ ); > ``` > <==> > > ```js > var promise = (async () => ( /*some expression with await*/ )) (); > ``` > > Then it can gave some convenience in writing some semi-async function, > like for example parallel async batch processing, which might look like: > > ```js > const backupBatch = (batch) => { > var tasks = []; > for (let item of batch) { > tasks.push( > async { > const content = await readContent(item); > await writeContent(item + ".bak", content); > } > ) > } > return Promise.all(tasks) > } > ``` > > or like > > ```js > const backupBatch = (batch) => { > var tasks = []; > for (let item of batch) { > tasks.push( > async ( > await writeContent(item + ".bak", await readContent(item)); > ) > ) > } > return Promise.all(tasks) > } > ``` > > of course this simplistic case can be rewritten without ``async``-block > like: > > ```js > const backupBatch = (batch) => { > return Promise.all( > batch.map( > async (item) => ( > await writeContent(item + ".bak", await readContent(item)); > ) > ) > ); > } > ``` > However I believe this not reduce usefulness of initial ``async``-block > construction. > > Also it should be mentioned that this idea "is't new", something very > similar I saw in [[async-do]](/topic/support-syntax#content-5) comment. > > And finally, if this construct will be introduced, it will provide some > nice symmetry - of whether you put async keyword in function header > definition, or at the very beginning of its body, like: > > ```js > const asyncFunc = async (/*args*/) => {/*function body with await-s*/}; > ``` > <==> > ```js > const asyncFunc = (/*args*/) => { return async {/*function body with > await-s*/} }; > ``` > <==> > ```js > const asyncFunc = (/*args*/) => ( async {/*function body with await-s*/} ); > ``` > > And > ```js > const asyncFunc = async (args) => (some_async_expression); > ``` > <==> > ```js > const asyncFunc = (args) => async (some_async_expression); > ``` > > By the way parentheses here is essential, since ``async x => x`` != > ``async (x => x)``, cause first evaluates into async-function, while the > second should be evaluated into completed promise which value is ``sync`` > function ``(x => x)``. > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170103/66d7c366/attachment.html>
That would create a refactoring hazard if i had the block:
{ a(); b(); return c(); }
and stuck theasync
keyword in front of it [...]
That's a pretty specific keyword to slip in before a given code block - is that really much of a real-world risk?
Also worth noting that the grammar here would have to preclude newlines
between async
and the opening bracket. This is already perfectly valid
JavaScript:
var async = 'gotcha'
var promise = async
{ console.log('hi!') }
That being said, this probably doesn't really make sense on it's own, but could definitely build on top of do/let blocks or lamdas (<-- not really current with the state of affairs on any of that).
> > That would create a refactoring hazard if i had the block: `{ a(); b(); > return c(); }` and stuck the `async` keyword in front of it [...] That's a pretty specific keyword to slip in before a given code block - is that really much of a real-world risk? Also worth noting that the grammar here would have to preclude newlines between `async` and the opening bracket. This is already perfectly valid JavaScript: var async = 'gotcha' var promise = async { console.log('hi!') } That being said, this probably doesn't really make sense on it's own, but could definitely build on top of do/let blocks or lamdas (<-- not really current with the state of affairs on any of that). On Tue, Jan 3, 2017 at 10:16 AM, Jordan Harband <ljharb at gmail.com> wrote: > That would create a refactoring hazard if i had the block: `{ a(); b(); > return c(); }` and stuck the `async` keyword in front of it - suddenly the > function wouldn't have an early completion in the block, it'd create and > throw away a Promise. > > On Tue, Jan 3, 2017 at 12:52 AM, Igor Baklan <io.baklan at gmail.com> wrote: > >> I looks like it would be nice to have ``async``-block which might be >> alias to ``async``-lambda immediate invocation, so that: >> >> ```js >> var promise = async { /*some statements with await*/ }; >> ``` >> <==> >> >> ```js >> var promise = (async () => { /*some statements with await*/ }) (); >> ``` >> >> and >> >> ```js >> var promise = async ( /*some statements with await*/ ); >> ``` >> <==> >> >> ```js >> var promise = (async () => ( /*some expression with await*/ )) (); >> ``` >> >> Then it can gave some convenience in writing some semi-async function, >> like for example parallel async batch processing, which might look like: >> >> ```js >> const backupBatch = (batch) => { >> var tasks = []; >> for (let item of batch) { >> tasks.push( >> async { >> const content = await readContent(item); >> await writeContent(item + ".bak", content); >> } >> ) >> } >> return Promise.all(tasks) >> } >> ``` >> >> or like >> >> ```js >> const backupBatch = (batch) => { >> var tasks = []; >> for (let item of batch) { >> tasks.push( >> async ( >> await writeContent(item + ".bak", await readContent(item)); >> ) >> ) >> } >> return Promise.all(tasks) >> } >> ``` >> >> of course this simplistic case can be rewritten without ``async``-block >> like: >> >> ```js >> const backupBatch = (batch) => { >> return Promise.all( >> batch.map( >> async (item) => ( >> await writeContent(item + ".bak", await readContent(item)); >> ) >> ) >> ); >> } >> ``` >> However I believe this not reduce usefulness of initial ``async``-block >> construction. >> >> Also it should be mentioned that this idea "is't new", something very >> similar I saw in [[async-do]](/topic/support-syntax#content-5) comment. >> >> And finally, if this construct will be introduced, it will provide some >> nice symmetry - of whether you put async keyword in function header >> definition, or at the very beginning of its body, like: >> >> ```js >> const asyncFunc = async (/*args*/) => {/*function body with await-s*/}; >> ``` >> <==> >> ```js >> const asyncFunc = (/*args*/) => { return async {/*function body with >> await-s*/} }; >> ``` >> <==> >> ```js >> const asyncFunc = (/*args*/) => ( async {/*function body with await-s*/} >> ); >> ``` >> >> And >> ```js >> const asyncFunc = async (args) => (some_async_expression); >> ``` >> <==> >> ```js >> const asyncFunc = (args) => async (some_async_expression); >> ``` >> >> By the way parentheses here is essential, since ``async x => x`` != >> ``async (x => x)``, cause first evaluates into async-function, while the >> second should be evaluated into completed promise which value is ``sync`` >> function ``(x => x)``. >> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -- Jeremy Martin 661.312.3853 http://devsmash.com @jmar777 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170103/f6214f85/attachment-0001.html>
I’m all for the async
block. In Scala, there actually are no async
functions; only async
blocks. (Technically, this isn’t in the language; it’s a macro from a library called scala-async scala/async.) This works out a bit more nicely because it’s expression-oriented to begin with.
But the nice thing about async
blocks is that you can then use promise combinators within a function that might compose a couple different async
operations. This might be a little less necessary in Javascript though, since it is rather flexible on the typing of promise-related functions; it will promote values to promises where necessary and flatten nested promises. Often in Scala, I’ll wrap a normal value in an async
to make it a Future
(Scala’s Promise
).
I’m all for the `async` block. In Scala, there actually are no `async` functions; only `async` blocks. (Technically, this isn’t in the language; it’s a macro from a library called scala-async <https://github.com/scala/async>.) This works out a bit more nicely because it’s expression-oriented to begin with. But the nice thing about `async` blocks is that you can then use promise combinators within a function that might compose a couple different `async` operations. This might be a little less necessary in Javascript though, since it is rather flexible on the typing of promise-related functions; it will promote values to promises where necessary and flatten nested promises. Often in Scala, I’ll wrap a normal value in an `async` to make it a `Future` (Scala’s `Promise`). > On Jan 3, 2017, at 10:48, Jeremy Martin <jmar777 at gmail.com> wrote: > > That would create a refactoring hazard if i had the block: `{ a(); b(); return c(); }` and stuck the `async` keyword in front of it [...] > > That's a pretty specific keyword to slip in before a given code block - is that really much of a real-world risk? > > Also worth noting that the grammar here would have to preclude newlines between `async` and the opening bracket. This is already perfectly valid JavaScript: > > var async = 'gotcha' > > var promise = async > > { console.log('hi!') } > > That being said, this probably doesn't really make sense on it's own, but could definitely build on top of do/let blocks or lamdas (<-- not really current with the state of affairs on any of that). > > > On Tue, Jan 3, 2017 at 10:16 AM, Jordan Harband <ljharb at gmail.com <mailto:ljharb at gmail.com>> wrote: > That would create a refactoring hazard if i had the block: `{ a(); b(); return c(); }` and stuck the `async` keyword in front of it - suddenly the function wouldn't have an early completion in the block, it'd create and throw away a Promise. > > On Tue, Jan 3, 2017 at 12:52 AM, Igor Baklan <io.baklan at gmail.com <mailto:io.baklan at gmail.com>> wrote: > I looks like it would be nice to have ``async``-block which might be alias to ``async``-lambda immediate invocation, so that: > > ```js > var promise = async { /*some statements with await*/ }; > ``` > <==> > > ```js > var promise = (async () => { /*some statements with await*/ }) (); > ``` > > and > > ```js > var promise = async ( /*some statements with await*/ ); > ``` > <==> > > ```js > var promise = (async () => ( /*some expression with await*/ )) (); > ``` > > Then it can gave some convenience in writing some semi-async function, like for example parallel async batch processing, which might look like: > > ```js > const backupBatch = (batch) => { > var tasks = []; > for (let item of batch) { > tasks.push( > async { > const content = await readContent(item); > await writeContent(item + ".bak", content); > } > ) > } > return Promise.all(tasks) > } > ``` > > or like > > ```js > const backupBatch = (batch) => { > var tasks = []; > for (let item of batch) { > tasks.push( > async ( > await writeContent(item + ".bak", await readContent(item)); > ) > ) > } > return Promise.all(tasks) > } > ``` > > of course this simplistic case can be rewritten without ``async``-block like: > > ```js > const backupBatch = (batch) => { > return Promise.all( > batch.map( > async (item) => ( > await writeContent(item + ".bak", await readContent(item)); > ) > ) > ); > } > ``` > However I believe this not reduce usefulness of initial ``async``-block construction. > > Also it should be mentioned that this idea "is't new", something very similar I saw in [[async-do]](/topic/support-syntax#content-5) comment. > > And finally, if this construct will be introduced, it will provide some nice symmetry - of whether you put async keyword in function header definition, or at the very beginning of its body, like: > > ```js > const asyncFunc = async (/*args*/) => {/*function body with await-s*/}; > ``` > <==> > ```js > const asyncFunc = (/*args*/) => { return async {/*function body with await-s*/} }; > ``` > <==> > ```js > const asyncFunc = (/*args*/) => ( async {/*function body with await-s*/} ); > ``` > > And > ```js > const asyncFunc = async (args) => (some_async_expression); > ``` > <==> > ```js > const asyncFunc = (args) => async (some_async_expression); > ``` > > By the way parentheses here is essential, since ``async x => x`` != ``async (x => x)``, cause first evaluates into async-function, while the second should be evaluated into completed promise which value is ``sync`` function ``(x => x)``. > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > > > > > -- > Jeremy Martin > 661.312.3853 > http://devsmash.com <http://devsmash.com/> > @jmar777 > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170103/e85141d6/attachment.html>
This proposal sounds a bit like do-expressions but with async support?
babeljs.io/docs/plugins/transform-do-expressions If that's the
case, why not async do { /*....*/ }
?
This proposal sounds a bit like do-expressions but with async support? https://babeljs.io/docs/plugins/transform-do-expressions/ If that's the case, why not `async do { /*....*/ }`? On Tue, Jan 3, 2017 at 10:55 AM, Alan Johnson <alan at breakrs.com> wrote: > I’m all for the `async` block. In Scala, there actually are no `async` > functions; only `async` blocks. (Technically, this isn’t in the language; > it’s a macro from a library called scala-async > <https://github.com/scala/async>.) This works out a bit more nicely > because it’s expression-oriented to begin with. > > But the nice thing about `async` blocks is that you can then use promise > combinators within a function that might compose a couple different `async` > operations. This might be a little less necessary in Javascript though, > since it is rather flexible on the typing of promise-related functions; it > will promote values to promises where necessary and flatten nested > promises. Often in Scala, I’ll wrap a normal value in an `async` to make it > a `Future` (Scala’s `Promise`). > > On Jan 3, 2017, at 10:48, Jeremy Martin <jmar777 at gmail.com> wrote: > > That would create a refactoring hazard if i had the block: `{ a(); b(); >> return c(); }` and stuck the `async` keyword in front of it [...] > > > That's a pretty specific keyword to slip in before a given code block - is > that really much of a real-world risk? > > Also worth noting that the grammar here would have to preclude newlines > between `async` and the opening bracket. This is already perfectly valid > JavaScript: > > var async = 'gotcha' > > var promise = async > > { console.log('hi!') } > > That being said, this probably doesn't really make sense on it's own, but > could definitely build on top of do/let blocks or lamdas (<-- not really > current with the state of affairs on any of that). > > > On Tue, Jan 3, 2017 at 10:16 AM, Jordan Harband <ljharb at gmail.com> wrote: > >> That would create a refactoring hazard if i had the block: `{ a(); b(); >> return c(); }` and stuck the `async` keyword in front of it - suddenly the >> function wouldn't have an early completion in the block, it'd create and >> throw away a Promise. >> >> On Tue, Jan 3, 2017 at 12:52 AM, Igor Baklan <io.baklan at gmail.com> wrote: >> >>> I looks like it would be nice to have ``async``-block which might be >>> alias to ``async``-lambda immediate invocation, so that: >>> >>> ```js >>> var promise = async { /*some statements with await*/ }; >>> ``` >>> <==> >>> >>> ```js >>> var promise = (async () => { /*some statements with await*/ }) (); >>> ``` >>> >>> and >>> >>> ```js >>> var promise = async ( /*some statements with await*/ ); >>> ``` >>> <==> >>> >>> ```js >>> var promise = (async () => ( /*some expression with await*/ )) (); >>> ``` >>> >>> Then it can gave some convenience in writing some semi-async function, >>> like for example parallel async batch processing, which might look like: >>> >>> ```js >>> const backupBatch = (batch) => { >>> var tasks = []; >>> for (let item of batch) { >>> tasks.push( >>> async { >>> const content = await readContent(item); >>> await writeContent(item + ".bak", content); >>> } >>> ) >>> } >>> return Promise.all(tasks) >>> } >>> ``` >>> >>> or like >>> >>> ```js >>> const backupBatch = (batch) => { >>> var tasks = []; >>> for (let item of batch) { >>> tasks.push( >>> async ( >>> await writeContent(item + ".bak", await readContent(item)); >>> ) >>> ) >>> } >>> return Promise.all(tasks) >>> } >>> ``` >>> >>> of course this simplistic case can be rewritten without ``async``-block >>> like: >>> >>> ```js >>> const backupBatch = (batch) => { >>> return Promise.all( >>> batch.map( >>> async (item) => ( >>> await writeContent(item + ".bak", await readContent(item)); >>> ) >>> ) >>> ); >>> } >>> ``` >>> However I believe this not reduce usefulness of initial ``async``-block >>> construction. >>> >>> Also it should be mentioned that this idea "is't new", something very >>> similar I saw in [[async-do]](/topic/support-syntax#content-5) comment. >>> >>> And finally, if this construct will be introduced, it will provide some >>> nice symmetry - of whether you put async keyword in function header >>> definition, or at the very beginning of its body, like: >>> >>> ```js >>> const asyncFunc = async (/*args*/) => {/*function body with await-s*/}; >>> ``` >>> <==> >>> ```js >>> const asyncFunc = (/*args*/) => { return async {/*function body with >>> await-s*/} }; >>> ``` >>> <==> >>> ```js >>> const asyncFunc = (/*args*/) => ( async {/*function body with await-s*/} >>> ); >>> ``` >>> >>> And >>> ```js >>> const asyncFunc = async (args) => (some_async_expression); >>> ``` >>> <==> >>> ```js >>> const asyncFunc = (args) => async (some_async_expression); >>> ``` >>> >>> By the way parentheses here is essential, since ``async x => x`` != >>> ``async (x => x)``, cause first evaluates into async-function, while the >>> second should be evaluated into completed promise which value is ``sync`` >>> function ``(x => x)``. >>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > > -- > Jeremy Martin > 661.312.3853 > http://devsmash.com > @jmar777 > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -- - Oli Oli Lalonde http://www.syskall.com <-- connect with me! -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170103/4e34cada/attachment-0001.html>
As I've mentioned in initial post
this idea "isn't new", something very similar I saw in [async-do] comment
So answer yes - it actually the same idea. However as for me do
part is
quite optional and can be omitted without any lost (in this construct).
Meaning that if we will introduce different variations of so called "do
{...}" statement in future, they not mandatory should share do
keyword
(they rather should only share the same "spirit").
As I've mentioned in initial post > this idea "isn't new", something very similar I saw in [[async-do]](/topic/support-syntax#content-5) comment So answer yes - it quite the same idea. However as for me ``do`` part is quite optional and can be omitted without any lost (in this construct). Meaning that if we will introduce different variations of so called "do {...}" statement in future, they not mandatory should share ``do`` keyword (they rather should only share the same "spirit"). -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170103/5533c247/attachment.html>
I looks like it would be nice to have
async
-block which might be alias toasync
-lambda immediate invocation, so that:var promise = async { /*some statements with await*/ };
<==>
var promise = (async () => { /*some statements with await*/ }) ();
and
var promise = async ( /*some statements with await*/ );
<==>
var promise = (async () => ( /*some expression with await*/ )) ();
Then it can gave some convenience in writing some semi-async function, like for example parallel async batch processing, which might look like:
const backupBatch = (batch) => { var tasks = []; for (let item of batch) { tasks.push( async { const content = await readContent(item); await writeContent(item + ".bak", content); } ) } return Promise.all(tasks) }
or like
const backupBatch = (batch) => { var tasks = []; for (let item of batch) { tasks.push( async ( await writeContent(item + ".bak", await readContent(item)); ) ) } return Promise.all(tasks) }
of course this simplistic case can be rewritten without
async
-block like:const backupBatch = (batch) => { return Promise.all( batch.map( async (item) => ( await writeContent(item + ".bak", await readContent(item)); ) ) ); }
However I believe this not reduce usefulness of initial
async
-block construction.Also it should be mentioned that this idea "isn't new", something very similar I saw in [async-do] comment.
And finally, if this construct will be introduced, it will provide some nice symmetry - of whether you put async keyword in function header definition, or at the very beginning of its body, like:
const asyncFunc = async (/*args*/) => {/*function body with await-s*/};
<==>
const asyncFunc = (/*args*/) => { return async {/*function body with await-s*/} };
<==>
const asyncFunc = (/*args*/) => ( async {/*function body with await-s*/} );
And
const asyncFunc = async (args) => (some_async_expression);
<==>
const asyncFunc = (args) => async (some_async_expression);
By the way parentheses hear (in
async(...)
) might be essencial, for example for following case:async x => x
!=async (x => x)
, cause first evaluates into async-function, while the second should be evaluated into completed promise which value issync
function(x => x)
.