In the previous century, many languages featured a preprocessor (most prominently, C/C++) that often did unassuming text replacement. While this is handy for expressing constants (#define MYCONST 1), it also leads to potentially unexpected outcomes once the replacement gets more complex (for example, #define MYCONST 1 + 1 and when applied as 5 * MYCONST yields 5 * 1 + 1 = 6 instead of the expected 10 (from 5 * (1 + 1)) ) .
However, a preprocessor allows program programming (metaprogramming) and therefore makes things easier for the developer. Instead of copying and pasting expressions and excessive boilerplate code, a quick macro definition leads to a smaller code base and reusable calls and—as a consequence—fewer errors. In order to make the best use of Rust's type system, macros cannot simply search and replace text; they have...