Why macros?

Macros make powerful language or syntax extensions, and thus metaprogramming, possible; for example, Rust has a regex! macro which allows for defining regular expressions in your program, which are compiled while your code is compiled. That way the regular expressions are verified and can be optimized at compile time, and so avoid runtime overhead.

Macros can capture repetitive or similar code patterns and replace them with other source code; the macro expands the original code into new code. This expansion happens early in compilation, before any static checking is done, so the resulting code is compiled together with the original code. In this sense, they much more resemble Lisp macros than C macros. Rust macros allow writing Don't Repeat Yourself ;(DRY) code, by factoring out the common parts of functions. But a macro is higher-level than a function, because a macro allows for generating the code for many functions at compile time.

So, as a Rust developer, you can also write your own macros, replacing repetitive code with much simpler code and thereby automating tasks. On the other side of the spectrum, this could even make it possible to write domain-specific languages. Macro coding follows a specific set of declarative pattern-based rules. Rust's macro system is also hygienic, which means no conflict is possible between variables used in the macro and variables outside the macro. Each macro expansion happens in a distinct syntax context, and each variable is tagged with the syntax context where it was introduced.

Macro code itself is harder to understand than normal Rust code, so it is not that easy to make. But on the other hand, you won't code macros every day; if a macro is tested, just use it. The full story of macro writing extends into advanced regions of Rust, but in the following sections we discuss the basic techniques for developing macros.