dk00 / livescript-next

Enable latest ES features for LiveScript
https://lsn.netlify.com/
The Unlicense
39 stars 3 forks source link

mark function explicitly as async? #2

Closed gkovacs closed 7 years ago

gkovacs commented 7 years ago

first, thank you for your excellent work in bringing livescript to the ES7 world!

just my 2 cents, but I think it would be great for readability if it were possible to explicitly mark functions as async, similar to the async proposal at https://github.com/gkz/LiveScript/pull/836

the syntax implemented here seems to do something more implicit instead, using the same syntax as ordinary functions. while convenient for writing code, I can see 2 major issues for readability and maintainability/editing:

readability: you can't tell from the function declaration whether a function is async or not - you have to scan the entire function body to see whether or not there is an await statement.

maintainability: simply commenting out a line of code in your function for debugging purposes can now entirely change the code (it might change the function from async to regular, if it's the last await statement in the function body) - of course we could add a Promise.resolve to the return value to ensure it retains the same function call semantics, but we'd have to uncomment/add back an await statement.

a final issue caused by implicit-async-functions is that

function async-fetch
  return 'foo'
  data = await <| await fetch \https://api.github.com/gists/public .json!

or

function async-fetch
  if false
    data = await <| await fetch \https://api.github.com/gists/public .json!
  return 'foo'

vs

function async-fetch
  return 'foo'

now generate entirely different code (top 2 are async, bottom is not), even though just looking at the functions they would appear to be identical. (since we're normally assume that the dead code below the return statement in the first one, or the contents within the "if false" block, would have been removed during the dead code removal stage of compilation. hence, if code comes to rely on this implicit-async-functions feature, it may also prevent implementation of certain forms of dead-code removal and other compiler optimizations in the future)

dk00 commented 7 years ago

Yes, it's possible to mark async functions with async in this way, even without gkz/LiveScript#836.

We can implement it by transforming call to async with a function expression, just like how await is implemented.

Anonymous async functions(->>, ~>>, -->>, ~~>>) require syntax change, and would be enabled after merging gkz/LiveScript#836.

The idea of implicit async function was from coffeescipt, its docs said function*(){} and async function(){} are nonsense, but provide yield return and await return to explicitly mark generator or async.