Elixir is based on functions in functions in functions.

Functions have a complicated syntax. To simplify them, the functions are organized into “macros” by defmacro.

Macros are evaluated at compile time and must return quote expression.

These are then used to define constants and DSLs. But macros are really just reused functions.


quote substitutes {function, metadata, arguments} usually {Expression, Modules, Nested Expressions}

quote translates whatever is in it as AST which has precedence.

quote do 
  1 + (2 - 3)

is translated as AST:

{:+, [...], [1, {:-, [...], [2,3]}]}

quote do: variable translates to `{:variable, [], Elixir}``

Quoted literals return themselves

quote do: "hey"
# "hey"


String interpolation inside quotes

n = 12

quote do: 1 + unquote(n)
# {:+, [context: Elixir, imports: [{1, Kernel}, {2, Kernel}]], [1, 12]}

Macro.to_string – converts the long macro to its string version


defmacro my_if do


defmacro using(which) when is_atom(which) do apply(MODULE, which, []) end