It seems that IEX is a specially case. I would appreciate some elucidation on what happens in IEX (with respect to AST injection) that allows unquote to accept invalid ASTs. I’d appreciate suggestions on how this feature could be leveraged for testing/scripting as well, if this was the goal.
Context
I read in the docs and in various books/guides that unquote must be passed a valid AST as it injects an AST where unquote is called.
The below is permitted in iex:
1.
iex(91)> quote do unquote %{}
...(91)> end
%{}
2.
iex(92)> quote do: unquote {1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}
3.
iex(93)> quote do
...(93)> first_var_in_block
...(93)> unquote {1, "hello", :pizza, 'world'}
...(93)> third_var_in_block
...(93)> end
{:__block__, [],
[
{:first_var_in_block, [], Elixir},
{1, "hello", :pizza, ~c"world"}, # <= Apparently invalid AST.
{:third_var_in_block, [], Elixir}
]}
Example number three, it can be seen that the evaluation was injected into the midst of the other AST fragments.
Edit:
It’s definitely evalling the arg, I thought it might be skipping it given IEX’s environment,
iex(95)> second_var = 9
9
iex(96)> quote do
...(96)> first_var_in_block
...(96)> unquote {1, "hello", :pizza, second_var}
...(96)> third
...(96)> end
{:__block__, [],
[
{:first_var_in_block, [], Elixir},
{1, "hello", :pizza, 9},
{:third, [], Elixir}
]}