Macros with same name and different arities?

I am trying to create two different macros with the same name and different arities. Plus one macro calls the other.

I am going in the right direction with this?

 defmacro inspector(item, label, opts \\ [])
    when is_binary(label) and is_list(opts) do
      quote do
        # do things
        inspector unquote(item), unquote(opts)
      end
  end

defmacro inspector(item, opts \\ []) when is_list(opts) do
   quote do 
       # do things
   end
 end

but I get this error

== Compilation error in file lib/clouseau.ex ==
** (CompileError) lib/clouseau.ex:18: defmacro inspector/2 conflicts with defaults from inspector/3
    lib/clouseau.ex:18: (module)
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
** (exit) shutdown: 1
    (elixir) lib/kernel/parallel_compiler.ex:325: Kernel.ParallelCompiler.terminate/1
    (elixir) lib/kernel/parallel_compiler.ex:65: Kernel.ParallelCompiler.spawn_compilers/3
    (mix) lib/mix/compilers/elixir.ex:159: Mix.Compilers.Elixir.compile_manifest/8
    (mix) lib/mix/compilers/elixir.ex:86: Mix.Compilers.Elixir.compile/6
    (mix) lib/mix/tasks/compile.elixir.ex:68: Mix.Tasks.Compile.Elixir.run/1
    (mix) lib/mix/task.ex:301: Mix.Task.run_task/3
    (elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2
    (elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2

It’s not about macro. When you use the default value like def inspector(item, label, opts \\ []), you actually defining two functions, namely inspector/3 and inspector/2.

So in your example, both of the macros defines inspect/2, which cause the confliction.

4 Likes

Thanks. I didn’t give much thought how functions with defaults are defined.