It doesn’t - you’re still thinking of them as separate functions. Start thinking of it as a single function where each clause adds another piece of a case expression (same name and arity - same function).
The interpreter simply tries the patterns in order (pattern matching is highly optimized on the BEAM). The first one that succeeds has its expression evaluated (which becomes the return value).
If none succeeds the process crashes because it can’t find a match - that is the problem you experienced in your opening post.
https://elixir-lang.org/getting-started/modules-and-functions.html#named-functions
Function declarations also support guards and multiple clauses.