# `Macro`
[🔗](https://github.com/elixir-lang/elixir/blob/v1.20.0-rc.3/lib/elixir/lib/macro.ex#L7)

Functions for manipulating AST and implementing macros.

Macros are compile-time constructs that receive Elixir's AST as input
and return Elixir's AST as output.

Many of the functions in this module exist precisely to work with Elixir
AST, to traverse, query, and transform it.

Let's see a simple example that shows the difference between functions
and macros:

    defmodule Example do
      defmacro macro_inspect(value) do
        IO.inspect(value)
        value
      end

      def fun_inspect(value) do
        IO.inspect(value)
        value
      end
    end

Now let's give it a try:

    import Example

    macro_inspect(1)
    #=> 1
    #=> 1

    fun_inspect(1)
    #=> 1
    #=> 1

So far they behave the same, as we are passing an integer as argument.
But let's see what happens when we pass an expression:

    macro_inspect(1 + 2)
    #=> {:+, [line: 3], [1, 2]}
    #=> 3

    fun_inspect(1 + 2)
    #=> 3
    #=> 3

The macro receives the representation of the code given as argument,
while a function receives the result of the code given as argument.
A macro must return a superset of the code representation. See
`t:input/0` and `t:output/0` for more information.

To learn more about Elixir's AST and how to build them programmatically,
see `quote/2`.

> #### Evaluating code {: .tip}
>
> The functions in this module do not evaluate code. In fact,
> evaluating code from macros is often an anti-pattern. For code
> evaluation, see the `Code` module.

# `captured_remote_function`

```elixir
@type captured_remote_function() :: fun()
```

A captured remote function in the format of &Mod.fun/arity

# `escape_opts`

```elixir
@type escape_opts() :: [
  unquote: boolean(),
  prune_metadata: boolean(),
  generated: boolean()
]
```

# `input`

```elixir
@type input() ::
  input_expr() | {input(), input()} | [input()] | atom() | number() | binary()
```

The inputs of a macro

# `inspect_atom_opts`

```elixir
@type inspect_atom_opts() :: [{:escape, (binary(), char() -&gt; binary())}]
```

# `metadata`

```elixir
@type metadata() :: keyword()
```

A keyword list of AST metadata.

The metadata in Elixir AST is a keyword list of values. Any key can be used
and different parts of the compiler may use different keys. For example,
the AST received by a macro will always include the `:line` annotation,
while the AST emitted by `quote/2` will only have the `:line` annotation if
the `:line` option is provided.

The following metadata keys are public:

  * `:context` - Defines the context in which the AST was generated.
    For example, `quote/2` will include the module calling `quote/2`
    as the context. This is often used to distinguish regular code from code
    generated by a macro or by `quote/2`.

  * `:counter` - The variable counter used for variable hygiene. In terms of
    the compiler, each variable is identified by the combination of either
    `name` and `metadata[:counter]`, or `name` and `context`.

  * `:from_brackets` - Used to determine whether a call to `Access.get/3` is from
    bracket syntax.

  * `:from_interpolation` - Used to determine whether a call to `Kernel.to_string/1` is
    from interpolation.

  * `:generated` - Whether the code should be considered as generated by
    the compiler or not. This means the compiler and tools like Dialyzer may not
    emit certain warnings.

  * `:if_undefined` - How to expand a variable that is undefined. Set it to
    `:apply` if you want a variable to become a nullary call without warning
    or `:raise`

  * `:keep` - Used by `quote/2` with the option `location: :keep` to annotate
    the file and the line number of the quoted source.

  * `:line` - The line number of the AST node. Note line information is discarded
    from quoted code but can be enabled back via the `:line` option.

The following metadata keys are enabled by `Code.string_to_quoted/2`:

  * `:assoc` - contains metadata about the `=>` operator location in a
    map key-value AST node (when `:token_metadata` is true). This entry
    appears on map key nodes only

  * `:closing` - contains metadata about the closing pair, such as a `}`
    in a tuple or in a map, or such as the closing `)` in a function call
    with parens (when `:token_metadata` is true). If the function call
    has a do-end block attached to it, its metadata is found under the
    `:do` and `:end` metadata

  * `:column` - the column number of the AST node (when `:columns` is true).
    Note column information is always discarded from quoted code.

  * `:delimiter` - contains the opening delimiter for sigils, strings,
    and charlists as a string (such as `"{"`, `"/"`, `"'"`, and the like)

  * `:do` - contains metadata about the `do` location in a function call with
    `do`-`end` blocks (when `:token_metadata` is true)

  * `:end` - contains metadata about the `end` location in a function call with
    `do`-`end` blocks (when `:token_metadata` is true)

  * `:end_of_expression` - denotes when the end of expression effectively
    happens (when `:token_metadata` is true). This is only available for
    expressions inside "blocks of code", which are either direct children
    of a `__block__` or the right side of `->`. The last expression of the
    block does not have metadata if it is not followed by an end of line
    character (either a newline or `;`). This entry may appear multiple times
    in the same metadata if the expression is surround by parens

  * `:format` - set to `:keyword` when an atom is defined as a keyword.
    It may also be set to `:atom` to distinguish `nil`, `false`, and `true`

  * `:indentation` - indentation of a sigil heredoc

  * `:parens` - denotes a node was surrounded by parens for grouping.
    This entry may appear multiple times in the same metadata if
    multiple pairs are used for grouping

The following metadata keys are private:

  * `:alias` - Used for alias hygiene.
  * `:ambiguous_op` - Used for improved error messages in the compiler.
  * `:imports` - Used for import hygiene.
  * `:var` - Used for improved error messages on undefined variables.

Do not rely on them as they may change or be fully removed in future versions
of the language. They are often used by `quote/2` and the compiler to provide
features like hygiene, better error messages, and so forth.

If you introduce custom keys into the AST metadata, please make sure to prefix
them with the name of your library or application, so that they will not conflict
with keys that could potentially be introduced by the compiler in the future.

# `output`

```elixir
@type output() ::
  output_expr()
  | {output(), output()}
  | [output()]
  | atom()
  | number()
  | binary()
  | captured_remote_function()
  | pid()
```

The output of a macro

# `t`

```elixir
@type t() :: input()
```

Abstract Syntax Tree (AST)

# `camelize`

```elixir
@spec camelize(String.t()) :: String.t()
```

Converts the given string to CamelCase format.

This function was designed to camelize language identifiers/tokens,
that's why it belongs to the `Macro` module. Do not use it as a general
mechanism for camelizing strings as it does not support Unicode or
characters that are not valid in Elixir identifiers.

## Examples

    iex> Macro.camelize("foo_bar")
    "FooBar"

    iex> Macro.camelize("foo/bar")
    "Foo.Bar"

If uppercase characters are present, they are not modified in any way
as a mechanism to preserve acronyms:

    iex> Macro.camelize("API.V1")
    "API.V1"
    iex> Macro.camelize("API_SPEC")
    "API_SPEC"

# `classify_atom`
*since 1.14.0* 

```elixir
@spec classify_atom(atom()) :: :alias | :identifier | :quoted | :unquoted
```

Classifies an `atom` based on its possible AST placement.

It returns one of the following atoms:

  * `:alias` - the atom represents an alias

  * `:identifier` - the atom can be used as a variable or local function
    call (as well as be an unquoted atom)

  * `:unquoted` - the atom can be used in its unquoted form,
    includes operators and atoms with `@` in them

  * `:quoted` - all other atoms which can only be used in their quoted form

Most operators are going to be `:unquoted`, such as `:+`, with
some exceptions returning `:quoted` due to ambiguity, such as
`:"::"`. Use `operator?/2` to check if a given atom is an operator.

## Examples

    iex> Macro.classify_atom(:foo)
    :identifier
    iex> Macro.classify_atom(Foo)
    :alias
    iex> Macro.classify_atom(:foo@bar)
    :unquoted
    iex> Macro.classify_atom(:+)
    :unquoted
    iex> Macro.classify_atom(:Foo)
    :unquoted
    iex> Macro.classify_atom(:"with spaces")
    :quoted

# `compile_apply`
*since 1.16.0* 

Applies a `mod`, `function`, and `args` at compile-time in `caller`.

This is used when you want to dynamically invoke a function at
compile-time and force it to be tracked as a compile-time dependency.
For example, this is used by `dbg/1` to force the `dbg_callback`
configuration to be a compile-time dependency.

If you want to "invoke" a macro instead, remember macros are by
definition compile-time, and you can use `Macro.expand/2`.

# `dbg`
*since 1.14.0* 

```elixir
@spec dbg(t(), t(), Macro.Env.t()) :: t()
```

Default backend for `Kernel.dbg/2`.

This function provides a default backend for `Kernel.dbg/2`. See the
`Kernel.dbg/2` documentation for more information.

This function:

  * prints information about the given `env`
  * prints information about `code` and its returned value (using `opts` to inspect terms)
  * returns the value returned by evaluating `code`

You can call this function directly to build `Kernel.dbg/2` backends that fall back
to this function.

This function raises if the context of the given `env` is `:match` or `:guard`.

# `decompose_call`

```elixir
@spec decompose_call(t()) :: {atom(), [t()]} | {t(), atom(), [t()]} | :error
```

Decomposes a local or remote call into its remote part (when provided),
function name and argument list.

Returns `:error` when an invalid call syntax is provided.

## Examples

    iex> Macro.decompose_call(quote(do: foo))
    {:foo, []}

    iex> Macro.decompose_call(quote(do: foo()))
    {:foo, []}

    iex> Macro.decompose_call(quote(do: foo(1, 2, 3)))
    {:foo, [1, 2, 3]}

    iex> Macro.decompose_call(quote(do: Elixir.M.foo(1, 2, 3)))
    {{:__aliases__, [], [:Elixir, :M]}, :foo, [1, 2, 3]}

    iex> Macro.decompose_call(quote(do: 42))
    :error

    iex> Macro.decompose_call(quote(do: {:foo, [], []}))
    :error

# `escape`

```elixir
@spec escape(term(), escape_opts()) :: t()
```

Recursively escapes a value so it can be inserted into a syntax tree.

## Examples

    iex> Macro.escape(:foo)
    :foo

    iex> Macro.escape({:a, :b, :c})
    {:{}, [], [:a, :b, :c]}

    iex> Macro.escape({:unquote, [], [1]}, unquote: true)
    1

## Options

  * `:unquote` - when `true`, this function leaves `unquote/1` and
    `unquote_splicing/1` expressions unescaped, effectively unquoting
    the contents on escape. This option is useful only when escaping
    ASTs which may have quoted fragments in them. Note this option
    will give a special meaning to `quote`/`unquote` nodes, which need
    to be valid AST before escaping. Defaults to `false`.

  * `:prune_metadata` - when `true`, removes most metadata from escaped AST
    nodes. Note this option changes the semantics of escaped code and
    it should only be used when escaping ASTs. Defaults to `false`.

  * `:generated` - (since v1.19.0) Whether the AST should be considered as generated
    by the compiler or not. This means the compiler and tools like Dialyzer may not
    emit certain warnings.

    As an example for `:prune_metadata`, `ExUnit` stores the AST of every
    assertion, so when an assertion fails we can show code snippets to users.
    Without this option, each time the test module is compiled, we would get a
    different MD5 of the module bytecode, because the AST contains metadata,
    such as counters, specific to the compilation environment. By pruning
    the metadata, we ensure that the module is deterministic and reduce
    the amount of data `ExUnit` needs to keep around. Only the minimal
    amount of metadata is kept, such as `:line`, `:no_parens` and `:delimiter`.

## Comparison to `quote/2`

The `escape/2` function is sometimes confused with `quote/2`,
because the above examples behave the same with both. The key difference is
best illustrated when the value to escape is stored in a variable.

    iex> Macro.escape({:a, :b, :c})
    {:{}, [], [:a, :b, :c]}
    iex> quote do: {:a, :b, :c}
    {:{}, [], [:a, :b, :c]}

    iex> value = {:a, :b, :c}
    iex> Macro.escape(value)
    {:{}, [], [:a, :b, :c]}

    iex> quote do: value
    {:value, [], __MODULE__}

    iex> value = {:a, :b, :c}
    iex> quote do: unquote(value)
    ** (ArgumentError) tried to unquote invalid AST: {:a, :b, :c}
    Did you forget to escape term using Macro.escape/1?

`escape/2` is used to escape *values* (either directly passed or variable
bound), while `quote/2` produces syntax trees for
expressions.

## Dealing with references and other runtime values

Macros work at compile-time and therefore `Macro.escape/1` can only escape values
that are valid during compilation, such as numbers, atoms, tuples, maps, binaries,
etc.

However, you may have values at compile-time which cannot be escaped, such as
`reference`s and `pid`s, since the process or memory address they point to will
no longer exist once compilation completes. Attempting to escape said values will
raise an exception. This is a common issue when working with NIFs.

Luckily, Elixir v1.19 introduces a mechanism that allows those values to be escaped,
as long as they are encapsulated by a struct within a module that defines the
`__escape__/1` function. This is possible as long as the reference has a natural
text or binary representation that can be serialized during compilation.

Let's imagine we have the following struct:

    defmodule WrapperStruct do
      defstruct [:ref]

      def new(...), do: %WrapperStruct{ref: ...}

      # efficiently dump to / load from binaries
      def dump_to_binary(%WrapperStruct{ref: ref}), do: ...
      def load_from_binary(binary), do: %WrapperStruct{ref: ...}
    end

Such a struct could not be used in module attributes or escaped with `Macro.escape/2`:

    defmodule Foo do
      @my_struct WrapperStruct.new(...)
      def my_struct, do: @my_struct
    end

    ** (ArgumentError) cannot inject attribute @my_struct into function/macro because cannot escape #Reference<...>

To address this, structs can re-define how they should be escaped by defining a custom
`__escape__/1` function which returns the AST. In our example:

    defmodule WrapperStruct do
      # ...

      def __escape__(struct) do
        # dump to a binary representation at compile-time
        binary = dump_to_binary(struct)
        quote do
          # load from the binary representation at runtime
          WrapperStruct.load_from_binary(unquote(Macro.escape(binary)))
        end
      end
    end

Now, our example above will be expanded as:

    def my_struct, do: WrapperStruct.load_from_binary(<<...>>)

When implementing `__escape__/1`, you must ensure that the quoted expression
will evaluate to a struct that represents the one given as argument.

# `expand`

```elixir
@spec expand(input(), Macro.Env.t()) :: output()
```

Receives an AST node and expands it until it can no longer
be expanded.

Note this function does not traverse the AST, only the root
node is expanded.

This function uses `expand_once/2` under the hood. Check
it out for more information and examples.

# `expand_literals`
*since 1.14.1* 

```elixir
@spec expand_literals(input(), Macro.Env.t()) :: output()
```

Expands all literals in `ast` with the given `env`.

This function is mostly used to remove compile-time dependencies
from AST nodes. In such cases, the given environment is usually
manipulated to represent a function:

    Macro.expand_literals(ast, %{env | function: {:my_code, 1}})

At the moment, the only expandable literal nodes in an AST are
aliases, so this function only expands aliases (and it does so
anywhere in a literal).

However, be careful when removing compile-time dependencies between
modules. If you remove them but you still invoke the module at
compile-time, Elixir will be unable to properly recompile modules
when they change.

# `expand_literals`
*since 1.14.1* 

```elixir
@spec expand_literals(t(), acc, (t(), acc -&gt; {t(), acc})) :: t() when acc: term()
```

Expands all literals in `ast` with the given `acc` and `fun`.

`fun` will be invoked with an expandable AST node and `acc` and
must return a new node with `acc`. This is a general version of
`expand_literals/2` which supports a custom expansion function.
Please check `expand_literals/2` for use cases and pitfalls.

# `expand_once`

```elixir
@spec expand_once(input(), Macro.Env.t()) :: output()
```

Receives an AST node and expands it once.

The following contents are expanded:

  * Macros (local or remote)
  * Aliases are expanded (if possible) and return atoms
  * Compilation environment macros (`__CALLER__/0`, `__DIR__/0`, `__ENV__/0` and `__MODULE__/0`)
  * Module attributes reader (`@foo`)

If the expression cannot be expanded, it returns the expression
itself. This function does not traverse the AST, only the root
node is expanded. The expansion happens as if it was expanded by
the Elixir compiler and therefore compilation tracers will be invoked
and deprecation warnings will be emitted during the expansion.

`expand_once/2` performs the expansion just once. Check `expand/2`
to perform expansion until the node can no longer be expanded.

## Examples

In the example below, we have a macro that generates a module
with a function named `name_length` that returns the length
of the module name. The value of this function will be calculated
at compilation time and not at runtime.

Consider the implementation below:

    defmacro defmodule_with_length(name, do: block) do
      length = length(Atom.to_charlist(name))

      quote do
        defmodule unquote(name) do
          def name_length, do: unquote(length)
          unquote(block)
        end
      end
    end

When invoked like this:

    defmodule_with_length My.Module do
      def other_function, do: ...
    end

The compilation will fail because `My.Module` when quoted
is not an atom, but a syntax tree as follows:

    {:__aliases__, [], [:My, :Module]}

That said, we need to expand the aliases node above to an
atom, so we can retrieve its length. Expanding the node is
not straightforward because we also need to expand the
caller aliases. For example:

    alias MyHelpers, as: My

    defmodule_with_length My.Module do
      def other_function, do: ...
    end

The final module name will be `MyHelpers.Module` and not
`My.Module`. With `Macro.expand/2`, such aliases are taken
into consideration. Local and remote macros are also
expanded. We could rewrite our macro above to use this
function as:

    defmacro defmodule_with_length(name, do: block) do
      expanded = Macro.expand(name, __CALLER__)
      length = length(Atom.to_charlist(expanded))

      quote do
        defmodule unquote(name) do
          def name_length, do: unquote(length)
          unquote(block)
        end
      end
    end

# `generate_arguments`
*since 1.5.0* 

```elixir
@spec generate_arguments(0, context :: atom()) :: []
@spec generate_arguments(pos_integer(), context) :: [{atom(), [], context}, ...]
when context: atom()
```

Generates AST nodes for a given number of required argument
variables using `Macro.var/2`.

Note the arguments are not unique. If you later on want
to access the same variables, you can invoke this function
with the same inputs. Use `generate_unique_arguments/2` to
generate unique arguments that can't be overridden.

## Examples

    iex> Macro.generate_arguments(2, __MODULE__)
    [{:arg1, [], __MODULE__}, {:arg2, [], __MODULE__}]

# `generate_unique_arguments`
*since 1.11.3* 

```elixir
@spec generate_unique_arguments(0, context :: atom()) :: []
@spec generate_unique_arguments(pos_integer(), context) :: [
  {atom(), [{:counter, integer()}], context},
  ...
]
when context: atom()
```

Generates AST nodes for a given number of required argument
variables using `Macro.unique_var/2`.

The second argument is generally the macro caller's module.

## Examples

    [var1, var2] = Macro.generate_unique_arguments(2, __CALLER__.module)

# `inspect_atom`
*since 1.14.0* 

```elixir
@spec inspect_atom(:literal | :key | :remote_call, atom(), inspect_atom_opts()) ::
  binary()
```

Inspects `atom` according to different source formats.

The atom can be inspected according to the three different
formats it appears in the AST: as a literal (`:literal`),
as a key (`:key`), or as the function name of a remote call
(`:remote_call`).

## Options

  * `:escape` - a two-arity function used to escape a quoted
    atom content, if necessary. The function receives the atom
    content as string and a quote delimiter character, which
    should always be escaped. By default the content is escaped
    such that the inspected sequence would be parsed as the
    given atom.

## Examples

### As a literal

Literals include regular atoms, quoted atoms, operators,
aliases, and the special `nil`, `true`, and `false` atoms.

    iex> Macro.inspect_atom(:literal, nil)
    "nil"
    iex> Macro.inspect_atom(:literal, :foo)
    ":foo"
    iex> Macro.inspect_atom(:literal, :<>)
    ":<>"
    iex> Macro.inspect_atom(:literal, :Foo)
    ":Foo"
    iex> Macro.inspect_atom(:literal, Foo.Bar)
    "Foo.Bar"
    iex> Macro.inspect_atom(:literal, :"with spaces")
    ":\"with spaces\""

### As a key

Inspect an atom as a key of a keyword list or a map.

    iex> Macro.inspect_atom(:key, :foo)
    "foo:"
    iex> Macro.inspect_atom(:key, :<>)
    "<>:"
    iex> Macro.inspect_atom(:key, :Foo)
    "Foo:"
    iex> Macro.inspect_atom(:key, :"with spaces")
    "\"with spaces\":"

### As a remote call

Inspect an atom the function name of a remote call.

    iex> Macro.inspect_atom(:remote_call, :foo)
    "foo"
    iex> Macro.inspect_atom(:remote_call, :<>)
    "<>"
    iex> Macro.inspect_atom(:remote_call, :Foo)
    "\"Foo\""
    iex> Macro.inspect_atom(:remote_call, :"with spaces")
    "\"with spaces\""

# `operator?`
*since 1.7.0* 

```elixir
@spec operator?(name :: atom(), arity()) :: boolean()
```

Returns `true` if the given name and arity is an operator.

## Examples

    iex> Macro.operator?(:not_an_operator, 3)
    false
    iex> Macro.operator?(:.., 0)
    true
    iex> Macro.operator?(:+, 1)
    true
    iex> Macro.operator?(:++, 2)
    true
    iex> Macro.operator?(:..//, 3)
    true

# `path`
*since 1.14.0* 

```elixir
@spec path(t(), (t() -&gt; as_boolean(term()))) :: [t()] | nil
```

Returns the path to the node in `ast` for which `fun` returns a truthy value.

The path is a list, starting with the node in which `fun` returns
a truthy value, followed by all of its parents.

Returns `nil` if `fun` returns only falsy values.

Computing the path can be an efficient operation when you want
to find a particular node in the AST within its context and then
assert something about it.

## Examples

    iex> Macro.path(quote(do: [1, 2, 3]), & &1 == 3)
    [3, [1, 2, 3]]

    iex> Macro.path(quote(do: [1, 2]), & &1 == 5)
    nil

    iex> Macro.path(quote(do: Foo.bar(3)), & &1 == 3)
    [3, quote(do: Foo.bar(3))]

    iex> Macro.path(quote(do: %{foo: [bar: :baz]}), & &1 == :baz)
    [
      :baz,
      {:bar, :baz},
      [bar: :baz],
      {:foo, [bar: :baz]},
      {:%{}, [], [foo: [bar: :baz]]}
    ]

# `pipe`

```elixir
@spec pipe(t(), t(), integer()) :: t()
```

Pipes `expr` into the `call_args` at the given `position`.

This function can be used to implement `|>` like functionality. For example,
`|>` itself is implemented as:

    defmacro left |> right do
      Macro.pipe(left, right, 0)
    end

`expr` is the AST of an expression. `call_args` must be the AST *of a call*,
otherwise this function will raise an error. As an example, consider the pipe
operator `|>/2`, which uses this function to build pipelines.

Even if the expression is piped into the AST, it doesn't necessarily mean that
the AST is valid. For example, you could pipe an argument to `div/2`, effectively
turning it into a call to `div/3`, which is a function that doesn't exist by
default. The code will raise unless a `div/3` function is locally defined.

# `postwalk`

```elixir
@spec postwalk(t(), (t() -&gt; t())) :: t()
```

This function behaves like `prewalk/2`, but performs a depth-first,
post-order traversal of quoted expressions.

# `postwalk`

```elixir
@spec postwalk(t(), any(), (t(), any() -&gt; {t(), any()})) :: {t(), any()}
```

This functions behaves like `prewalk/3`, but performs a depth-first,
post-order traversal of quoted expressions using an accumulator.

# `postwalker`
*since 1.13.0* 

```elixir
@spec postwalker(t()) :: Enumerable.t()
```

Returns an enumerable that traverses the  `ast` in depth-first,
post-order traversal.

## Examples

    iex> ast = quote do: foo(1, "abc")
    iex> Enum.map(Macro.postwalker(ast), & &1)
    [1, "abc", {:foo, [], [1, "abc"]}]

# `prewalk`

```elixir
@spec prewalk(t(), (t() -&gt; t())) :: t()
```

Performs a depth-first, pre-order traversal of quoted expressions.

Returns a new AST where each node is the result of invoking `fun` on each
corresponding node of `ast`.

## Examples

    iex> ast = quote do: 5 + 3 * 7
    iex> {:+, _, [5, {:*, _, [3, 7]}]} = ast
    iex> new_ast = Macro.prewalk(ast, fn
    ...>   {:+, meta, children} -> {:*, meta, children}
    ...>   {:*, meta, children} -> {:+, meta, children}
    ...>   other -> other
    ...> end)
    iex> {:*, _, [5, {:+, _, [3, 7]}]} = new_ast
    iex> Code.eval_quoted(ast)
    {26, []}
    iex> Code.eval_quoted(new_ast)
    {50, []}

# `prewalk`

```elixir
@spec prewalk(t(), any(), (t(), any() -&gt; {t(), any()})) :: {t(), any()}
```

Performs a depth-first, pre-order traversal of quoted expressions
using an accumulator.

Returns a tuple where the first element is a new AST where each node is the
result of invoking `fun` on each corresponding node and the second one is the
final accumulator.

## Examples

    iex> ast = quote do: 5 + 3 * 7
    iex> {:+, _, [5, {:*, _, [3, 7]}]} = ast
    iex> {new_ast, acc} = Macro.prewalk(ast, [], fn
    ...>   {:+, meta, children}, acc -> {{:*, meta, children}, [:+ | acc]}
    ...>   {:*, meta, children}, acc -> {{:+, meta, children}, [:* | acc]}
    ...>   other, acc -> {other, acc}
    ...> end)
    iex> {{:*, _, [5, {:+, _, [3, 7]}]}, [:*, :+]} = {new_ast, acc}
    iex> Code.eval_quoted(ast)
    {26, []}
    iex> Code.eval_quoted(new_ast)
    {50, []}

# `prewalker`
*since 1.13.0* 

```elixir
@spec prewalker(t()) :: Enumerable.t()
```

Returns an enumerable that traverses the  `ast` in depth-first,
pre-order traversal.

## Examples

    iex> ast = quote do: foo(1, "abc")
    iex> Enum.map(Macro.prewalker(ast), & &1)
    [{:foo, [], [1, "abc"]}, 1, "abc"]

# `quoted_literal?`
*since 1.7.0* 

```elixir
@spec quoted_literal?(t()) :: boolean()
```

Returns `true` if the given quoted expression represents a quoted literal.

Atoms and numbers are always literals. Binaries, lists, tuples,
maps, and structs are only literals if all of their terms are also literals.

## Examples

    iex> Macro.quoted_literal?(quote(do: "foo"))
    true
    iex> Macro.quoted_literal?(quote(do: {"foo", 1}))
    true
    iex> Macro.quoted_literal?(quote(do: {"foo", 1, :baz}))
    true
    iex> Macro.quoted_literal?(quote(do: %{foo: "bar"}))
    true
    iex> Macro.quoted_literal?(quote(do: %URI{path: "/"}))
    true
    iex> Macro.quoted_literal?(quote(do: URI.parse("/")))
    false
    iex> Macro.quoted_literal?(quote(do: {foo, var}))
    false

# `special_form?`
*since 1.7.0* 

```elixir
@spec special_form?(name :: atom(), arity()) :: boolean()
```

Returns `true` if the given name and arity is a special form.

# `struct!`

> This function is deprecated. Use Macro.struct_info!/2 instead.

# `struct_info!`
*since 1.18.0* 

```elixir
@spec struct_info!(module(), Macro.Env.t()) :: [
  %{
    :field =&gt; atom(),
    optional(:required) =&gt; boolean(),
    optional(:default) =&gt; term()
  }
]
```

Extracts the struct information.

This is useful when a struct needs to be expanded at
compilation time and the struct being expanded may or may
not have been compiled (including structs in the defined
under the module being compiled). For compiled modules,
it will invoke `module.__info__(:struct)`.

Calling this function also adds an export dependency on the
given struct.

It will raise `ArgumentError` if the struct is not available.

## Compatibility considerations

This function currently returns both `:required` and `:default`
entries for each field. While this naming is inconsistent
(a required field should not have a default), this is done for
backwards compatibility purposes.

In future releases, Elixir may introduce truly required struct
fields, the required field will be removed and default will be
present only if the field is optional. Your code should prepare
for such scenario accordingly.

# `to_string`

```elixir
@spec to_string(t()) :: String.t()
```

Converts the given expression AST to a string.

This is a convenience function for converting AST into
a string, which discards all formatting of the original
code and wraps newlines around 98 characters. See
`Code.quoted_to_algebra/2` as a lower level function
with more control around formatting.

If the AST contains invalid nodes, this function will
attempt to inspect them, to aid debugging, although
the elements won't be formatted accordingly.

## Examples

    iex> Macro.to_string(quote(do: foo.bar(1, 2, 3)))
    "foo.bar(1, 2, 3)"

# `to_string`

> This function is deprecated. Use Macro.to_string/1 instead.

```elixir
@spec to_string(t(), (t(), String.t() -&gt; String.t())) :: String.t()
```

Converts the given expression AST to a string.

The given `fun` is called for every node in the AST with two arguments: the
AST of the node being printed and the string representation of that same
node. The return value of this function is used as the final string
representation for that AST node.

This function discards all formatting of the original code.

## Examples

    Macro.to_string(quote(do: 1 + 2), fn
      1, _string -> "one"
      2, _string -> "two"
      _ast, string -> string
    end)
    #=> "one + two"

# `traverse`

```elixir
@spec traverse(t(), any(), (t(), any() -&gt; {t(), any()}), (t(), any() -&gt; {t(), any()})) ::
  {t(), any()}
```

Performs a depth-first traversal of quoted expressions
using an accumulator.

Returns a tuple where the first element is a new AST and the second one is
the final accumulator. The new AST is the result of invoking `pre` on each
node of `ast` during the pre-order phase and `post` during the post-order
phase.

## Examples

    iex> ast = quote do: 5 + 3 * 7
    iex> {:+, _, [5, {:*, _, [3, 7]}]} = ast
    iex> {new_ast, acc} =
    ...>  Macro.traverse(
    ...>    ast,
    ...>    [],
    ...>    fn
    ...>      {:+, meta, children}, acc -> {{:-, meta, children}, [:- | acc]}
    ...>      {:*, meta, children}, acc -> {{:/, meta, children}, [:/ | acc]}
    ...>      other, acc -> {other, acc}
    ...>    end,
    ...>    fn
    ...>      {:-, meta, children}, acc -> {{:min, meta, children}, [:min | acc]}
    ...>      {:/, meta, children}, acc -> {{:max, meta, children}, [:max | acc]}
    ...>      other, acc -> {other, acc}
    ...>    end
    ...>  )
    iex> {:min, _, [5, {:max, _, [3, 7]}]} = new_ast
    iex> [:min, :max, :/, :-] = acc
    iex> Code.eval_quoted(new_ast)
    {5, []}

# `underscore`

```elixir
@spec underscore(atom() | String.t()) :: String.t()
```

Converts the given argument to a string with the underscore-slash format.

The argument must either be an atom, representing an Elixir module,
or a string representing a module without the `Elixir.` prefix.

This function was designed to format language identifiers/tokens with the underscore-slash format,
that's why it belongs to the `Macro` module. Do not use it as a general
mechanism for underscoring strings as it does not support Unicode or
characters that are not valid in Elixir identifiers.

## Examples

    iex> Macro.underscore("FooBar")
    "foo_bar"

    iex> Macro.underscore("Foo.Bar")
    "foo/bar"

    iex> Macro.underscore(Foo.Bar)
    "foo/bar"

In general, `underscore` can be thought of as the reverse of
`camelize`, however, in some cases formatting may be lost:

    iex> Macro.underscore("SAPExample")
    "sap_example"

    iex> Macro.camelize("sap_example")
    "SapExample"

    iex> Macro.camelize("hello_10")
    "Hello10"

    iex> Macro.camelize("foo/bar")
    "Foo.Bar"

# `unescape_string`

```elixir
@spec unescape_string(String.t()) :: String.t()
```

Unescapes characters in a string.

This is the unescaping behaviour used by default in Elixir
single- and double-quoted strings. Check `unescape_string/2`
for information on how to customize the escaping map.

In this setup, Elixir will escape the following: `\0`, `\a`, `\b`,
`\d`, `\e`, `\f`, `\n`, `\r`, `\s`, `\t` and `\v`. Bytes can be
given as hexadecimals via `\xNN` and Unicode code points as
`\uNNNN` escapes.

This function is commonly used on sigil implementations
(like `~r`, `~s` and others), which receive a raw, unescaped
string, and it can be used anywhere that needs to mimic how
Elixir parses strings.

## Examples

    iex> Macro.unescape_string("example\\n")
    "example\n"

In the example above, we pass a string with `\n` escaped
and return a version with it unescaped.

# `unescape_string`

```elixir
@spec unescape_string(String.t(), (non_neg_integer() -&gt; non_neg_integer() | false)) ::
  String.t()
```

Unescapes characters in a string according to the given mapping.

Check `unescape_string/1` if you want to use the same mapping
as Elixir single- and double-quoted strings.

## Mapping function

The mapping function receives an integer representing the code point
of the character it wants to unescape. There are also the special atoms
`:newline`, `:unicode`, and `:hex`, which control newline, unicode,
and escaping respectively.

Here is the default mapping function implemented by Elixir:

    def unescape_map(:newline), do: true
    def unescape_map(:unicode), do: true
    def unescape_map(:hex), do: true
    def unescape_map(?0), do: ?0
    def unescape_map(?a), do: ?\a
    def unescape_map(?b), do: ?\b
    def unescape_map(?d), do: ?\d
    def unescape_map(?e), do: ?\e
    def unescape_map(?f), do: ?\f
    def unescape_map(?n), do: ?\n
    def unescape_map(?r), do: ?\r
    def unescape_map(?s), do: ?\s
    def unescape_map(?t), do: ?\t
    def unescape_map(?v), do: ?\v
    def unescape_map(e), do: e

If the `unescape_map/1` function returns `false`, the char is
not escaped and the backslash is kept in the string.

## Examples

Using the `unescape_map/1` function defined above is easy:

    Macro.unescape_string("example\\n", &unescape_map(&1))

# `unique_var`
*since 1.11.3* 

```elixir
@spec unique_var(var, context) :: {var, [{:counter, integer()}], context}
when var: atom(), context: atom()
```

Generates an AST node representing a unique variable
given by the atoms `var` and `context`.

Calling this function with the same arguments will
generate another variable, with its own unique counter.
See `var/2` for an alternative.

The second argument is generally the macro caller's module.

## Examples

    var = Macro.unique_var(:foo, __CALLER__.module)

# `unpipe`

```elixir
@spec unpipe(t()) :: [t()]
```

Breaks a pipeline expression into a list.

The AST for a pipeline (a sequence of applications of `|>/2`) is similar to the
AST of a sequence of binary operators or function applications: the top-level
expression is the right-most `:|>` (which is the last one to be executed), and
its left-hand and right-hand sides are its arguments:

    quote do: 100 |> div(5) |> div(2)
    #=> {:|>, _, [arg1, arg2]}

In the example above, the `|>/2` pipe is the right-most pipe; `arg1` is the AST
for `100 |> div(5)`, and `arg2` is the AST for `div(2)`.

It's often useful to have the AST for such a pipeline as a list of function
applications. This function does exactly that:

    Macro.unpipe(quote do: 100 |> div(5) |> div(2))
    #=> [{100, 0}, {{:div, [], [5]}, 0}, {{:div, [], [2]}, 0}]

We get a list that follows the pipeline directly: first the `100`, then the
`div(5)` (more precisely, its AST), then `div(2)`. The `0` as the second
element of the tuples is the position of the previous element in the pipeline
inside the current function application: `{{:div, [], [5]}, 0}` means that the
previous element (`100`) will be inserted as the 0th (first) argument to the
`div/2` function, so that the AST for that function will become `{:div, [],
[100, 5]}` (`div(100, 5)`).

# `update_meta`

```elixir
@spec update_meta(t(), (keyword() -&gt; keyword())) :: t()
```

Applies the given function to the node metadata if it contains one.

This is often useful when used with `Macro.prewalk/2` to remove
information like lines and hygienic counters from the expression
for either storage or comparison.

## Examples

    iex> quoted = quote line: 10, do: sample()
    {:sample, [line: 10], []}
    iex> Macro.update_meta(quoted, &Keyword.delete(&1, :line))
    {:sample, [], []}

# `validate`

```elixir
@spec validate(term()) :: :ok | {:error, term()}
```

Validates the given expressions are valid quoted expressions.

Check the type `t:Macro.t/0` for a complete specification of a
valid quoted expression.

It returns `:ok` if the expression is valid. Otherwise it returns
a tuple in the form of `{:error, remainder}` where `remainder` is
the invalid part of the quoted expression.

## Examples

    iex> Macro.validate({:two_element, :tuple})
    :ok
    iex> Macro.validate({:three, :element, :tuple})
    {:error, {:three, :element, :tuple}}

    iex> Macro.validate([1, 2, 3])
    :ok
    iex> Macro.validate([1, 2, 3, {4}])
    {:error, {4}}

# `var`

```elixir
@spec var(var, context) :: {var, [], context} when var: atom(), context: atom()
```

Generates an AST node representing the variable given
by the atoms `var` and `context`.

Note this variable is not unique. If you later on want
to access this same variable, you can invoke `var/2`
again with the same arguments. Use `unique_var/2` to
generate a unique variable that can't be overridden.

## Examples

In order to build a variable, a context is expected.
Most of the times, in order to preserve hygiene, the
context must be `__MODULE__/0`:

    iex> Macro.var(:foo, __MODULE__)
    {:foo, [], __MODULE__}

However, if there is a need to access the user variable,
nil can be given:

    iex> Macro.var(:foo, nil)
    {:foo, [], nil}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
