Moving Forward by Letting Go
How Programming Languages Like Clojure Stay Simple Yet Flexible
Typically, developers tend to focus on transforming data when writing computer programs. However, the code of the program itself can be treated as data which is what a compiler does when it compiles the program. The code of the program is referred to as the AST, and many languages provide tools for manipulating AST at runtime before the code is executed — referred to as metaprogramming.
Lisps are famous for having powerful metaprogramming facilities derived from their homoiconic nature. The core language consists of a small set of built-in primitives, and the rest is implemented using macros and functions in the standard library.
Since these same tools are available to the users, anybody can easily extend the language to add semantics for their problem domain — the aspect of macros that’s discussed most often.
While you can extend the language this way, the Clojure community tends to discourage using macros if they can be avoided. The rationale is that macros introduce additional complexity, and Clojure values simplicity. I generally agree with this sentiment, and I find that I tend to use macros sparingly myself. However, saying that macros shouldn’t be overused is not the same as saying they shouldn’t be used at…