It’s main use is accessing a tuple value using an index, which works no matter the size of tuple and in context, where pattern matching is not an option. Just like there’s :erlang.map_get for maps, because pattern matching is not enough.
There’s places in OTP, where you might get differently sized tuples, where leading parts of them contain the same data. You can use elem/2 to select the common fields without needing to know which specific tuple you got if the differenciation doesn’t matter for the code. It also means your code doesn’t break if OTP decides to add another version of tuple with yet another additional datapoint added to the end.
If flag
timestamp,strict_monotonic_timestamp, ormonotonic_timestampis specified, the first tuple element istrace_tsinstead, and the time stamp is added as an extra element last in the message tuple.
Usually one would likely use maps for such a usecase, but sticking to tuples for performance sensitive calls like around tracing is also a good idea.
Also e.g. elixir’s record handling code wouldn’t be a lot more complex macro magic without having such functionality. Technically it doesn’t use Kernel.elem/2, but it optimizes by calling :erlang.element/2 directly, which is also what Kernel.elem/2 is using.






















