Skip to content
Tech News
← Back to articles

Abstracting Effects with Continuations

read original more articles
Why This Matters

This article highlights the importance of using continuations to abstract various effects in programming, such as error handling and asynchronous computations. By leveraging continuations, developers can create more flexible and expressive code that can handle complex workflows and effects seamlessly, which is crucial for building reliable and scalable software systems in the tech industry.

Key Takeaways

Abstracting effects with continuations

Representing errors as values is a powerful tool for writing reliable programs. A result value wraps the desired value or holds information about why the computation failed. An explicit result type represents the possibility of failure in the type system. A function that returns a result forces the caller to account for failure.

The result is one instance of a bigger pattern. A promise represents computation that is asynchronous. Return a promise and the caller is forced to wait for the computation to complete before accessing the value.

A result and promise each track a specific detail about some computation. To generalise over the details of a computation, use a continuation. Using a continuation says: “I have no idea how you’re going to get the value, but when you do, this is what should be done next.”

Filinski, Representing Monads (1994) proves continuations can express any monad (such as Result and Promise). We will not get into the maths of the proof. This post is to demonstrate how to use continuations in Gleam.

A contrived example

We work with a fetch function that returns a value for a key. The function is provided by the caller and takes a String key and returns a String value.

Accepting fetch as an argument allows us to fetch values from different data sources as needed. A trivial implementation of fetch could ignore the key and always return "yes" :

fn fetch(key: String) -> String { "yes" }

The business logic does the following. For a fixed list of keys, transform each to uppercase, and return the length of the associated value. A simple solution to this task looks like the following.

... continue reading