Several years ago, I worked through the book Elixir in Action1. It was the first time I’d encountered actor systems, and I loved it. Thousands of light weight processes interacting through messages – this felt like what object orientation had promised me many years before.
I worked through examples spinning up processes, passing PIDs2, sending messages for completion, failure messages, recovery strategies. It felt exhilarating orchestrating these processes – the power, the possibilities,…
And then, having learned these super-powered coding techniques, we hid them. When the book packaged functions into a library, the public API hid as much of the complication as possible. A blocking version just looked like a function call. The process management, the message, the mailboxes, almost the entire distributed processing framework was all hidden. At first glance it was disappointingly simple. Almost vanilla. And yet, it was beautiful3. The library function did exactly what it needed to.
I realized something.
The user of your code doesn’t care how clever it is.4
I’d encountered something earlier in Haskell5, but it hadn’t sunk in properly then. The Elixir example was so clear. Library APIs are are to help a user accomplish a task, they’re not for you to show off. Anything which doesn’t help a user accomplish what they want to do is unhelpful noise and complication.
The revelation was also unexpected. I’d expected the book to surprise me with distributed systems. I hadn’t expected it to change the way that I thought about designing code in general.
There are consequences.
As the library designer, you need to know the magic. You need to know the low level plumbing, the tricks and performance. But for the user – it should all be below the surface.
As a collaborator, your clever code does need to be comprehensible to others. But that’s a different, inner beauty.
The biggest, and hardest consequence – you need to know your audience. You can’t judge what the best API is, you can’t judge the most intuitive concepts, unless you know your audience and what they want to accomplish.
… and how to do that is a blog post (or book) in itself. But it’s almost certain that your user doesn’t care about your cleverness. They appreciate it – but they’ve got a job to do! Write for your users. Show empathy in your APIs.
- There’s a new edition in preparation! If you’ve any interest in Elixir or concurrent systems via the actor model, it’s well worth reading. โฉ๏ธ
- Process identifiers โฉ๏ธ
- I wish I could find the exact code example. I’ll add it if I find it. โฉ๏ธ
- I might even go further and say that your general user mustn’t know or care how clever it is. Would ChatGPT be more or less used if the UI had more knobs to twiddle, or told the user how hard it had to work for every answer? โฉ๏ธ
- Haskell tutorials typically start with recursions, but as you progress you learn to use higher level constructs like folds. It feels less fundamental magic, but gains refinement. โฉ๏ธ