verilog

verilog

Macros - how are they different to functions? When should they be used? How do they differ to C's macros?

Hello, I’m new to Elixir.
I was reading about the macros of Elixir but didn’t quite get it. I know C and familiar with its marcos.
Although I didn’t quite understand Elixir’s macros yet. Could you answer my basic questions about macros:

  1. What is the difference between functions and macros in Elixir?
  2. Why or when Should I use them?
  3. How they are different for C’s macros?

Most Liked

stefanchrobot

stefanchrobot

Re 1. Given:

my_thing(:some_param)

If my_thing is a macro, the line above will be evaluated at compilation time, otherwise it will be evaluated at run-time. Note that macro can invoke a function which means the function will be invoked at compilation time, which in turn means you can do all kinds of fancy and crazy stuff at compile-time.

Re 2. Use macros if functions are not enough to remove boilerplate. The line is blurry. Generally, avoid using macros.

Re 3. Elixir macros are safer (hygienic) and more powerful. They transform a piece of Elixir code into a different piece of Elixir code. The coolest thing is that the piece of code you’re working with is expressed as an Elixir data structure.

I highly recommend going through the blog series about macros by Saša Jurić.

NobbZ

NobbZ

C Macros are very similar to the “search and replace” function in your editor, as that is exactly how they are implemented. They are very dumb.

Elixir macros though are able to “understand” the arguments they got and produce completely different code for different arguments.

OvermindDL1

OvermindDL1

C Macro’s are indeed a templating engine, more similar to EEX than anything else, entirely textual and not AST aware at all. Elixir Macro’s are AST transformers, more like LISP macro’s, which is closer to C++ templates. Essentially an Elixir Macro is a function that executes at compile time to transform one AST form (whatever is passed in to it as an AST instead of as values) and returns a new AST to put in it’s place, and that continues resolving down until it is finally at the ‘base’ AST level and no more expansions can happen, which is then when it is compiled into Erlang.

easco

easco

C macros result in direct, textual replacement at the point the preprocessor encounters it. The preprocessor provides some simple flow control (e.g.#ifdef) but overall your ability to generate code from the Macro system is primitive and it is based on simple text substitution.

Elixir’s macro system allows you to use the full power of the language to write Elixir code. You can use conditionals, functions from the standard library, operations, etc… all to build Elixir code at compile time. So if you want to define a function in a module for each string from a list, it can be done.

stefanchrobot

stefanchrobot

Does it? Last time I used them it worked more like a templating engine. AFAIK Elixir macros can inspect the code in ways that is not possible in C. For example:

iex(1)> quote do  # when macros receive args, they are quoted; how does it look like?
...(1)>   1 + 2
...(1)> end
{:+, [context: Elixir, import: Kernel], [1, 2]}

iex(2)> defmodule Fun do
...(2)>   defmacro transform({:+, context, args}) do  # must return code in quoted form
...(2)>     {:-, context, args}  # flip the + into -; leave rest as-is
...(2)>   end
...(2)> end
iex(3)> require Fun  # we need to opt-in to use macros
iex(4)> Fun.transform(1 + 2)  # transforms 1 + 2 into 1 - 2
-1

Note that since the example happens in IEx, the expression 1 - 2 is instantly evaluated.

Where Next?

Popular in Questions Top

LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
Kagamiiiii
Student & New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New

We're in Beta

About us Mission Statement