Support to unquote fragments pushed to master

187 views
Skip to first unread message

José Valim

unread,
Mar 11, 2013, 12:23:01 AM3/11/13
to elixir-l...@googlegroups.com
Hello everyone,

We have exciting news to share. I have pushed to master a couple fixes that allow:

1. Macros to define macros
2. Easy dynamic generation of functions

I will detail those two briefly.

In previous versions, Elixir always escaped unquoted contents, so if you had a macro that had to define another macro, like this:

    defmacro new_macro do
      quote do
        defmacro sample(a) do
          quote do
            unquote(a) + 1
          end
        end
      end
    end

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

jer...@jeremyhuffman.com

unread,
Mar 13, 2013, 10:25:28 PM3/13/13
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br
This all makes a lot of sense, but what is the advantage of the "constants" over using attributes? It seems more verbose:

-      expand_on: size * @node_size, contract_on: contract_on * @node_size) +      expand_on: size * unquote(node_size), contract_on: contract_on * unquote(node_size))

José Valim

unread,
Mar 17, 2013, 1:00:34 PM3/17/13
to elixir-l...@googlegroups.com
Hello Jeremy,

For now, it is indeed more verbose but adding an operator for unquote is not out of question in the future.

The advantage so far is simply to avoid naming conflicts since @attributes are also used for declaring documentation, annotating the module and more. Therefore, it looks to me that using variables feels more natural. And if it does become a common idiom, we can try to make it shorter. :)



José Valim
Skype: jv.ptec
Founder and Lead Developer


--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages