Correct, this code won’t:
iex(8)> defmodule My do
...(8)> defmacro go(fun) do
...(8)> quote do
...(8)> def hello(), do: unquote(Macro.escape(fun) )()
...(8)> end
...(8)> end
...(8)> end
{:module, My,
<<70, 79, 82, 49, 0, 0, 4, 188, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 152,
0, 0, 0, 17, 9, 69, 108, 105, 120, 105, 114, 46, 77, 121, 8, 95, 95, 105,
110, 102, 111, 95, 95, 7, 99, 111, 109, ...>>, {:go, 1}}
iex(9)>
nil
iex(10)> defmodule Test do
...(10)> require My
...(10)> My.go(fn() -> IO.puts "hello" end)
...(10)> end
** (CompileError) iex:12: invalid call {:fn, [line: 12], [{:->, [line: 12], [[], {{:., [line: 12], [{:__aliases__, [line: 12], [:IO]}, :puts]}, [line: 12], ["hello"]}]}]}()
iex:12: (module)
But not for the reason you think, it’s not that it is a function, because it’s not, it’s still only AST here, rather in go
:
fun
is:
{:fn, [],
[
{:->, [],
[
[],
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [], ["hello"]}
]}
]}
And thus Macro.escape(fun)
returns:
{:{}, [],
[
:fn,
[],
[
{:{}, [],
[
:->,
[],
[
[],
{:{}, [],
[
{:{}, [],
[
:.,
[],
[{:{}, [], [:__aliases__, [alias: false], [:IO]]}, :puts]
]},
[],
["hello"]
]}
]
]}
]
]}
The AST was escaped into even more AST, so with the unquote
that removes the outer AST layer into the ast, then that essentially becomes this code:
def hello(), do: {:fn, [],
[
{:->, [],
[
[],
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [], ["hello"]}
]}
]}()
Notice the ()
at the end, you are trying to ‘call’ a tuple, not a function, and ‘that’ is why it fails. 
EDIT: If you want to change your example to actually escaping a function, not ast, then just don’t make it a macro for the go
function:
iex(13)> defmodule My do
...(13)> def go(fun) do
...(13)> quote do
...(13)> def hello(), do: unquote(Macro.escape(fun) )()
...(13)> end
...(13)> end
...(13)> end
warning: redefining module My (current version defined in memory)
iex:13
{:module, My,
<<70, 79, 82, 49, 0, 0, 4, 176, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 146,
0, 0, 0, 17, 9, 69, 108, 105, 120, 105, 114, 46, 77, 121, 8, 95, 95, 105,
110, 102, 111, 95, 95, 7, 99, 111, 109, ...>>, {:go, 1}}
iex(14)> defmodule Test do
...(14)> require My
...(14)> My.go(fn() -> IO.puts "hello" end)
...(14)> end
** (ArgumentError) cannot escape #Function<0.79763921 in file:iex>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, PIDs and remote functions in the format &Mod.fun/arity
(elixir) src/elixir_quote.erl:114: :elixir_quote.argument_error/1
(elixir) src/elixir_quote.erl:136: :elixir_quote.escape/3
(elixir) lib/macro.ex:422: Macro.escape/2
iex:16: My.go/1
iex:16: (module)
Here it fails because it really can’t serialize a function. 
(Hmm, when were PID’s supported…)