Tech News
← Back to articles

Writing your own BEAM

read original related products more articles

This is my Code BEAM Europe 2025 talk, converted to a blogpost.

I was always fascinated with BEAM, how it allowed easy spawning of processes that didn’t share state, allowed for sending and selectively receiving messages, and linking to each other thus enabling creation of supervision trees.

It’s an interesting set of primitives that interact in a nice way, and are in my view responsible for much of the appeal of BEAM languages. I wanted to see how much it takes to support these primitives, and I set out to write my own toy MVP implementation of BEAM.

As a disclaimer, I haven’t read The BEAM Book yet, and how I do things might differ substantially from how the real BEAM does things. This is an exploration from first principles based on how I perceive BEAM from the outside, and doesn’t aim for truthfulness to the reference implementation, real world usefulness nor performance.

The below examples are written in Elm, but if you can express it in Elm, you can express it in anything (it’s purely functional so there’s no mutation, it’s single threaded and has no concurrency primitives, etc.).

AST representation

I will only be making the scheduler and its main loop, not a full-blown language or VM. This allows me to only keep a few hardcoded examples around and skip writing a parser, CLI and a bunch more parts that a real compiler would have.

In the interest of skipping as much work as possible, I’ll be using continuation passing style (CPS) for the example programs instead of the usual “list of statements” style:

-- ☑️ YES: continuations type Program = End | Work Int K | Spawn Program KPid | Send Pid String K | Receive String K | Crash | Link Pid K type alias K = () -> Program type alias KPid = Pid -> Program -- ❌ NO: list of statements type Stmt = Let String Expr | Work Int | Spawn Program | Send Pid String | Receive String Program | Crash | Link Pid type alias Program = List Stmt

This means I don’t have to care about environments, bindings, scopes, return values, expressions and so on, as this will be handled by the continuation arguments in the host language:

... continue reading