If you’ve been programming for a while, Elixir probably feels strange at first. Not difficult exactly, just sideways. You understand the syntax. You can read the code. But when you sit down to write something, the patterns you’d use in Ruby or Python don’t quite fit. You find yourself fighting the language instead of flowing with it.
Here’s what’s actually happening: you’re not learning a new syntax. You’re learning a different execution model. And until that clicks, Elixir will keep feeling harder than it needs to be.
The Shift That Makes Everything Else Make Sense
Most languages teach you to think in steps and state. You write code that does things in sequence, modifying values as you go:
user = get_user(id)
user.name = "New Name"
user.save()
Your mental model is: get the thing, change it, save it. Three steps acting on one piece of state.
Elixir works differently. It doesn’t organize code around things that change. It organizes code around transformations. You have data structures and functions that transform them. That’s it.
🎯 Join Groxio's Newsletter
Weekly lessons on Elixir, system design, and AI-assisted development - plus stories from our training and mentoring sessions.
We respect your privacy. No spam, unsubscribe anytime.
Bruce opens his Elixir course with this:
“In this module, you’ll learn about operators and variables, but underneath it all, it is all about functions and data.”
— Bruce Tate
Don’t think in terms of state changes. Think in terms of transformations.
He’s not simplifying for beginners. He’s giving you the actual model that expert Elixir developers use every day. Data and the functions that work with that data. Everything else—pattern matching, pipe operators, immutability, processes, supervision trees—builds on that foundation.
Once you stop trying to modify state and start thinking in transformations, loops become Enum calls, conditionals become pattern matching in function heads, and objects become plain maps or structs. The language isn’t fighting you anymore because you’re working with its model instead of against it.
Why This Is Harder Than Your First Language
Here’s the uncomfortable truth: learning Elixir is harder for experienced developers than for beginners. Not because Elixir is more complex, but because you have to unlearn patterns that work perfectly well in other languages.
You’ve built instincts. You know how to structure code. You’ve internalized solutions to common problems. And now Elixir is asking you to set most of that aside and think differently.
That cognitive friction isn’t a bug in your learning process. It’s the actual work. You’re not just adding new syntax to your toolbox. You’re rebuilding the mental model underneath.
But here’s the good news: once the model clicks, Elixir becomes one of the clearest languages you’ll work with. Because the model is simple. Data flows through functions. That’s the whole game.
What to Practice Right Now
Here’s something concrete you can do today: stop reading Elixir code from left to right. Read it from right to left and inside out.
Dave Thomas opens Programming Elixir with this example:
"Elixir"
|> pragmatic
|> concurrent
|> fun
This isn’t just syntax—it’s the book literally showing you how to think. The data flows down. Each function transforms it. The result emerges naturally.
Look at this line:
String.upcase(String.trim(user_input))
Don’t read it as “call String.upcase on the result of String.trim.” That’s still thinking in steps.
Instead, read it as: “user_input becomes trimmed input becomes uppercase output.” The data transforms as it moves through functions. You’re following the data, not the function calls.
With the pipe operator, the transformation becomes explicit:
user_input
|> String.trim()
|> String.upcase()
Now the data flows down. Each function describes what happens to it. No hidden state. No side effects. Just: this becomes that becomes that.
When you catch yourself thinking “this function does something,” stop and reframe: “this function transforms something into something else.” That small shift in language reveals whether you’re thinking in the old model or the new one.
What Comes Next
This mental model shift—from steps and state to data and functions—is the foundation. Everything in this series builds on it.
Next week, we’ll look at why everything in Elixir is an expression, and how that changes the way you structure code at a fundamental level. Not as trivia, but as a design tool you can use immediately.
The rest will make a lot more sense once you see expressions the way Elixir does.
See you in the next chapter.
— Paulo Valim & Bruce Tate
Want to Learn Elixir the Way It's Actually Designed?
This post is part of our series following Bruce Tate's structured Elixir course - the same course that has helped hundreds of developers successfully make this mental model shift. If you're ready to stop fighting Elixir and start flowing with it, we'd love to teach you.