amirOrbe
Default arguments best practices?
Hi everyone, I have a function with two parameters with default values something like:
def(param1 \\ %{}, param2 \\ "") do
###
end
this is the best practice for do that? or you know another way ?
Most Liked
zachdaniel
I’ve learned the hard way that if you ever have more than one optional argument its a smell and you should refactor it to an opts list ![]()
srcoulombe
You can also use functions from the Keyword module
def foo(opts \\ []) do
arg1 = Keyword.get(opts, :arg1, "default_value")
...
end
dimitarvp
Absolutely never do this. Your colleagues or even your own future self will forget or be in a hurry just once and introduce a bug that would be difficult to track down.
Either only one optional argument and it must 99% of the time be the last one – unless the differences in type will make it completely obvious if something goes wrong – or use a keyword list as others have said. That approach also allows you to easily name stuff f.ex.
do_stuff(repo, changeset, username: "amir", password: "nope", dob: ~D[2000-01-01])
zachdaniel
Sure, there is always the caveat of not breaking existing code. But “never do it if you can avoid it” I think is always implicit in this kind of advice. I don’t see how in top_n/4 the fourth arg only makes sense with the 3rd arg. Those both look like things I’d want to be able to specify independently.
I think for libraries who have to avoid breaking changes, you should begin with options lists over even a single optional argument, so that you never have this problem. In our own application code it’s a different story as we can update all callers when we change the function. Even still, all cases where I used to reach for optional args I now instead use options lists. All of the benefits, none of the downsides.
thiagomajesk
You have no idea how much I agree with this @zachdaniel, and it bites too many people in the butt too frequently. Maybe it should be part of the anti-patterns documentation!?
I’ve been working with Elixir for a long time now, how come I’ve missed this gem!? I surely must have overlooked it. Thanks for sharing!







