Keyword Lists
A keyword list is simply a list of two-element tuples where the first element of every tuple is an atom, such as [name: "Ada", age: 30], which is shorthand for [{:name, "Ada"}, {:age, 30}]. Because it's built on the ordinary list, a keyword list preserves insertion order, allows the same key to appear more than once, and inherits every list characteristic discussed for lists and tuples — cheap prepending, O(n) lookup. These properties make keyword lists a poor fit for large lookup tables but a great fit for their actual purpose: small, ordered sets of optional configuration passed into a function call.
Cricket analogy: A keyword list like [overs: 20, powerplay: 6, format: :t20] mirrors the ordered list of match rules read out at a T20 toss, where the same rule category could technically be restated, unlike a fixed scorecard field.
Keyword Lists as Function Options
Because the last argument of a function call that is a list of key: value pairs can be written without the surrounding brackets, Elixir functions widely accept an options keyword list as their final argument, e.g. String.split(str, ",", trim: true) or IO.inspect(value, limit: 50, pretty: true). Inside the function, Keyword.get/3, Keyword.fetch/2, and Keyword.get_values/2 (for duplicate keys) let you read those options safely with sensible defaults, which is exactly the pattern used throughout the standard library and frameworks like Ecto and Phoenix for things like changeset options or route configuration.
Cricket analogy: Keyword.get(opts, :powerplay, 6) mirrors a tournament organizer applying a default six-over powerplay unless a league explicitly overrides it in the rulebook.
Keyword Lists vs. Maps
The key distinctions from maps are ordering, duplicate keys, and lookup cost: keyword lists preserve the order you wrote them in and allow repeated keys (useful for things like multiple validate: rules or repeated plug: entries in a Phoenix router), while maps guarantee unique keys and O(1) average lookup but no defined ordering guarantee for iteration in the general case. As a rule, Elixir style favors keyword lists specifically for short, static, syntactically-nice option lists at call sites, and maps for everything else — larger data, data built or looked up at runtime, or data where key uniqueness matters.
Cricket analogy: A keyword list mirrors the specific ordered instructions a captain gives at the toss, while a map mirrors the full player database looked up by name during team selection — order matters for the former, fast lookup for the latter.
# Keyword list literal and the equivalent tuple list
opts = [name: "Ada", role: :admin]
opts == [{:name, "Ada"}, {:role, :admin}] # true
# Trailing keyword list can drop the brackets
String.split("a, b,, c", ",", trim: true)
def connect(host, opts \\ []) do
timeout = Keyword.get(opts, :timeout, 5000)
ssl = Keyword.get(opts, :ssl, false)
IO.puts("Connecting to #{host} (timeout: #{timeout}, ssl: #{ssl})")
end
connect("db.internal", timeout: 10_000, ssl: true)
# Duplicate keys are preserved, unlike in a map
rules = [validate: :required, validate: :min_length]
Keyword.get_values(rules, :validate) # [:required, :min_length]Elixir's own syntax leans on keyword lists heavily: if/else/end blocks, case clauses, and do/end blocks all desugar into keyword list arguments like [do: ..., else: ...] under the hood, which is part of why keyword lists get special bracket-dropping syntax as a function's final argument.
Keyword.get/2 on a keyword list with many entries is an O(n) linear scan, just like any list lookup. Don't use a keyword list as a large runtime lookup table — reach for a map once you're storing more than a handful of dynamically-built entries or need guaranteed O(1) access.
- A keyword list is a list of two-element {atom, value} tuples, written [key: value, ...].
- Keyword lists preserve order and allow duplicate keys, unlike maps.
- The trailing-argument bracket-dropping syntax makes keyword lists ideal for function options.
- Keyword.get/3, Keyword.fetch/2, and Keyword.get_values/2 are the main access functions.
- Elixir's own control-flow syntax (if, case, do/end) desugars into keyword lists.
- Lookup in a keyword list is O(n); use a map for large or frequently-looked-up data.
- Keyword lists are best for small, static, ordered option lists at call sites.
Practice what you learned
1. What is [name: "Ada", age: 30] equivalent to?
2. Which property distinguishes keyword lists from maps?
3. Why can the final keyword-list argument of a function call be written without square brackets?
4. What is the time complexity of Keyword.get/3 on a keyword list?
5. What Elixir constructs are internally implemented using keyword lists?
Was this page helpful?
You May Also Like
Maps in Elixir
Understand Elixir's key-value data structure, how to build, update, and pattern-match against maps, and when to reach for structs instead.
Lists and Tuples in Elixir
Learn how Elixir's two core sequential data structures — singly linked lists and fixed-size tuples — are represented in memory and when to use each one.
Protocols in Elixir
Learn how Elixir protocols provide polymorphism across data types, letting a single function like Enum.map or to_string dispatch differently for lists, maps, and your own structs.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics