Implementing Algebraic Effects in C
microsoft.com
microsoft.com
For example, the P language [10] is a language for describing verifiable asyn-
chronous state machines, and used for example to implement and verify the core
of the USB device driver stack that ships with Microsoft Windows 8. Compiling
to C involves a complex CPS-style transformation [19, 26] to enable async/await
style programming [5] with a receive statement – using the effects library this
transformation is no longer necessary and we can generate straightforward C
code instead. Similarly, we hope to integrate this library with libuv [29] (the
asynchronous C library underlying Node [43]) and improve programming with
libuv directly from C or C++ using async/await style abstractions [12, 27]
Since the linked abstract doesn't actually mention this practical application, consider this comment as a goad to encourage more people to click through to the paper :)IMO, Koka (or something similar) has more potential to become a mainstream language than "traditional" FP languages (Haskell, OCaml, Idris, etc.).
Effects seem to be easier to understand than monads (at least on a superficial level) and more modular (I don't have a lot of experience with Haskell, so take that with a grain of salt).
Its syntax is also very close to C-like languages.
Taken from the Koka book[2]:
fun square1(x : int) : total int {
return x*x
}
fun square2(x : int) : io int {
println( "a not so secret side-effect" )
return x*x
}
`square1` is a pure mathematical function, so its effect is `total`. `square2` has a side-effect because of `println`, so its effect is `io`. This means that `square2` can raise exceptions, not terminate, be non-deterministic, read and write to the heap, and do any input/output operations.Note that Koka can infer effects, so these annotations are optional.
[1]: https://www.microsoft.com/en-us/research/project/koka/?from=...
[2]: https://koka-lang.github.io/koka/doc/kokaspec.html#sec-effec...
(And then there's https://reasonml.github.io, which I work on)
I actually tried to use it very recently in a new project at my workplace, but unfortunately I decided not to. I found some fundamental things were lacking.
I didn't find documentation about how to interact with npm libraries (e.g. how do I use a websockets library in Reason? Do I have to create my own bindings? If so, how?).
There also seemed to be nothing similar to async/await in Reason/Bucklescript yet and I couldn't find out how to use promises.
I'll definitely reevaluate it in the future. I think it is an awesome project with great potential (along with Bucklescript which is awesome too).
You can also check the community's work: https://reasonml.github.io/community/
import 'mod::memcmp': O(1);
where O(1) is big O notation.I could see this being used to choose between allocators or schedulers given specific requirements.
Just wanted to add that you can find the library at: https://github.com/koka-lang/libhandler
The `dev` branch contains a sample of `libuv` integration. There is still a lot to be done in terms of creating a better interface and providing implementations of standard effects but the core is working quite well by now.
Enjoy!
The original Icon compiler compiled to CPS C. That was pretty cool.
One can do much of what Icon did using GCC local functions and computed gotos to get something much closer to not-CPS.
There's Simon Tatham's PuTTY, which uses his co-routine macros, which are an extravagant meta-programming macros around a Duff's device. He also has an extensive set of meta-programming macros as well, not related to co-routines.
Some Schemes compile to C code where all functions always return immediately, but what they return is a continuation, and the top-level is a for(;;) { next = next(); }.
EDIT: I'm particularly fond of PuTTY. Its SSHv2 implementation all the way up to the end of authentication is a single, huge function. It looks completely synchronous, but it's not, because it's actually a co-routine. As a result, and in spite of being a single huge function, it's actually quite readable.
As an aside, I feel algebraic effect handlers are safer to use than most coroutine or shift/reset implementations because they offer more structure. As put by others: "Algebraic Effects+Handlers" are to "delimited continuations" as "while" is to "goto"
[1]: https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html