Elixir
Metaprogramming with Macros
Write code that writes code at compile time.
By EZ4Code Team
macrometaprogrammingast
Code
# Macro: generates code at compile time
defmodule MyMacros do
defmacro unless(condition, do: block) do
quote do
if not unquote(condition), do: unquote(block)
end
end
defmacro my_if(cond, do: yes, else: no) do
quote do
case unquote(cond) do
true -> unquote(yes)
false -> unquote(no)
end
end
end
end
# Usage
import MyMacros
unless false do
IO.puts("This prints")
end
# Inspecting AST
ast = quote do: 1 + 2 * 3
IO.inspect(ast)
# {:+, [context: ...], [1, {:*, [...], [2, 3]}]}
# Macro that defines a function
defmodule Loggable do
defmacro deflogged(name, do: body) do
quote do
def unquote(name) do
IO.puts("Calling #{unquote(name)}")
result = unquote(body)
IO.puts("Result: #{inspect(result)}")
result
end
end
end
end
defmodule Example do
import Loggable
deflogged greet do
"Hello!"
end
endExplanation
Macros operate on ASTs (abstract syntax trees) at compile time — they receive code as data and return new code. quote wraps code as AST; unquote injects values into the AST. Macros are the foundation of Elixir's DSLs (Plug, Ecto, Phoenix routes). Use sparingly — they make code harder to debug. Always check macro hygiene rules.
More Elixir Snippets
Pattern Matching
Pattern matching is core to Elixir — used everywhere.
Pipe Operator
Chain function calls with the |> pipe operator.
Processes and Messages
Spawn lightweight processes and send messages.
GenServer
Build stateful server processes with GenServer behaviour.
Supervisors and OTP
Build fault-tolerant supervision trees.
Protocols and Enums
Polymorphism via protocols and the Enum module.