Rendering a payroll template In a project I decided to parse a file and create functions during compilation to speed up rendering of a payroll template. I had (or still have?) a hard time grasping macros in Elixir so I started experimenting in a smaller scale. This was the winner and it also worked out in the project:

defmodule Swapper do
  defmodule Helper do
    defmacro make_custom_swapper(name, left, right) do
      quote bind_quoted: [n: name, l: left, r: right] do
        def unquote(:"#{n}_swapper")(unquote(l)), do: unquote(r)
        def unquote(:"#{n}_swapper")(unquote(r)), do: unquote(l)
      end
    end
  end

  defmodule Maker do
    require Helper
    defmacro generate_multiple_custom_swappers(pairs) do
      quote do
        for {n,l,r} &lt;- unquote(pairs) do
          Helper.make_custom_swapper(n,l,r)
        end
      end
    end
  end
end

defmodule TestingGrounds do
  require Swapper.Maker
  require Swapper.Helper

  # testing Helper
  Swapper.Helper.make_custom_swapper(:lofa,:a,27)

  letters = String.split("abcdefghijklmnopqrstuvwxyz", "", trim: true)
  letter_swapper_list =
    for l &lt;- letters do
      {:letter, l, String.upcase(l)}
    end

  things_to_swap = [{:eclipse, "moon", "sun"}|letter_swapper_list]

  # the big guns
  Swapper.Maker.generate_multiple_custom_swappers(things_to_swap)
end


I'm glad that it works but getting to this solution involved adding more stuff where I got lucky. It feels exactly like this when I first discovered &amp;/1 that seemed like the solution to everything:

defmodule A do
  def massage(string) do
    string
    |&gt; (&amp;splitter/1).() # == splitter 
  end

  defp splitter(str) do
    str
    |&gt; String.split("")
  end
end
I like the simplicity of just using unquote at the module level to generate the defs, such as:


defmodule MyModule do
  def do_map_stuff(method, arg) do
    IO.inspect([method, arg])
  end

  Enum.each [:method1, :method2, :method3], fn method -&gt;
    def unquote(method)(map) when is_map(map) do
    do_map_stuff(unquote(method), map)
  end

    def unquote(method)(arg)  do
    do_map_stuff(unquote(method), arg)
    end
  end
end