I’m glad to announce the first public release of dotty-cps-async. This release depends on the published version of the compiler and can-be downloaded from maven central.
Showcase:
Full implementation of async/await: all language constructions are supported.
Produce optimized code: the number of monad brackets is equal to the number of async operations, sequential parts run without additional overhead.
Pluggable interface for continuation monads.
Limited support for high-order functions: urls.map( httpClient.fetch(_) ).map(await(_)) can be an idiomatic way to fetch all URLs from the list in parallel.
Miscellaneous additional futures, such as automatic coloring, custom value discard, and sip22 compatibility layer.
import cps.compact.sip22 provides a SIP22-like interface. All test cases from the original Scala-Async distribution successfully passed with a change of imports only and included in the regression suite.
It is also possible to compile sip22 async code without changing the source code with shim’s help: add to the dependencies’ shim-scala-async-dotty-cps-async’ to scala3 dependencies instead scala-async for scala2.
Note that compatibility was not a primary goal during the development of dotty-cps-async. The generated code is quite different, so if you need a bug-to-bug compatible version of scala2 async, you should wait for the port of the original XAsync compiler plugin.
0.9.0 is published:
What was changed since 1-st public release, in the version, which is available for scala 3.0.1 final:
Main points behind bug fixing:
Implemented async variants for most high-order functions from scala standard library; Now if you use await inside for loop or fold – usually, it just works.
Simplified setting of shifted version of high-order functions: now developer can declare one inplace, instead creating an extra typeclass.
Implemented support oft custom call-chain builders: I.e. the following expression for( url <- urls if await(score(url)) > 0) yield await(fetch(url))
will traverse through urls only once, because we can merge filter and map in WithFilter call-chain builder.
Implemented support of automatic coloring:
I.e. we can write something like:
async {
val auth = db.retrieveAuth(url)
val data = fetchData(auth,url)
if (isInteresting(data)) then
db.increaseScoring(url)
}
the compiler will insert needed awaits automatically.
ScalaJS:
– Implemented support for non-monadic objects in awaited statements (i.e., js.Promise) - now it is possible use await(js.Promise) inside async block.
– Implemented JSFuture, which looks like ‘promise’ from the js side, but as typed monad on scala side.
It was tested in few internal projects and open-source libraries, depending from dotty-cps-async
The current one really assumes a lot of familiarity specific to scala’s async libraries and a research niche.
CpsAsyncMonad and the like are really not that common terminology for someone that is coming from python/javascript/c#. To be honest, even tough I’ve written parsers in scala and async-await AST transformations in other languages I really can’t follow this introduction (I find it easier to go over the code).
0.9.18. bring a compiler plugin with support for direct context encoding, which can be a practical next intermediate step in the journey of asynchronous API development.