TL;DR: Use String.to_atom/1
at compile time only.
In the Erlang VM, atoms are not garbage-collected. Because of that, unchecked creation of atoms can lead to memory leaks at best, and a crashed VM at worse. This has been widely discussed on the internet.
Both String.to_atom/1
and the :"string"
expression generate arbitrary atoms from strings.
Using these two techniques for converting a string to an atom can lead to the above-mentioned
problem.
Developers who know this try to minimize the risk of unbound creation of atoms. Typically, they do informal analysis of the code to determine whether it’s safe to convert arbitrary strings to atoms.
Instead of doing an analysis each time, try this heuristic:
- If the code in question is only evaluated at compile time, it may be safe to use
String.to_atom/1
. Informal analysis is still recommended however. - If the code in question is evaluated at runtime, use
String.to_existing_atom/1
. If you’re concerned it will crash because a string is given for a non-existing atom, then re-evaluate your design. It’s likely you have unbound creation of atoms. Consider that a bug in your code, and adjust your code to not rely on unbound atom creation.
Using the heuristic, I have been able to maintain a strict rule of never using
String.to_atom/1
at runtime. I’ve never had to make an
exception to this rule.