Historically, Lisps have been described as “programmable programming languages.” This description fits Clojure, and a large part of the reason for that is macros. Macros allow a programmer to extend the Clojure language in ways that are difficult or impossible in most other languages.
A programming language is a means for building abstractions. Instead of doing tedious manual work, a programmer can write code once and treat that code as a reusable unit. Code can be executed repeatedly in a loop; or, code can be grouped as a unit and given a name as a function; or, using conditionals, the same code can do different things in different circumstances.
It should be clear that some languages offer more powerful means of abstraction than others. Imagine for a moment a programming language without loops. Such a language might be usable, but unrolling all loops by hand would be incredibly tedious. Similarly, a language without functions might be able to do anything any other Turing-complete language can do, but code would have to be repeated over and over.
In short, when a language lacks proper means of abstraction, the result is boilerplate and repetition, both signs of fundamental weaknesses in that language. Macros are powerful because they give you a way to define entirely new levels of abstraction within the language itself. Macros are the ultimate tool for eliminating boilerplate and growing a programming language up to meet your needs.
Macros allow you ...