However, before using the
*_to_existing_atom()functions, consider whether an explicit conversion is more appropriate. Quite often there are only a few atoms that are valid in the context the conversion is done, and in those cases it is better to translate them yourself and reject invalid inputs, as*_to_existing_atom()can return any atom that exists in the system, not just those expected in the context.
[…]%% DO, AND PREFER (see STL-001) input_to_atom(<<"foo">>) -> foo; input_to_atom(<<"bar">>) -> bar; input_to_atom(<<"quux">>) -> quux.
What I like about the explicit code approach is that it potentially decouples the text in the binary from the atom used internally. Externally, short is good. Internally, longer is clearer.
Things like processes and ETS tables should allow non-atoms as names
There’s hardly a situation when becomes a real limitation. Registering processes or tables to atoms can be thought as declaring global variables in C. C doesn’t let you declare global variables dynamically, and people live with such limitation just fine.
For processes one can use {via, gproc, ...}. For ETS tables instead of ets:lookup(list_to_atom(lists:concat([foo, Namespace])), Key) one can use ets:lookup(foo, {Namespace, Key}) or just use unnamed tables and pass references explicitly, etc.
All in all, to me the most important property of atoms is their internal representation as unboxed integers. The last thing I want to think about are corner cases where code like
{ok, Something} ?= ....
becomes 1% slower because internal representation of term ok somehow got poisoned by unrelated code doing stupid things with dynamic atoms, so the VM has to run some non-trivial logic with different internal representations to pattern-match this.