Closed nadako closed 6 years ago
Should it be keywords? Maybe meta is preferable since it can hold some additional info e.g. for cps.
Not sure, meta for compiler features always look weird IMO.
Anyway, right now I'm also considering Kotlin-style coroutines that don't actually require much new syntax and maybe can indeed be triggered by meta at least at first.
So, after some research, I think I like the Kotlin approach more. They have the "suspending" function modifier and calling functions with this modifier means that the current coroutine should be paused. It's more generic and doesn't require explicit await
syntax, which can be nice for DSLs. Also the fact that the compiler knows that there's a suspending call, eliminates potential bugs when someone forgets to await
a function when its result value is unused.
The original example could look like this:
suspend function loadXml(url) {
return Xml.parse(loadString(url)); // loadString is suspending, so the execution will be paused
}
suspend function loadString(url) { ... }
Here's a fully working demonstration: https://gist.github.com/nadako/8761a0767654dd28c8a636d84ea399e8
I don't like there is no syntax which will notify reader about "suspend points".
I don't like there is no syntax which will notify reader about "suspend points".
I think in real world, the function like the loadString
above would return some kind of future/promise/task, and to await it there'll be a suspending await
method, which is quite straightforward to read IMO:
suspend function loadXml(url) {
return Xml.parse(loadString(url).await()); // or await(loadString(url))
}
The benefit of not having await
hard-baked into the language itself is that it can be used for DSLs for e.g. UIs or in-game cutscenes, where everything is async and you'd have to write await
everywhere and the code would become very cluttered.
Another benefit is that await
have a single meaning - we await for execution of some task, while there can also be yield
- we just yield control returning some value (generators), or channel.send
(go-like concurrency). Kotlin approach supports all these by implementing very basic suspendable functions which then others can build on.
Looks nice at first sight.
Alright, I pushed whatever I had in a Gist as README and will continue to clear syntax-related things up there.
To support that we introduce new keywords:
async
andawait
, a newExpr
node:EAwait(e:Expr)
and theisAsync
flag for theFunction
structure.