The example above would fail because "unquote(a)" would be expanded when evaluating new_macro and since "a" is not available in there, it would generate an exception. On master, the code above works because "unquote(a)" is just expanded when sample is called. In other words, the unquote now always binds to the direct parent quote. This explains 1).
The second builds on top of this feature to allow easy function generation. Now we can do this:
Enum.each [foo: 1, bar: 2, baz: 3], fn { k, v } ->
def unquote(k)(arg) do
unquote(v) + arg
end
end
This works because def/2, defp/2 and friends now delegate to quote underneath so it supports unquote fragments on its definition.
Here is an example of how this helps cleaning up code:
Here is a commit that shows how we made defdelegate support the same feature:
In a way, this simulates free variables. It would be impractical to have free variables in Elixir per se, however by using this feature, we can get a similar result. Here is HashDict using this feature as if accessing variables defined in the module body as constants:
For more background info, feel free to check issue #880 on Github:
Please give it a try, there are surely some rough edges to handle.
José Valim
Skype: jv.ptec
Founder and Lead Developer