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

Add Implicit Async Functions #3757

Merged
merged 47 commits into from
Nov 2, 2016
Merged

Add Implicit Async Functions #3757

merged 47 commits into from
Nov 2, 2016

Conversation

GabrielRatener
Copy link
Contributor

Temporary fix for bug #3750, tried it, it works.

@GabrielRatener GabrielRatener changed the title changed jison acceptable versions change jison acceptable versions Dec 16, 2014
@GabrielRatener
Copy link
Contributor Author

Here is an outline of my async/await implementation:

The new await keyword implicitly modifies an enclosing function
into an async function which returns a native JS promise when called.
The returned promise resolves to the explicit return value of the function.

When an A-compliant promise is modified with await,
control is passed back to the calling function at that point. The async
function resumes once the function is resolved, with the value of the await <promise> expression being that of the resolved promise.

Similar to generators, in cases where a function needs to be made async
explicitly, await return <some optional expresstion> can be used inside
the function body instead.

When an awaited promise is rejected, a regular error is thrown. These errors can be handled like any other, with try/catch statements.

Since native ES6 promises cannot resolve to a promise, neither can
async function promises. Instead, the first non-thenable value encountered
in the promise resolution chain will be the actual resolution value of the async functions' promise. For example:

    someExplicitlyAsyncFuntion = ->
        # returns a promise that has resolution value 5
        await return Promise.resolve(5)

    do ->
        awaitedValue = await someExplicitlyAsyncFuntion()
        console.log awaitedValue    # logs 5 to the console

Unlike the yield operator, which can work with any kind of expression,
the await operator, works solely on promises. Since no arithmetic operation can
result in a promise in CS/JS, the await operator is given precedence over all arithmetic operators. For example:

    fn = (win, fail) ->
        win(3)

    do ->
        out = 1 + await new Promise(fn) ** 2
        console.log out     # outputs 10 to console

Similar to yield, await cannot occur outside a function body. Additionally,
yield or yield from, and await cannot occur in the same function body, doing so
will result in a compile time error. However in the future this may be enabled for async generators.

Any proposals, modifications, questions, or any other feedback would be really awesome!

@GabrielRatener GabrielRatener changed the title change jison acceptable versions Async/await support on top of enerators Dec 19, 2014
@GabrielRatener GabrielRatener changed the title Async/await support on top of enerators Async/await support on top of generators Dec 19, 2014
@GabrielRatener GabrielRatener changed the title Async/await support on top of generators Async/await Support on Top of Generators/Yield Dec 19, 2014
@vendethiel
Copy link
Collaborator

Amazing. I'm not sure the first commit should be in this PR, though.

@GabrielRatener
Copy link
Contributor Author

@vendethiel CS does not work properly with newer versions of Jison, see #3750. Until CS is updated to work with a newer version of Jison, shouldn't only v0.2.x be used?





Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What’s up with all these empty lines at the end?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lydell Not sure, but I want to make the last test more specific anyway, so I will eliminate this in the next commit.

@GabrielRatener
Copy link
Contributor Author

@vendethiel The first commit has been purged since #3750 has been fixed.

@nfour
Copy link

nfour commented Jan 16, 2015

SIgn me up, the more control flow options the better at this point!

generatorsAreAvailable = '--harmony' in process.execArgv or
'--harmony-generators' in process.execArgv
files.splice files.indexOf('generators.coffee'), 1 if not generatorsAreAvailable
files.splice files.indexOf('async.coffee'), 1 if not generatorsAreAvailable
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have made an unless generatorsAreAvailable block with the two files.splice lines in it.

@GabrielRatener
Copy link
Contributor Author

Considering making resolve an alias or possibly a replacement to await, any thoughts?

@GabrielRatener
Copy link
Contributor Author

@Artazor just added support for async constructors, I think this could be quite useful, nice idea!

@Artazor
Copy link
Contributor

Artazor commented Jan 30, 2015

@GabrielRatener, great! But I think that we should scan the AST of the constructor and add the implicit return of this at the end, or if there are explicit returns inside the body - wrap their results with some utility like

return a      
       # should be replaced with
return _nonPrimitive(a, this)

where

_nonPrimitive = (value, that) -> 
    if typeof value is 'object'
        value ? that 
    else 
        that ? value  # ? value - for the case when constructor called as function (without new)

@lydell
Copy link
Collaborator

lydell commented Nov 2, 2016

Looks good to me, too. Hit the green button when you feel like it, @GeoffreyBooth!

@GeoffreyBooth GeoffreyBooth merged commit 496fd5d into jashkenas:2 Nov 2, 2016
@GeoffreyBooth
Copy link
Collaborator

Thanks and congrats @GabrielRatener !

@GeoffreyBooth
Copy link
Collaborator

What about documentation for this?

@GabrielRatener
Copy link
Contributor Author

This should definitely be documented, especially since this could be a source of confusion as in #4349.

@GeoffreyBooth
Copy link
Collaborator

Do you care to write some documentation, perhaps as a new PR for 2?

@GabrielRatener
Copy link
Contributor Author

@GeoffreyBooth Yeah, I can open a new PR for that.

@GeoffreyBooth GeoffreyBooth modified the milestone: 2.0.0 Feb 9, 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.