English for Erlang Developers
Learn the English vocabulary for Erlang and the BEAM: fault tolerance, process isolation, and explaining why 'let it crash' is a deliberate design choice, not a bug.
Erlang conversations revolve around a concurrency model that looks alien to developers coming from thread-based languages, so the vocabulary centers on isolated processes, fault recovery, and explaining why crashing is often the correct behavior rather than something to prevent at all costs.
Key Vocabulary
Let it crash — the Erlang philosophy of allowing a process to fail immediately on an unexpected error instead of defensively catching every exception, relying on a supervisor to restart it into a known-good state. “We stopped wrapping every call in try/catch and adopted let it crash — the supervisor restarts the process faster than we could have recovered it manually.”
Supervision tree — the hierarchical structure of supervisor and worker processes that defines restart strategies, so that a failure in one branch is contained and repaired without affecting unrelated parts of the system. “The supervision tree only restarted the failing worker, so the rest of the application kept serving requests during the incident.”
Message passing / mailbox — the mechanism by which Erlang processes communicate exclusively through asynchronous messages delivered to a per-process mailbox, with no shared memory between processes. “Since there’s no shared state, all coordination happens through message passing — each process just reads from its own mailbox.”
Hot code swapping — the BEAM’s ability to load a new version of a module into a running system and migrate live processes to it without stopping the node or dropping connections. “We shipped the fix via hot code swapping, so the telecom switch never went down during the deploy.”
Process isolation — the guarantee that each lightweight Erlang process has its own memory and garbage collector, so a crash or memory spike in one process cannot corrupt or stall another. “Process isolation is why one misbehaving connection handler doesn’t drag down the other ten thousand connections on the node.”
Common Phrases
- “Should this error be handled defensively, or is this a case where we just let it crash?”
- “What’s the restart strategy for this branch of the supervision tree — one-for-one or one-for-all?”
- “Is this state coordinated through message passing, or are we accidentally sharing something?”
- “Can we ship this fix with hot code swapping, or does it require a full node restart?”
- “Are we actually relying on process isolation here, or did we introduce a shared resource?”
Example Sentences
Explaining a design decision to a teammate: “We deliberately let it crash on a malformed packet instead of trying to parse around it — the supervision tree handles the recovery.”
Reviewing an incident postmortem: “Process isolation contained the fault to a single connection handler, which is exactly why the outage only affected one customer instead of the whole node.”
Describing a deployment strategy: “Hot code swapping let us patch the billing module during business hours without dropping a single active call.”
Professional Tips
- Explain let it crash as a strategy, not negligence — it only works because of the supervision tree behind it, so always mention both together.
- Use supervision tree when discussing failure blast radius — naming the restart strategy (one-for-one vs one-for-all) shows you understand containment, not just recovery.
- Reach for message passing when someone assumes Erlang has shared mutable state — it’s the fastest way to correct a common misconception from thread-based backgrounds.
- Mention hot code swapping carefully in interviews — it’s a genuine BEAM differentiator, but be ready to explain its operational risks, not just its benefits.
Practice Exercise
- Explain the “let it crash” philosophy and why it depends on a well-designed supervision tree to be safe.
- Describe how message passing and process isolation together eliminate a whole category of concurrency bugs.
- Write two sentences describing a scenario where hot code swapping would be valuable in production.
In Practice: Navigating Nuance in Collaborative Development
Many developers new to Erlang, particularly those transitioning from languages with more rigid error handling or continuous monitoring, find the philosophy of “let it crash” profoundly unsettling. It’s a core tenet of the BEAM virtual machine and Erlang’s design, built around resilience and efficient resource utilization. However, simply stating “it should crash” isn’t enough in an English-speaking professional environment; you need to articulate why that choice is being made, demonstrating understanding of the underlying principles and mitigating potential concerns. This often involves explaining trade-offs – sacrificing immediate visibility for greater overall system stability.
Consider a scenario: Alice has just reviewed Bob’s PR, which introduces a new service handling user authentication. The code itself seems functional, but Bob’s comments include, “This needs more robust error handling.” While well-intentioned, this comment isn’t particularly helpful. A better response – and one that demonstrates the vocabulary we’ve been discussing – would be: “I appreciate your focus on robustness. I’ve reviewed the authentication service and deliberately opted for a ‘let it crash’ approach in certain failure scenarios. The goal is to avoid unnecessary process overhead during transient errors like network timeouts. By allowing failures to propagate, the system can quickly recover and continue serving legitimate requests. We’ve implemented circuit breakers to prevent cascading failures, and logging is configured to capture detailed information for debugging when necessary. This design aligns with Erlang’s philosophy of minimizing resource consumption in the face of intermittent issues.” Notice how this response explains why the crash is acceptable – it’s not a haphazard decision but a carefully considered one based on performance and resilience.
Furthermore, clear communication is vital during code reviews or when describing changes in Pull Requests. Instead of saying “The function will now handle errors,” which lacks precision, you might write: “This update refactors the error handling to prioritize immediate recovery. Uncaught exceptions are allowed to propagate upwards; this allows for quicker detection and isolation of issues rather than attempting to silently swallow them, which could mask underlying problems.” This phrasing highlights the proactive nature of the change – a deliberate choice to embrace failure as an opportunity for diagnosis. It also subtly reinforces the value of Erlang’s design philosophy.
Finally, remember that explaining technical concepts to non-technical stakeholders often requires adapting your language. You might say something like, “We’re building a system that is designed to gracefully handle temporary problems – essentially, it ‘lets them crash’ so that the core service remains available and responsive.” This framing avoids jargon while still conveying the key idea of resilience.
Here’s an example illustrating how to log errors effectively:
-module(my_service).
-export([start/1]).
start(Config) ->
case system_info(os_type) of
linux ->
{ok, Logger} = logger:new({my_service, "error"}, []),
logger:set_level(Logger, error);
_ ->
% Handle other OS types here (e.g., windows, darwin)
io:format("Warning: Unsupported OS type ~p~n", [system_info(os_type)]).
end,
{ok, true}.