Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang vs Elixir Macros

Tags:

erlang

elixir

I have came across some Erlang code which I am trying to convert to Elixir to help me learn both of the languages and understand the differences. Macros and metaprogramming in general is a topic I am still trying to get my head around, so hopefully you will understand my confusion.

The Erlang code

-define(p2(MAT, REP), 
        p2(W = MAT ++ STM) -> m_rep(0, W, STM, REP))

% where m_rep is a function already defined.

To me, it seems that in the above code, there is two separate definitions of the p2 macro that map to a private function called m_rep. In Elixir though, it seems that it is only possible to have one pattern matching definition. Is it possible to have different ones in Elixir too?

like image 556
plotplot Avatar asked Jan 28 '16 11:01

plotplot


People also ask

Is Elixir better than Erlang?

In terms of concurrency support, Elixir is preferred by the developers over Erlang. In terms of ease of application, fault-tolerant mechanism and distributed applications, Elixir is preferred mostly in the current environment.

Is Elixir faster than Erlang?

Yes! Elixir is slightly slower because we dispatch to Enum. reduce and Erlang doesn't perform a remote call.

When should I use Elixir macros?

So write macros responsibly. Elixir already provides mechanisms to write your everyday code in a simple and readable fashion by using its data structures and functions. Macros should only be used as a last resort. Remember that explicit is better than implicit.

What is macro in Erlang?

A macro is defined as follows: -define(Const, Replacement). -define(Func(Var1,...,VarN), Replacement). A macro definition can be placed anywhere among the attributes and function declarations of a module, but the definition must come before any usage of the macro.

What is the difference between elixir and Erlang?

Elixir offers more flexibility than Erlang. You can assign the same variable more than once in Elixir, however, Erlang doesn’t allow that. The focus on reducing programming errors: Elixir reduces the number of programming errors by its very design.

What is Elixir programming language?

Elixir runs on the Erlang Virtual Machine, and it’s a general-purpose programming language. This open-source language emphasizes on functional programming, concurrency, and fault tolerance. This dynamically-typed language features several similarities with Erlang.

What are the advantages of Erlang?

You can get several advantages if you use Erlang, and these are as follows: Ease-of-use: Erlang values simplicity. This language uses the functional programming paradigm, which encourages simplicity. Erlang goes further since its syntax allows simpler programming.

What is the best framework for Elixir?

Most developers coding in Elixir use Phoenix, a powerful framework that uses several features of Ruby on Rails. The other popular open-source frameworks for this language are as follows: Joe Armstrong, Robert Virding, and Mike Williams created Erlang as a proprietary software of Ericsson.


2 Answers

These are not two definitions. The first line is the macro, the second line is the replacement. The confusing bit is that the macro has the same name as the function for which it is generating clauses. For example when using your macro like this:

?p2("a", "b");
?p2("c", "d").

the above will be expanded to:

p2(w = "a" ++ stm) -> m_rep(0, w, stm, "b");
p2(w = "c" ++ stm) -> m_rep(0, w, stm, "d").

You can use erlc -P to produce a .P file that will show you the effects of macro expansion on your code. Check out this slightly simpler, compilable example:

-module(macro).
-export([foo/1]).

-define(foo(X),
        foo(X) -> X).

?foo("bar");
?foo("baz");
?foo("qux").

Using erlc -P macro.erl you will get the following output to macro.P:

-file("macro.erl", 1).

-module(macro).

-export([foo/1]).

foo("bar") ->
    "bar";
foo("baz") ->
    "baz";
foo("qux") ->
    "qux".

In Elixir you can define multiple function clauses using macros as well. It is more verbose, but I think it is also much clearer. The Elixir equivalent would be:

defmodule MyMacros do
  defmacro p2(mat, rep) do
    quote do
      def p2(w = unquote(mat) ++ stm) do
        m_rep(0, w, stm, unquote(rep))
      end
    end
  end
end

which you can use to define multiple function clauses, just like the erlang counterpart:

defmodule MyModule do
  require MyMacros

  MyMacros.p2('a', 'b')
  MyMacros.p2('c', 'd')
end
like image 69
Patrick Oscity Avatar answered Oct 21 '22 12:10

Patrick Oscity


I can't help myself here. :-) If it's the macros you are after then using LFE (Lisp Flavoured Erlang) gives you much better macro handling than either erlang or elixir. It also is compatible with both.

like image 34
rvirding Avatar answered Oct 21 '22 12:10

rvirding