We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
When working with Elixir, you might encounter an error when using default arguments in multiple function clauses. Letβs break down why this happens and how to fix it.
Consider the following Elixir code:
def change_post(%Post{id: nil} = post, attrs \\ %{}) do
Post.changeset(post, attrs) |> Ecto.Changeset.put_assoc(:taggings, [])
end
def change_post(%Post{} = post, attrs \\ %{}) do
Post.changeset(post, attrs)
end
At first glance, this looks fine. However, Elixir will raise an error because default arguments (\\ %{}
) are only allowed in a single function head. Defining them in multiple clauses is invalid.
To fix this, move the default argument to a single function head and delegate calls internally:
def change_post(post, attrs \\ %{})
def change_post(%Post{id: nil} = post, attrs) do
Post.changeset(post, attrs) |> Ecto.Changeset.put_assoc(:taggings, [])
end
def change_post(%Post{} = post, attrs) do
Post.changeset(post, attrs)
end
Why does this work?
- The first line (
def change_post(post, attrs \\ %{})
) ensures the default argument is only set once. - The subsequent clauses pattern match on
post
without redefining the default. - Elixir correctly applies the default argument when
attrs
is not provided.
Whenever you need multiple function clauses but also want a default argument, define the default once and delegate matching to separate clauses. This keeps your code clean, idiomatic, and error-free.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.