Passing quoted form from macro to a function

I have been playing with macros lately. Besides the simple examples, this is pretty much the first time.

I tried to pass the “internal” representation of code from a macro to a function in the same module.

Eventually I did it a “clunky” way, but I was amazed at how difficult it was. (Yes, a large part of this is
just my ignorance.)

So: mymac8 can pass code to myfunc – but the first seven tries cannot.

Code below. Any/all insights appreciated.

Hal


###   testme.exs

require MacroPlayground
import MacroPlayground

i = 6
mymac8 i > 5   # This works ok -- versions 1-7 do not 


### MacroPlayground

defmodule MacroPlayground do
  def myfunc(expr) do
    IO.puts "func1: expr inspected = #{inspect expr}"
  end

  defmacro mymac1(expr) do
    IO.puts "mymac1: expr inspected: #{inspect expr}"
    quote do
      IO.puts "mymac1 inside quote: expr inspected = #{inspect expr}"
      MacroPlayground.myfunc(expr)
    end
  end

  defmacro mymac2(expr) do
    IO.puts "mymac2: expr inspected: #{inspect expr}"
    quote do
      IO.puts "mymac2 inside quote: expr inspected = #{inspect expr}"
      MacroPlayground.myfunc(unquote expr)
    end
  end

  defmacro mymac3(expr) do
    IO.puts "mymac3: expr inspected: #{inspect expr}"
    quote do
      e1 = unquote expr
      IO.puts "mymac3 inside quote: e1 inspected = #{inspect e1}"
      MacroPlayground.myfunc(e1)
    end
  end

  defmacro mymac4(expr) do
    IO.puts "mymac4: expr inspected: #{inspect expr}"
    quote do
      e1 = expr
      IO.puts "mymac4 inside quote: e1 inspected = #{inspect e1}"
      MacroPlayground.myfunc(e1)
    end
  end

  defmacro mymac5(expr) do
    IO.puts "mymac5: expr inspected: #{inspect expr}"
    quote bind_quoted: [expr: expr] do
      IO.puts "mymac5 inside quote: expr inspected = #{inspect expr}"
      MacroPlayground.myfunc(expr)
    end
  end

  defmacro mymac6(expr) do
    IO.puts "mymac6: expr inspected: #{inspect expr}"
    quote bind_quoted: [e1: expr] do
      IO.puts "mymac6 inside quote: e1 inspected = #{inspect e1}"
      MacroPlayground.myfunc(e1)
    end
  end

  defmacro mymac7(expr) do
    IO.puts "mymac7: expr inspected: #{inspect expr}"
    e1 = expr
    quote do
      IO.puts "mymac7 inside quote: e1 inspected = #{inspect e1}"
      MacroPlayground.myfunc(e1)
    end
  end

  defmacro mymac8(expr) do
    IO.puts "mymac8: expr inspected: #{inspect expr}"
    e0 = Macro.to_string(expr)
    quote bind_quoted: [e1: e0] do
      e2 = Code.string_to_quoted(e1)
      IO.puts "mymac8 inside quote: e1 inspected = #{inspect e1}"
      IO.puts "mymac8 inside quote: e2 inspected = #{inspect e2}"
      MacroPlayground.myfunc(e2)
    end
  end
end

I would think the following comes close to what you are after:

defmodule MacroPlayground do
  def myfunc(expr) do
    IO.puts "func1: expr inspected = #{inspect expr}"
  end

  defmacro mymac1(expr) do
    IO.puts "mymac1: expr inspected: #{inspect expr}"
    MacroPlayground.myfunc(expr)
  end
end

A macro consumes AST and produces AST. Therefore no need to quote inside it if your intent is to pass the AST to the the target function.

Thanks very much. It seems obvious now
that you say this.

Almost midnight here, but I will look in the
morning.

Hal