Handling options in Erlang/OTP APIs

In a recent pull request the question came up whether options should be given as a list of two-tuples or as a map. While we have discussed that question informally in the Erlang/OTP team, it had not been previously discussed in the OTP Technical Board.

In a recent OTB meeting we decided on the following rules for choosing the representation of options:

  • Never use a record for public APIs, because records require an include file and if elements are added to a record, all code using it must be re-compiled.

  • Use a map for options unless a map will not work for some (good) reason.

  • If a map does not work, use a list.

Briefly, the main motivation for avoiding lists unless necessary, is that given the option list [{use_foo,true}, {use_foo,false}] the value of the use_foo is not immediately clear. Existing OTP APIs that use options are not consistent in that regard. With maps, that ambiguity cannot arise.

This rule will be applied to new APIs. We might extend old APIs to accept maps as well as lists if we’ll need to add more options to an existing API (as was the case with the PR mentioned previously), or if we’ll think that using an option map would be a substantial improvement.

For more details see: Handling options in OTP APIs

19 Likes

100% :partying_face:

I would add two other advantages to using maps:

  1. It allows me to pattern match on options in a function head.

  2. AFAIK maps are more energy efficient.

10 Likes

Great to have this officially stated! I believe this has been unofficially done for quite some time. For example, child specs and options for supervisors. The peer module also uses this.

I wonder if there is any way to safely deprecate proplists over a course of 3-4 years. I’d really love to see this done for older APIs (especially those handling dozens of options).

8 Likes