Type-strict signatures in "phx" generated code


I have noticed that new Phoenix “phx” generators produce more type-strict code than old “phoenix” generators. Like

old signature:
def changeset(struct, params \\ %{}) do
def changeset(%User{} = user, attrs) do


{:error, changeset} ->
{:error, %Ecto.Changeset{} = changeset} ->

I wonder what the reason behind these changes?
Is this the new Elixir code style?
Is Phoenix going to be more type-strict?


That’s not really all that helpful though, since now these matches will fail with a not so descriptive “match not found”, since it’s not a real type annotation.

It’s extremely helpful. It let’s you find bugs exactly at the call site instead of leaking a bad value down N layers into a function. Also, Elixir 1.5 gained improved function clause errors that will show you the value that didn’t match and all the clauses that it tried to match against. We made the change in the generators because the code is self documenting with the matches and more robust against bugs. For example, {:error, changeset} is a very loose term to return from an context interface. Imagine you later want to rate limit comments and return {:error, :rate_limited} back? Your web front-end needs to be able to handle the different return signatures now at every call site, whereas matching on the datastructures you expect to be returned ensures you are handling the values you expect to receive.


The second one makes sense but the first one (function head) feels like a bit of a hack to me. I’d rather use @spec and dialyzer.

1 Like

I would never consider pattern matching in a function head a “hack”, ever :slight_smile: