Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ES7 async/await implementation with concise syntax #836

Closed
wants to merge 4 commits into from

Conversation

summivox
Copy link
Contributor

@summivox summivox commented Feb 1, 2016

ES7 async/await is a syntax sugar for promise+generator async control pattern. Although this feature is still a draft in even ES7, it has gained considerable traction, and is completely usable right now through a babel plugin.

This patch provides a concrete example on which we can discuss syntax extensions to LiveScript that compiles to ES7 async/await.

async function

  1. Append an additional > to all arrows: ->>, ~>>, -->>, ~~>>
    Rationale for the syntax: terseness
  2. Prepend keyword async to arglist of arrow functions: async (arglist) -> body
    Rationale for the syntax: agrees with strawman proposal on async "ES6 rocket" functions
    (redundant)
  3. Prepend keyword async to named function definitions: async function name(arglist)
    Rationale for the syntax: obvious

await expression

  1. await compiles to await (in the same way as how yield is compiled now)
  2. await all compiles to await* (in the same way as how yield from is compiled now)
    Rationale: await* is proposed to have the same semantics as Promise.all (see strawman)
    (no longer in standard)

Example

af1 = (x) ->> await x
af2 = async (a, b, c) ~> await @x
async function af3(x)
  a = await af1 x

compiles to

var af1, af2, this$ = this;
af1 = async function(x){
  return (await x);
};
af2 = async function(a, b, c){
  return (await this$.x);
};
async function af3(x){
  var a;
  return a = (await af1(x));
}

References

@summivox summivox force-pushed the async-await-concise branch from 226cb80 to 11d17fc Compare February 1, 2016 16:21
@summivox summivox changed the title ES7 async/await implentation with concise syntax ES7 async/await implementation with concise syntax Feb 7, 2016
@dead-claudia
Copy link
Contributor

How would that work with libraries using that identifier? I'm working on one that could implement this general functionality at the library level, possibly more optimally than engines could. (I'm using Bluebird-style shortcuts to do it, including keeping the stack minimized.)

@summivox
Copy link
Contributor Author

['ID', 'async'] is left alone unless it is followed by a PARAM( or FUNCTION

@summivox
Copy link
Contributor Author

@vendethiel decided in #752 that lsc should not transpile ES7/ES6

@summivox summivox force-pushed the async-await-concise branch from 11d17fc to ba94ce4 Compare June 9, 2016 01:29
@summivox summivox force-pushed the async-await-concise branch from ba94ce4 to 8854954 Compare June 17, 2016 17:56
@darky
Copy link
Contributor

darky commented Oct 25, 2016

async/await almost in v8 as stable feature. Any activity here?

@dead-claudia
Copy link
Contributor

@gkz? IIRC this barely missed the V8 train for Node 7, and it's been shipping in Edge for a while.

@summivox
Copy link
Contributor Author

My opinion:

  • I don't think the syntax and semantics of async/await in ES7 would change in any major way, now that it is being rolled out experimentally.
  • The proposed syntax for LSC does not conflict with existing code, and is intended for early adopters specifically targeting ES7 (and quite possibly including further transpiling toolchain)

Therefore I believe it is safe for this to land in LSC.

@dead-claudia
Copy link
Contributor

WRT the PR itself, I feel having both (arg) ->> (and friends) and async (arg) -> is rather redundant.

@dead-claudia
Copy link
Contributor

dead-claudia commented Oct 25, 2016

@summivox You mean ES8? It barely missed the ES7 train.

@summivox
Copy link
Contributor Author

@isiahmeadows It seems that people have stopped caring about the "version number" and started to rely on shipping schedule instead. I'm fine with this ;)

Regarding syntax: Historically coffee-ish languages have this dilemma of symbols vs English words. && vs and in LSC is a prime example --- different operator precedence (with and being more sane therefore the default). I don't see why both versions of arrows cannot co-exist. However, if only one is to stay, I would suggest ->> which stays in line with the "symbolic" feel of the arrows while retaining orthogonality, and async function for the "English" side.

@dead-claudia
Copy link
Contributor

There is a push to get rid of many of the duplicate operators like && vs
and in one of the issues here. I can't remember the number right off,
though.

On Tue, Oct 25, 2016, 17:00 Yin Zhong [email protected] wrote:

@isiahmeadows https://github.com/isiahmeadows It seems that people have
stopped caring about the "version number" and started to rely on shipping
schedule instead. I'm fine with this ;)

Regarding syntax: Historically coffee-ish languages have this dilemma of
symbols vs English words. && vs and in LSC is a prime example --- different
operator precedence (with and being more sane therefore the default). I
don't see why both versions of arrows cannot co-exist. However, if only one
is to stay, I would suggest ->> which stays in line with the "symbolic"
feel of the arrows while retaining orthogonality, and async function for
the "English" side.


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
#836 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AERrBIhK8Lb0Von9c7bB-0p91_TBKyrPks5q3m35gaJpZM4HQRZq
.

@summivox
Copy link
Contributor Author

I just tested this with node v7.3.0 . It feels awesome.

@isiahmeadows : I agree with you on removing async (args) -> body now. For anonymous functions, LSC allows only arrows while ES6 allows both function() and arrow. There is no good reason to keep an alternative syntax for async.

@dk00
Copy link
Contributor

dk00 commented Feb 2, 2017

await* have been removed from the proposal, should we remove it as well, or simply compile it to await promise.all ... ?

@gkovacs
Copy link
Contributor

gkovacs commented Mar 30, 2017

Thank you for this excellent patch. I have noticed a bug when using it against the master branch ( 47ad4eb )

getdict = (name) ->>
  data = await getCollection(name)
  return {[key, val] for {key, val} in data}

somehow gets compiled to (notice the superfluous yield*)

// Generated by LiveScript 1.5.0
(function(){
  var getdict, out$ = typeof exports != 'undefined' && exports || this;
  out$.getdict = getdict = async function(name){
    var data, key, val;
    data = (await getCollection(name));
    return (yield* (function*(){
      var i$, ref$, len$, ref1$, resultObj$ = {};
      for (i$ = 0, len$ = (ref$ = data).length; i$ < len$; ++i$) {
        ref1$ = ref$[i$], key = ref1$.key, val = ref1$.val;
        resultObj$[key] = val;
      }
      return resultObj$;
    }()));
  };
}).call(this);

@summivox
Copy link
Contributor Author

@gkovacs : this is a separate issue: #764 #938

@gkovacs
Copy link
Contributor

gkovacs commented Mar 30, 2017

Thank you for the fast response! Also here's another issue. The following code compiles:

foo = -> ''

a = foo(async ->
  ''
)

And so does this:

foo = -> ''

a = foo ->>
  ''

But the following does not:

foo = -> ''

a = foo async ->
  ''

So in the example above, ->> and async -> aren't quite identical.

@dead-claudia
Copy link
Contributor

dead-claudia commented Mar 30, 2017

Here's my proposed resolution: remove async -> altogether. It doesn't fit with every other anonymous function syntax.

I'm kind of 1% tied to this project now, since the parser bugs have pretty much killed this project for me, and no stable release yet has provided ES6 support. But that's a little more meta.

@summivox
Copy link
Contributor Author

I want to remove async -> syntax so this is a wontfix.
I just haven't been actively working on this project for a long time.

@summivox summivox force-pushed the async-await-concise branch from 8854954 to 4b9323f Compare March 30, 2017 10:06
see http://wiki.ecmascript.org/doku.php?id=strawman:async_functions

async function: `->>`, `~>>`, `-->>`, `~~>>`, `async (arglist) ->...`, `async function name (arglist)`
await: `await` => `await`; `await all` => `await*` (proposed to translate to `Promise.all`, not final)

backcall does NOT work, but this should be fine because they were invented to create the illusion of async function anyway
@summivox summivox force-pushed the async-await-concise branch from 4b9323f to ed71900 Compare March 30, 2017 10:07
@summivox
Copy link
Contributor Author

Hmm done.

@gkovacs
Copy link
Contributor

gkovacs commented Mar 30, 2017

I fixed the issue of yield* statements being generated inside async functions due to bug #764 in gkovacs/livescript-async@97b86df (also removed await all as await* is no longer part of ES2017)

@yizhong-ms
Copy link

@gkovacs could you please make a PR to my branch; thanks

@gkovacs
Copy link
Contributor

gkovacs commented May 25, 2017

removed await* which no longer exists. fix issue of yield* statements…
@determin1st
Copy link

does this update work? tried to run examples on livescript.net with no luck.

@dead-claudia
Copy link
Contributor

@determin1st This PR hasn't been merged, and livescript.net isn't updated until the next release IIRC.

@determin1st
Copy link

oh, i see. experimented with promises a little, found it useful but they are not "real" part of the language. it's like helpers. probably wont use this functionality.

@gkovacs
Copy link
Contributor

gkovacs commented Jul 14, 2017

@rhendric Given that the ES2017 standard (with async functions) has now been released and nodejs and all major browsers support the syntax by default, is there any chance you could review and merge this pull request? Thank you!

@rhendric
Copy link
Collaborator

I would be very happy to look it over! @summivox, can you confirm that this is in a state that you endorse for merging, or if there are any outstanding issues or design questions, summarize what they are?

@summivox
Copy link
Contributor Author

@rhendric Let me quickly build and verify. I think tests need to be added.

@rhendric
Copy link
Collaborator

Yes please to tests. No rush from me (I'm actually running out the door right now and probably won't have free time for a few days anyway); just drop me a mention when you're ready for a review and I'll follow up when I'm able. Thanks!

@willin
Copy link

willin commented Aug 27, 2017

mark, pls add in asap

@willin
Copy link

willin commented Aug 29, 2017

can it use now?

@gkovacs
Copy link
Contributor

gkovacs commented Aug 29, 2017

@willin If you're impatient and want to use it now do npm install -g livescript-async ( https://www.npmjs.com/package/livescript-async - it is just standard livescript plus this patch, uploaded by me to NPM as I grew impatient for this to be released). But no it is not yet released in the official livescript.

@willin
Copy link

willin commented Aug 29, 2017

it will be great helpful if you add a documentation for this package.

@ozra
Copy link

ozra commented Sep 19, 2017

@gkovacs - thanks for the npm! Trying it out right now.

@gkovacs
Copy link
Contributor

gkovacs commented Sep 20, 2017

I've added tests in a new pull request #978 - as summivox asked this to be taken over in #977 I will be taking over the efforts for getting this merged

@rhendric
Copy link
Collaborator

#978 has landed, so I'm closing this.

@rhendric rhendric closed this Sep 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants