Open and Closed Effect Systems
— 2025-05-22

When discussing effect systems in the context of production programming languages, I believe that the most important distinction is whether effects are purely defined by the language, or whether users are also able to define them. When Magnus Madsen from the Flix programming language joined the Rust T-Lang call for two sessions last December, he used the terms “open” and “closed” to describe this distinction:

The most interesting effects in programming languages have to be built-in. This includes things like controlling whether a function guarantees it will terminate (“divergence”). Or whether a function is allowed to perform side effects (“purity”).

This is different from user-defined effects. These are typically defined using “algebraic effect handlers”, but I’ve also seen the term “typed continuation” used 1. I think of these more or less as language-level support for thoroughly typed iterators/generators/coroutines. It doesn’t really make sense to express “divergence” using iterators. Which is why even though all effect handlers are effects, not all effects are expressed using effect handlers.

In the context of Rust all we’re discussing right now is the introduction of a closed effect system. And that’s not because we don’t think an open system would not be useful or good. But because formalizing and generalizing Rust’s effect system in a backwards-compatible way is an incredible amount of work already. And in order to ship, we have to draw the line somewhere 2.

1

I believe there is a difference between the two terms, but I don’t quite remember. I find “typed continuation” to be a lot more evocative though. Coming from Node.js 0.8, I think of this kind of as “what if all callbacks were fully typed and we had a compiler that ensured they were handled”. Maybe not syntactically the same, but I think it’s semantically quite close.

2

Though that doesn’t mean we can’t keep syntactic space open to consider it later. Just because we’re saying “not now” doesn’t mean we’re saying “not ever”.