We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track

Elixir 1.18 ships with “type checking of function calls, alongside gradual inference of patterns and return types.”
I’m particularly excited about that because of the help the compiler can provide when changing return values for a function.
Consider the following two modules:
- A
MyCalendar
which has anensure_valid_week
function that returns:ok
or:error
if the week is less than 52 weeks. And,- An
Exercise
module that usesMyCalendar
to validate a week, returning a success or error message.defmodule MyCalendar do @weeks_in_a_year 52 def ensure_valid_week(value) when is_integer(value) do if value <= @weeks_in_a_year do :ok else :error end end end
defmodule Exercise do def do_something do week = 2 case MyCalendar.ensure_valid_week(week) do :ok -> "We did it!" :error -> "Oh, oh! That's not a valid week." end end end
It’s a contrived example, but I think you get the idea.
Now, what happens if we change the error return value in
ensure_valid_week
from:error
to{:error, :invalid_week}
, but we don’t update the pattern match in theExercise
module?defmodule MyCalendar do @weeks_in_a_year 52 def ensure_valid_week(value) when is_integer(value) do if value <= @weeks_in_a_year do :ok else + {:error, :invalid_week} - :error end end end
If we’re using Elixir 1.17, our compiler won’t tell us anything about the change. We hope our tests catch the error before we ship the code to production.
But if we’re using Elixir 1.18, when we compile, we get a beautiful warning:
$ mix compile Compiling 1 file (.ex) warning: the following clause will never match: :error because it attempts to match on the result of: MyCalendar.ensure_valid_week(week) which has type: dynamic(:ok or {:error, :invalid_week}) typing violation found at: │ 7 │ :error -> "Oh, oh! That's not a valid week." │ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ │ └─ lib/exercise.ex:7: Exercise.do_something/0
🤩 That’s a huge improvement that we, as Elixir users, get for free!
Of course, it’s not perfect yet. If we don’t reference the
MyCalendar
module directly, but instead make it the default argument that we can pass into the function (i.e. only making it one of the possible calendar implementations), then the compiler doesn’t know for sure that the:error
value won’t match.To see that, change the
MyCalendar.ensure_valid_week(week)
call and makeMyCalendar
the default argument for the function:defmodule Exercise do - def do_something do + def do_something(calendar \\ MyCalendar) do week = 2 - case MyCalendar.ensure_valid_week(week) do + case calendar.ensure_valid_week(week) do :ok -> "We did it!" :error -> "Oh, oh! That's not a valid week." end end end
Now,
mix compile
in Elixir 1.18 will not give us a warning.But that makes sense. It’s now possible to pass a
calendar
argument that does return ``:error-- so there are scenarios in which the
:errorpattern would match. The compiler just doesn't know anymore that
MyCalendar` is the only possible implementation.It would be amazing if the compiler could figure out what are all the call sites to
do_something/1
, calculate all their return values, and let us know if:error
is ever going to be returned. But I don’t know if that’s in the cards. For now, I’ll happily take the huuuuge improvement.
continue reading on www.elixirstreams.com
⚠️ This post links to an external website. ⚠️
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.