Gonza
Object literals vs pattern matching or alternatives?
Hi! Quick question from a guy coming from Javascript:
Whenever I have to handle some conditional behavior, like ‘do something depending on a well-defined flag’, instead of using a switch/case construct or a bunch of if/else, I usually do something like this:
const thingDoers = {
thingOne: () => { /* do thing one */ },
thingTwo: () => { /* do thing two */ },
thingThree: () => { /* do thing three */ },
DEFAULT: () => { /* do default thing */ }
}
Then I just run thingDoers[flag || 'DEFAULT']() and it works for all cases. If I have to add an additional one, is just a matter of declaring a new function, no extra logic involved.
Is this an acceptable/common pattern in Elixir as well, or do we just pattern-match the thing? Is there a better / more idiosyncratic way of doing the same?
Marked As Solved
sodapopcan
Definitely pattern match.
This is a nice use of multi-head functions AFAIC:
def thing_do(:thing_one), do: # ...
def thing_do(:thing_two), do: # ...
def thing_do(:thing_three), do: # ...
def thing_do(_), do: # ...
thing_do(flag) # If `flag` is `nil` it'll hit the last (default) case
You can do the same thing with one function head and a case if you want. It’s the same thing at the end of the day.
Also Liked
Gonza
Thanks! Looks even cleaner (my main driver for rejecting switch/case and nested ifs)
I’m still learning about Elixir but I’m loving it every day a little more
sodapopcan
Definitely don’t shy away from case! It’s very commonly used in Elixir. It’s much different than JS’s switch since it deals exclusively with pattern matches (and of course doesn’t need to break).
sodapopcan
Unfortunately it is my first language ![]()
In any event, welcome to Elixir Forums!
sodapopcan
Just adding that your fall-through clause should probably be def thing_do(nil), do: # ... otherwise you could run into some subtle bugs. Since _ will match anything, thing_do(:thang_tree), for example, will successfully hit the default clause. You probably want things to just blow up in that case.
Gonza
Thanks for the input! That’s a subtle difference, yes, worthy of consideration.
In my particular case, I guess I’d usually just use _ because I’d want to catch all other cases and send them to a virtual black hole. In an express controller, for example, I do something like DEFAULT: () => res.json({success: false, code: 'UNKNOWN_PARAM'}) (just ignore the fact I’m supposed to check beforehand my flags, it’s just an example)
But I see the value in treating nil as a different thing too







