The snippets you are showing are not equivalent, but at least they are close enough to assume you are checking for the value of the the key stuff as well in version 1 to make them equivalent.
Iād go definitively with the top level pattern match. It does read mutch better in my opinion. Also some ides do list them as different functions in the overview which makes finding the correct piece of code much easier.
Also Iām not quite sure what you meant with handling the default case. The underscore does work in both situations.
Even if there is a clear preference to use function clauses in the community, case has its right to exist as well. Iād use a case, when I canāt pattern match on the functions arguments directly, but have to do some calculations first as in the following contrived example.
def foo(a, b) do
c = a - b
case c do
0 -> :equal
_ -> :inequal
end
end
Of course this particular example can be done with a pattern match as well, but I think you can see what I want to tell.
Thereās no real difference between the two approaches, so it comes down to a specific case and personal preferences. Personally, I use case if the function body will be small enough even with case. If there are more branches and/or thereās more additional code in the function, I move branching into a multiclause to keep the āmainā function code clear.
As a newbie, Iām finding myself gravitating toward the second style because it helps me quickly spot which code-body is relevant to the case Iām thinking about. It seems more scannable because the multiple defs signal that thereās no code between the arguments and the case.