mcgingras

mcgingras

What is the "do" in a defmacro param?

Hello all,

I’ve been reading about metaprogramming and encountered examples that look like the following:
defmodule example(example_param, do: block)

I haven’t encountered syntax with the do param like that before, and I’ve been confused how that works. I have not been able to find much in the way of documentation since quite honestly I’m not even sure what to search for.

How does the caller pass the “block” to the function? What is this sort of syntax called?

Most Liked

Eiji

Eiji

@mcgingras If you do not understand some syntax you should check Syntax reference special documentation page.

Regarding your questions you should be especially interested in those sections:

Syntactic sugar

All of the constructs above are part of Elixir’s syntax and have their own representation as part of the Elixir AST. This section will discuss the remaining constructs that “desugar” to one of the constructs explored above. In other words, the constructs below can be represented in more than one way in your Elixir code and retain AST equivalence.

Source: Syntax reference — Elixir v1.20.2

Keywords

Keywords in Elixir are a list of tuples of two elements where the first element is an atom. Using the base constructs, they would be represented as:

[{:foo, 1}, {:bar, 2}]

However Elixir introduces a syntax sugar where the keywords above may be written as follows:

[foo: 1, bar: 2]

Source: Syntax reference — Elixir v1.20.2

Keywords as last arguments

Elixir also supports a syntax where if the last argument of a call is a keyword list then the square brackets can be skipped. This means that the following:

if(condition, do: this, else: that)

is the same as

if(condition, [do: this, else: that])

which in turn is the same as

if(condition, [{:do, this}, {:else, that}])

Source: Syntax reference — Elixir v1.20.2

do/end blocks

The last syntax convenience are do/end blocks. do/end blocks are equivalent to keywords as the last argument of a function call where the block contents are wrapped in parentheses. For example:

if true do
  this
else
  that
end

is the same as:

if(true, do: (this), else: (that))

Source: Syntax reference — Elixir v1.20.2

RudManusachi

RudManusachi

It’s nothing but the keyword list with key :do. The equivalent would be:
defmodule example(example_param, [{:do, block}])

And usually inside the macro you unquote the block.

if the last argument of a call is a keyword list then the square brackets can be skipped

See keywords as last arguments, followed by the section about do/end blocks

The other thing is elixir’s tokenizer treats do/end as an “expression” where end is a terminal “end of expression”.

mcgingras

mcgingras

Thank you! I wasn’t sure what to search within the reference material. “Keywords as last arguments” is exactly what I am looking for. Thanks so much for the help.

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
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
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: <h1>Create Post</h1> <%= ...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call t...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29603 241
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
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
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
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52673 488
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement