by Chad Fennell

On Polyglot Programming

Build a toolbox and fill it full of tools.

On Polyglot Programming

The folks over at bitcrowd announced their selection of Elixir for building an open source version of Bluesky’s data plane. I’m a huge fan of Elixir so this obviously panders to my preferences. But I want to focus on something else: how the bitcrowd team’s cultivation of expertise in multiple programming languages unlocks massive new possibilities.

On Complexity

There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult. - C. A. R. Hoare

When searching for a solution to a problem it’s helpful to have more than one tool to choose from. Programming languages are peculiar tools. They are not just one thing; they are a collection of opinions and tradeoffs. And because of that, software development teams often stick to what they know, arguing that adding a new language complicates their stack. The emotional appeal I hear in this context is that they don’t want to “chase shiny objects.”

But sometimes that shiny object is a screwdriver and the problem you are staring at is a screw. And because programming languages present subtle tradeoffs, you will never see the right one for the screwdriver that it is without cultivating knowledge of how these systems work, where they excel, where they break. In the right context, that knowledge can be a massively simplifying force for the execution and maintenance of the software you are building, even at the cost of adding a new language to your stack.

Easy vs Simple

A pile of multicolored fabric

Years ago, I attended Rich Hickey’s presentation “simple made easy” at RailsConf 2012. It had a profound impact on how I think about solving problems. The crux of Rich’s point is that we often reach for easy solutions when we should be building simple solutions where easy is what is familiar, close at hand, and where simple is something like un-intertwined or complected - the opposite of complex. Your favorite axe is close at hand. But maybe it’s not the right tool for the job.

bitcrowd’s Tradeoff or How Rust Enabled Elixir

The important wrinkle in bitcrowd’s selection of Elixir is that they wrote one CPU-bound critical component in Rust. That was the unlock to get all of the goodness of the BEAM for the rest.

The compute-bound half runs in Rust regardless of host language. What’s left for Elixir is orchestration: high-concurrency request serving and the fan-out queue, the regime where the BEAM is at its best and where our own production experience says it’s most efficient.

Adding Lanes To the Highway Doesn’t Resolve Congestion

Aerial view of congested highway interchange

People become a lot more receptive to new ideas when what they have been doing is not working for them, often in dramatic fashion. But we almost always resist the inevitably painful change that is actually required to resolve the problem. Instead, we choose to amplify previous efforts, and reaching out for help is a call to add to our brute force efforts. I mentally shorten this conversation to: “What I’m doing isn’t working but I don’t want to change.”

I like to think of this call to do more as the “extra lane on the highway” solution. Studies have conclusively demonstrated that, counterintuitively, adding lanes to a busy highway won’t reduce congestion. Certain kinds of software systems problems remind me of this phenomenon. It’s like adding more memory to fix a memory leak. If a system is consuming a massive amount of resources and wearing out the team as they try to keep up with it, maybe it’s the wrong solution. If you are paying exorbitant AWS bills for a traditional relational database where a hosted SQLite database (they exist now) would suffice, you will wind up adding lanes to keep up with demand. If your team only knows, say PHP, and is tasked with delivering a high performance real time service, you’ll be adding lanes - external tools, server resources, and generally flowing against the “rebuild the world one every request” grain in order to achieve that goal. Maybe look at how other language communities have solved this problem to see if there is a more ergonomic fit.

Don’t Wait For the Crisis

This is fine meme

We are less creative, more contracted, more reactionary when we are stressed or scared. We fall back into comfortable - easy - patterns under duress. What we are doing isn’t working but we are unable to change. So, don’t wait for that moment.

It’s hard to pick from a set of tools you don’t really understand. Build a small project in a popular language that you are not familiar with in order to learn a bit about what I like to call its “chi” - how it wants to flow around problem spaces. Loading that up into your RAM means you will think differently about problems - even in your own preferred stack. Worst case scenario: you know enough to reject a solution on its merits rather than on a lack of familiarity. It’s all upside.

Plus, it’s fun.

Enjoyed this? Get new posts in your inbox.

Subscribe