Potential regression with pattern matching inside default argument expressions

Hello,

I’ve come across a difference in behaviour between Elixir 1.9.4 and later Elixir versions (tested with 1.10, 1.10.4, 1.11.0, 1.11.2, 1.12, 1.12.3).

Reproduction

Here is a test module showing the issue:

defmodule TestDefaultArguments do
  def test(
        arg1,
        arg2 \\ (
          default = "default"
          default
        )
      ) do
    arg1 <> "-" <> arg2
  end
end

If you run then mix run -e "TestDefaultArguments.test(\"arg1\") |> IO.puts()":

  • On Elixir 1.9.4, you see the expected output arg1-default.
  • On later Elixir versions (tested on Elixir 1.10, 1.10.4, 1.11.0, 1.11.2, 1.12, 1.12.3), you see the following error message:
** (MatchError) no match of right hand side value: "default"
    (test_gettext 0.1.0) lib/test_gettext.ex:5: TestDefaultArguments.test/1
    (stdlib 3.14.2.2) erl_eval.erl:680: :erl_eval.do_apply/6
    (stdlib 3.14.2.2) erl_eval.erl:888: :erl_eval.expr_list/6
    (stdlib 3.14.2.2) erl_eval.erl:411: :erl_eval.expr/5
    (elixir 1.10.4) lib/code.ex:341: Code.eval_string_with_error_handling/3
    (elixir 1.10.4) lib/enum.ex:783: Enum."-each/2-lists^foreach/1-0-"/2

Details

I believe it’s something to do with the pattern match default = "default" within the default argument expression.

I came across this in a situation where the default argument expression is gettext("foo"). This is a macro which compiles down to:

(
  msgid = ManagerWeb.Gettext.dpgettext_noop("default", nil, "foo")
  Gettext.dpgettext(ManagerWeb.Gettext, "default", nil, msgid, %{})
)

And I get a similar error message:

** (MatchError) no match of right hand side value: "foo"

So what I care about doing is having the gettext call in the default argument expression, but I’ve tried to distill it down to what I think is going wrong.

My Question/Request

I know it’s possible to work around this by not having the gettext macro call in the default argument expression.

However, this is code that was working with Elixir 1.9.4, so I wanted to bring it up to check whether it is an expected change in behaviour, or if it is an unexpected regression?

Many thanks,
Steve

3 Likes