By now, you’ve seen that Elixir code isn’t organized around changing state or executing steps. It’s organized around values flowing through functions.
That naturally raises the next question:
If functions transform data, what kind of data should you use?
In Elixir, this isn’t a cosmetic choice. The shape of your data determines how your code behaves, how it reads, and how it evolves.
Elixir Doesn’t Have “One Data Structure”
Many languages push you toward one dominant structure: objects, hashes, or dictionaries.
Elixir doesn’t.
Instead, it gives you several small, focused data types, each optimized for a specific kind of work:
- atoms
- tuples
- lists
- maps
They overlap slightly, but they are not interchangeable. Choosing between them is a design decision, not a convenience.
Atoms Encode Meaning
Atoms are constants with names:
:ok
:error
:pending
They are not strings, and they are not labels for display. Atoms exist to represent meaning.
When you see:
{:ok, result}
{:error, reason}
You’re not looking at data values. You’re looking at semantic signals.
Atoms make intent explicit. They let data describe what it represents, not just what it contains.
🎯 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.
Tuples Encode Fixed Structure
Tuples are ordered collections with a fixed size:
{:ok, value}
{:error, reason}
This is not arbitrary.
Tuples are used when:
- the number of elements matters
- the position of elements matters
- the structure is intentional
A tuple says: this data has a known shape.
That’s why return values in Elixir so often use tuples. The shape itself communicates meaning.
Lists Encode Sequential Access
Lists are not general-purpose containers.
They are linked lists, optimized for head-first, sequential processing:
[1, 2, 3]
Lists are ideal when:
- order matters
- you process items one by one
- you traverse from the front
They are a poor choice for:
- random access
- frequent indexing
- large key-based lookups
In Elixir, choosing a list tells the reader: this data will be walked through, element by element, from the head.
Maps Encode Association
Maps are for key-based access:
%{name: "Paulo", role: :admin}
Maps shine when:
- you care about values by name
- keys matter more than order
- data is accessed selectively
Maps are flexible, but flexibility has limits.
If you find yourself relying on specific keys always being present, that flexibility may be hiding design intent. That’s often a signal that a more explicit shape—like a tuple or a struct—is needed.
Why This Matters More Than Convenience
Beginners often ask which data type is faster.
That’s not the most useful question.
In Elixir, choosing the right data structure does three things at once:
- it feels more natural to work with
- it’s more efficient for the access patterns you’re using
- it communicates intent clearly to other developers
Lists are efficient because they’re meant to be accessed head-first. Tuples are efficient because their size and layout are fixed. Maps are efficient because they’re designed for associative lookup.
Performance isn’t ignored, it’s built into the design.
When data shape matches intent, code becomes easier to read, easier to refactor, and harder to misuse.
Most of the complexity in Elixir code comes not from the logic, but from choosing the wrong shape early.
What to Practice Today
Take a piece of Elixir code you’ve written recently and ask:
- Is this list really a sequence?
- Is this map hiding a fixed structure?
- Would a tuple make intent clearer?
- Are atoms being used to signal meaning, or replaced by strings?
Try changing the data shape without changing behavior.
If the code becomes clearer, you’ve learned something important.
What Comes Next
At this point in the series, you have all the raw materials:
- expressions that return values
- bindings instead of mutation
- functions selected by arity and arguments
- data shapes that encode intent
The final step in Module 1 is to see how these ideas work together in a small, complete example.
That’s where everything clicks.
See you in the next chapter.
— Paulo Valim & Bruce Tate
Want to Master Elixir the Way It's Actually Designed?
This post is from Bruce Tate's structured Elixir course, where you build deep understanding step by step—not through scattered tutorials, but through a proven learning path used by hundreds of developers. Stop piecing together blog posts and start learning Elixir the right way.