2
votes

Today while walking through some code I came across the following two function headers and realized that, as far as I can tell, they should be duplicates. Same number of parameters and no matches or guards to let us bypass the first one. But the compiler isn't giving me a warning that the second will never match. Any explanation why that would be?

  def update_display_cache(context, text, line_no, position, text, adjusted_text, _) do
  def update_display_cache(context, display_line, line_no, position, text, adjusted_text, _) do

I made a couple of simple functions with matching parameter lists, including one with the trailing _ parameter and they all gave the expected warning.
warning: this clause cannot match because a previous clause at line 24 always matches

I also copied and pasted the entire first function header and body without changes and still didn't get a warning.

Elixir 1.7.4

1
Just to be sure... is the function defined in the same module? And are you sure that things recompiled? (Sometimes removing the _build directory is the ultimate check) - Everett
Correct me if I'm wrong, but as far as I can see both functions have the same number of parameters with no guards helping to distinguish between them. - Guru Stron
The history of this apparently goes back several years through several modules, copied and pasted. Trust me, it's been recompiled! @GuruStron that is the point of the question. I see no difference between the headers except a name, so why doesn't the compiler warn me? - Sinc
@Sinc Yep, missed the "no" in question) - Guru Stron

1 Answers

8
votes

The param text appears two times in the first definition, adding the extra constraint that those two values have to be equal to match.

A simpler minimal example reproducing it:

  def equals?(a, a), do: true
  def equals?(_, _), do: false