Elixirでは普段何気なくalias Hoge.{A, B}みたいに書いていますが、このaliasにしか出てこないHoge.{A, B}という構文は文法的にどういう意味になっているのでしょうか?

quoteして構文木を見てみると、Hoge.{A, B}Hoge.{}/2という関数呼び出しに相当する構文らしいということがわかります。

iex(11)> quote do Mod.func(a, b) end
{{:., [], [{:__aliases__, [alias: false], [:Mod]}, :func]}, [],
 [{:a, [], Elixir}, {:b, [], Elixir}]}
iex(12)> quote do Mod.{a, b} end
{{:., [], [{:__aliases__, [alias: false], [:Mod]}, :{}]}, [],
 [{:a, [], Elixir}, {:b, [], Elixir}]}

ということは、Hoge.{}/2を定義することができれば、Hoge.{A, B}を意味のある式にすることができます。

以下のように、通常のdefでは{}という名前の関数を定義することはできません。

iex(9)> defmodule Invalid do
...(9)>   def {}(a, b) do
...(9)>     a + b
...(9)>   end
...(9)> end
** (SyntaxError) iex:10: syntax error before: '('

しかし、マクロを使って無理やり構文木をねじ込めば、{}も定義できるのではないでしょうか?

そのために、まずは通常の関数定義がどのような構文木になるのかを調べてみます。

iex(13)> quote do def func(a, b) do c end end
{:def, [context: Elixir, import: Kernel],
 [
   {:func, [context: Elixir], [{:a, [], Elixir}, {:b, [], Elixir}]},
   [do: {:c, [], Elixir}]
 ]}

これを参考にして、以下のようなマクロdefbracesを作ります。このマクロは、

defbraces do
  def hoge1(x), do: ...
  def hoge2(x, y), do: ...
  ...
end

というようにdefbracesを呼び出した時に、その中にある全てのdefの関数名を{}で書き換えた構文木を元の位置に挿入するマクロとなります。

このマクロの実装自体は、以下のように簡単に行うことができます。

# defbraces.ex
defmodule DefBraces do
  defp replace_def_func_name(
    {:def, def_opts, [{_func_name, func_opts, args} | rest_def]},
    new_func_name
  ) do
    {:def, def_opts, [{new_func_name, func_opts, args} | rest_def]}
  end

  defmacro defbraces [do: do_block] do
    defs = case do_block do
             {:def, _, _} -> [do_block]
             {:__block__, _, defs} -> defs
           end
    defs
    |> Enum.map(&replace_def_func_name(&1, :{}))
  end
end

これを実際に使ったコードも書いてみます。

# use_defbraces.ex
defmodule UseDefBraces do
  require DefBraces

  DefBraces.defbraces do
    def braces(a), do: a
    def braces(a, b), do: a + b
    def braces(a, b, c), do: a + b + c
  end
end

これを実行すると、実際に{}/1, {}/2, {}/3が定義されており、UseDefBraces.{a, b}のような形で呼び出せることが分かります。

iex(4)> c("defbraces.exs")
[DefBraces]
iex(5)> c("use_defbraces.exs")
[UseDefBraces]
iex(6)> UseDefBraces.{3}
3
iex(7)> UseDefBraces.{3, 4}
7
iex(8)> UseDefBraces.{3, 4, 5}
12

このように、一応Hoge.{A, B}のような形の式に意味を持たせることはできるようです。まともな使い道があるかどうかは分かりませんが……。