Never Look Back - A New Paradigm: The Elixir of Life

Posted on Nov 4, 2025

Chapter 3: A New Paradigm: The Elixir of Life

My discovery of Elixir wasn’t a sudden epiphany but a gradual realization that there had to be a better way to address the problems I was facing. Elixir, a dynamic, functional language built on the Erlang Virtual Machine (BEAM), offered a fundamentally different set of answers.

  1. Functional Programming vs. Object-Oriented

    Moving from Ruby to Elixir is a shift from an Object-Oriented (OO) mindset to a Functional Programming (FP) one. In Ruby, everything is an object. You create instances of classes, these instances hold state, and you call methods on them that mutate that state.

    In Elixir, the primary building blocks are functions. Data is separate from behavior. And, crucially, data is immutable.

    # In Elixir, you don't change data, you transform it.
    my_map = %{name: "Andi", role: "developer"}
    
    # This doesn't change my_map. It returns a NEW map.
    updated_map = Map.put(my_map, :role, "senior developer")
    
    # my_map is still %{name: "Andi", role: "developer"}
    

    This seems like a small difference, but it has massive consequences. Immutability eliminates a whole class of bugs related to shared, mutable state. You never have to wonder if some other part of the system has unexpectedly changed the data you’re working with. This makes code easier to reason about, easier to test, and, most importantly, makes concurrency trivial and safe.

  2. Pattern Matching: A Developer’s Superpower

    If there’s one feature that defines the Elixir experience, it’s pattern matching. It’s not just a switch statement on steroids; it’s a way of controlling program flow and destructuring data at the same time.

    You can pattern match on function heads:

    def handle_request(%{method: "GET", path: "/users/" <> id}) do
      # Logic to get user by id
    end
    
    def handle_request(%{method: "POST", path: "/users", body: body}) do
      # Logic to create a user with the body
    end
    
    def handle_request(_request) do
      # A catch-all for requests we don't handle
    end
    

    This is incredibly expressive. The function signature itself documents what it expects. The _request catch-all at the end is a common pattern that acts as an “else” and prevents unhandled cases from crashing (or rather, allows them to to crash explicitly, which we’ll get to).

    You can also use it with the case statement to handle different outcomes:

    case Repo.insert(changeset) do
      {:ok, user} ->
        # Success! Do something with the created user.
        {:ok, user}
    
      {:error, changeset} ->
        # Failure! The changeset tells us exactly what went wrong.
        {:error, changeset}
    end
    

    This forces you to handle both the success and failure paths. It makes “happy path” programming difficult and encourages robust, resilient code from the very beginning.

  3. The BEAM: A Battle-Tested Foundation

    Perhaps the most significant advantage Elixir has is its runtime: the BEAM. The Erlang VM was designed from the ground up by Ericsson in the 1980s to build fault-tolerant, highly concurrent telecommunications systems—systems that needed to run with “nine nines” of uptime (99.9999999%).

    The BEAM’s concurrency model is not based on threads but on millions of tiny, lightweight processes that are completely isolated from each other. They don’t share memory. They communicate by sending messages. A web request in a Phoenix application is handled by its own process. A WebSocket connection has its own process.

    The BEAM’s scheduler is pre-emptive and runs on all available CPU cores. This means you get true parallelism out of the box. A single, powerful server can handle an enormous amount of concurrent work without breaking a sweat. The GIL is simply not a factor. The architectural complexity of running separate worker processes for background jobs melts away. You can just spawn a new process. It’s that simple.


Read prev: The Cracks in the Foundation | Read next: Phoenix - The Framework That Respects You