PragTob

PragTob

Hey everyone, this has been on my mind for some time and I’d love your input on it!

TLDR: I feel like maps are superioer for storing and working with configuration options as compared to keyword lists and am wondering what I might be missing :slight_smile:

So, in Elixir it seems like Keyword lists are the de facto standard for passing options around. It’s what Mix.Config does and sort of advocates, to my understanding. Also it is advocated in the guides

These characteristics are what prompted keyword lists to be the default mechanism for passing options to functions in Elixir

The special characteristics mentioned are:

  • Keys must be atoms
  • Keys are ordered, as specified by the developer.
  • Keys can be given more than once

While I agree that the first one is cool/important for options, I don’t see the value of the other two for options as I see them. Given options there is only ever one option and there should be one key/value pair for it (e.g. should this print a warning? How long should this run?) and I don’t care about the ordering of the keys as I just want to get my specific value.

I can clearly see the value of these properties (and therefore Keyword lists) for DSLs like Ecto (as mentioned in the docs as well) but not for options.

In practice I found keyword lists awkward to deal with when used as options. My two main pain points are:

  • keys might occur twice while I want exactly one (when I override the value of that one key I probably want it)
  • pattern matching is hard (you gotta match on the length of the list and the order of keys) - while I love to pattern match on configuration options

To elaborate on the last point, I found it to be quite nice to pattern match on configuration options to handle them which reads very nice imo:

  defp print_configuration_information(_, %{print: %{configuration: false}}) do
    nil
  end
  defp print_configuration_information(jobs, config) do
    # do printing magic
  end

This is also why I use maps for configuration in benchee.

So in short, I feel like maps are superior for storing and working with configuration options but at the same time I somehow feel like I’m not writing idiomatic elixir and that I’m missing some great advantage of keyword lists.

Opinions/Advice/Insights? :slight_smile:

Thanks!
Tobi

Showing Posts 1 to 9

dsissitka

dsissitka

Have you seen how, for example, System.cmd/3 does it?

https://github.com/elixir-lang/elixir/blob/87710cd49521fc396f3f04fa8615f05e7f57ecc0/lib/elixir/lib/system.ex#L578-L603

josevalim

josevalim

Creator of Elixir

There are situations where the latter two properties are very handy. Ecto’s query syntax and Elixir’s OptionParser are situations where you need both. The import special form also leverages the last property (keys can be given more than once). I am pretty sure there are more examples but those are three from the top of my mind.

One of the reasons I also like to use keywords list for options is because we have a well defined dichotomy where keyword lists are used for incomplete sets (you do not need to pass all keys) while maps expect all keys to be there. This allows me to use the assertive map.key syntax when using maps. It doesn’t need to be an OR choice though. I agree pattern matching on maps is really handy and for such cases I would likely accept a keyword list but convert it to a map with defaults:

map = Enum.into(user_options, %{key: "default", other_key: false, ...})

This way the API is consistent with Elixir and you can still leverage the map properties when you don’t care about duplicates nor ordering.

25
Post #2
bbense

bbense

This will sound terrible, but sometimes the biggest advantage of doing something is just because everybody else is doing it that way.

In particular, if you are supporting a public library going against the flow is going to lead to an endless stream of questions about keywords not working as options. You’d think programmers would be slightly better than most at reading documentation, but sadly programmers are just people. People as a rule don’t read documentation[1].

While this may seem like a little thing, it’s annoyances like this that sap your energy for supporting open software. It’s one thing to be paid to read man pages to people, it’s a whole 'nuther thing to do it for free in your spare time. Matz’s “principle of least surprise” that drove the design of Ruby is a valuable lesson.

Compared to Elixir, Ruby had terrible documentation for a large part of it’s early history, yet it thrived despite that. One of the reasons for this is that you’d just try the obvious thing and 90% of the time, it would just work.

[1]- Actually this is not true, there’s just always a significant percentage that don’t and seem much a much larger percentage than they really are.

sotojuan

sotojuan

Yeah I agree. Phoenix and Elixir both use Keyword Lists so I do as well.

PragTob

PragTob OP

Thank you all for your answers! I think I’ll play with converting keyword lists to maps for internal use, that seems like a good solution :slight_smile: Also thanks for arguing for using the Elixir standard against what I might prefer and the way System.cmd/3 deals with the problem - you’ve all been very helpful (as always!) :smiley:

BartOtten

BartOtten

The Erlang Team has changed the default in favor of maps. Not sure if Elixir will follow.

10
Post #6
PragTob

PragTob OP

bit late but thanks for passing this along, very interesting and good to know!

BartOtten

BartOtten

In his talk at the virtual DevsForUkraine conference, José Valim addressed the question.

TLDL; he still favors lists

But when we want him to reconsider, all we need to say is: José, I think there is a performance issue with using lists for config. He will then benchmark it extensively, re-read every line involved, find 4 unrelated bugs, write fixes, push them to master and finally answer. All within 15 minutes.

PragTob

PragTob OP

Thanks for summarizing it!

I was actually the one asking José that question there, thanks to this thread :grin:

Link to the moment in the Q&A for future reference: https://www.youtube.com/watch?v=2Vhd5fw59UY&t=1116s

As a bit of input here, I don’t think performance is or will be an issue. Even erlang maps are internally represented as lists until there is a map size of 32 iirc. Reason being, hashing is expensive and so for small maps a linear search is actually faster. Since I don’t hope many people pass along more than 30 (I hope more than 5) options, performance should be the same/comparable.

— All posts loaded —

Where Next? Top

Trending in Discussions Top

cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
achempion
I’ve been using Emacs as my main code editor for more than a two years. It’s a custom build version although I’ve tried doom emacs and sp...
New
axelson
Hi there! :wave: @frigidcode and I (but mostly him) have been running an Elixir Book club, we’re almost done with Designing Elixir Syste...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
georgeguimaraes
Just published claude-code-elixir, a plugin marketplace for Claude Code with Elixir support. These are the plugins I’ve been using for my...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews