Skip to content
Back to the collection

Retrofitting Effect Handlers onto OCaml

KC Sivaramakrishnan, Stephen Dolan, Leo White

Show all 6 authors

Tom Kelly, Sadiq Jaffer, Anil Madhavapeddy

2021 · arXiv

Read the paper
HN score
0
Mentions
7
Readers
4
Months
5
What’s in a score?

From the abstract

Effect handlers have been gathering momentum as a mechanism for modular programming with user-defined effects. Effect handlers allow for non-local control flow mechanisms such as generators, async/await, lightweight threads and coroutines to be composably expressed. We present a design and evaluate a full-fledged efficient implementation of effect handlers for OCaml, an industrial-strength multi-paradigm programming language. Our implementation strives to maintain the backwards compatibility and performance profile of existing OCaml code. Retrofitting effect handlers onto OCaml is challenging since OCaml does not currently have any non-local control flow mechanisms other than exceptions. Our implementation of effect handlers for OCaml: (i) imposes a mean 1% overhead on a comprehensive macro benchmark suite that does not use effect handlers; (ii) remains compatible with program analysis tools that inspect the stack; and (iii) is efficient for new code that makes use of effect handlers.

Metadata: arXiv. Abstracts retain their original authors’ rights.

In the conversation

Original HN comments, with labels from simple text rules. A label describes the whole comment and may miss context or irony. Read the discussion to make up your own mind. About the labels

7 selected excerpts · 7 total mentions

grumpyprole
Neutral mention · rule
> Do you have any good resources on OCaml5 effect handlers I can follow? I encourage you to have a look at the published paper, it's an easy read and covers the motivation and examples: https://arxiv.org/abs/2104.00250 Here's an excellent talk that walks through modifying a non-trivial code base for concurrency using effect handlers: https://youtu.be/k3oQwpyXmpo > It does feel to me like error's and async's both should remain orthogonal They aren't completely orthogonal though, as both are effects. Haskell and Rust model both with Monads. OCaml 5 can model both with effect handlers. It is desirable to track the difference in types, this is something I hope the OCaml folks will add in the future.
sadiq
Neutral mention · rule
We certainly hope so. You may find Thomas Leonard's talk from last year's workshop interesting: https://watch.ocaml.org/videos/watch/74ece0a8-380f-4e2a-bef5... The paper we wrote on retrofitting effect handlers: https://arxiv.org/abs/2104.00250 also has some http benchmarks
wahern
Neutral mention · rule
Non-contiguous stacks are typically just linked-lists of call frames, or groups or call frames. One of the examples that used to be regularly trotted out comp.lang.c 15+ years ago was an IBM mainframe environments, where stacks were linked lists but still managed by hardware. Off the top of my head, current examples of non-contiguous stacks on more familiar system with supporting code compiled directly to machine code (i.e. not language interpreters and VMs, where this is actually very common), include 1) gccgo, which compiles Go code to use split stacks. 2) gcc with -fsplit-stacks, which permits compiling C (and C++?) code which uses the same stack discipline as…
Read the full comment
gccgo. 3) OCaml's new concurrency work utilizes non-contiguous stacks. I'm not familiar with OCaml toolchains, but notably they do generate DWARF and related tables so both debuggers and the garbage collector can properly walk logical stacks. See https://arxiv.org/abs/2104.00250 4) There's a stack-smashing and ROP prevention technique call shadow stacks, where a single logical call stack is implemented using two contiguous stacks, one primarily for return addresses (or related metadata) and the other primarily for objects. See https://en.wikipedia.org/wiki/Shadow_stack Both GCC and clang support software-implemented shadow stack disciplines (SafeStacks), and some newer Intel and ARM ISA extensions implement hardware-enforced shadow stacks.
kcsrk
Neutral mention · rule
Abandoned is perhaps too strong a term :-). Effect handlers in the language are supported by fibers, lightweight stacklets managed by the runtime. The details of the implementation can be found in the upcoming research paper in PLDI'21 conference [1]. The effect handlers in Multicore OCaml today do not provide effect safety. Programs are not statically guaranteed to handle all the effects they may perform. This is only as bad as exceptions in OCaml and every other mainstream language with exceptions. We are working on developing an effect system, which will ensure effect safety i.e, the compiler ensures that all the effects performed are caught. You also get a nice…
Read the full comment
inferred type that says what effects a particular function may perform; if it performs none, then it is a pure function! This implementation would still use the current fiber support in the runtime. Leo White, one of the developers of Multicore OCaml had given a talk on this new effect system a few years ago [2]. That's the best place today to learn about the new effect handlers. The plan is to first add the fiber runtime support to OCaml without the syntax extensions for effect handlers, and then introduce syntax along with the effect system. [1] https://arxiv.org/abs/2104.00250 [2] https://www.janestreet.com/tech-talks/effective-programming/
sadiq
Neutral mention · rule
It involved a fair amount of research and there were many technical challenges. Maintaining backwards compatibility in terms of language features and single-threaded performance puts constraints around what you can implement. Also from my personal experience, debugging segfaults in parallel programs that could be caused by GC bugs is a painstaking process. We've written a couple of papers detailing the internals and the trade-offs involved: https://arxiv.org/abs/2004.11663 (for parallelism) and https://arxiv.org/abs/2104.00250 (for effects) Added to that is the complexity of tracking a moving target. Multicore had to be rebased through 12 releases of OCaml, which in itself was a non-trivial amount of work.
sadiq
Neutral mention · rule
Good questions! 1) As I mentioned in https://news.ycombinator.com/item?id=27142502 there is support for parallelism and concurrency. Giving an example of where these might be useful in a webservice. The addition of shared-memory parallelism is beneficial where you might have a great deal of shared state that needs to be used to service requests. An in-memory cache is a good example - with a processed-based approach managing read/writes and avoiding significant overhead from marshalling the data is difficult. Concurrency via effects at a minimum can make writing network-based services much more pleasant (and debuggable!). See the examples in…
Read the full comment
https://arxiv.org/abs/2104.00250 where programs can be written in a direct-style similar to blocking IO but using effects are transformed to use asynchronous interfaces. There's work going on in the project at the moment to build fast cross-platform IO implementations that sit atop of uring/gcd/iocp. 3) This is a good question and one we're still working on. I think one of the lead developers KC has a few good ideas about instrumentation we can do to enable detecting races to global state. It's certainly going to be an issue for people porting large codebases. 4) This is the place to start: https://github.com/ocaml-multicore/multicore-opam#install-mu... .
sadiq
Neutral mention · rule
Not dumb questions at all. Multicore adds parallelism via Domains (which are essentially heavyweight threads) and concurrency via Effects and fibers. There's a multicore GC that supports both of those. We plan to upstream things in two parts. First domains-only parallelism and then effects as a follow-up. When the latter lands users will be able to define their own effects and handlers, yes. Performance is pretty good, you can see our PLDI2021 paper for a proper performance evaluation and loads more details: https://arxiv.org/abs/2104.00250

Keep following the thread.

More in Programming languages

More from the same topics.