How are Clojure macros different from C macros?

I am new to learning Clojure. I started couple of months ago. I am trying to learn Macros.

I initially got confused understanding difference between macros and higher-order functions in Clojure as a higher order function could take lambdas and execute one of them how many times it wanted based on any conditions and filter.

So I posted a question with a simple example regarding this on StackOverflow itself. I got my doubts cleared from the answer.

This is what I understood,

  • Macros won't evaluate all the arguments unlike functions to evaluate the body.
  • Macros can be selective about what to evaluate and what not and how to convert one piece of code into another using quote,unquote and splicing syntax.
  • The final code that comes out of the macro is then evaluated.
  • So my question is, How is it different from preprocessor directives and macros used in C ? What power does Lisp/Clojure macros give to the developers which C macros completely lack and are often used widely.


    Some notable differences:

  • Clojure macros operate on Lisp data structures whereas C macros operate on text . This capability is a consequence of Lisps being homoiconic (ie Lisp source code is expressed as Lisp data structures). Homoiconicity isn't strictly necessary for a macro system to be effective, but it certainly makes it much more convenient and natural.
  • You can execute Clojure macros at runtime as well as compile time (eg using eval )
  • Clojure macros are written in Clojure itself . Contrast with C preprocessor macros, which have their own separate mini-language. This is a big advantage when writing more complex macros: you don't have to mentally switch between different languages (you do of course still need to mentally distinguish between which code you want to execute while processing the macro vs. which code you want to generate as the output of the macro)
  • Clojure macros are Turing complete - you can perform arbitrary code generation within them. Not true for standard C preprocessor macros, which are somewhat limited in their ability to express complex code generation. EDIT : Thanks Jeremy for providing links to some amusing hacks by which the C preprocessor can be coerced into acting in a turning-complete manner. The overall point still stands though: these aren't really practical ways to write general purpose code.
  • Arguably, macros are still the distinguishing "killer feature" of Lisps. For a little extra explanation on this topic, it's worth reading Paul Graham's essay "What Made Lisp Different"


    C macros allow plain text substitution and are pretty dumb(in terms of operations that can be performed). Further, if it did allow more complicated expressions, using it would be cumbersome because you're manipulating plain strings.

    Since Clojure and Lisps in general use S-Expressions(which are just plain linked lists) and allow the full language to be used at macro-expansion time, you can build far more complex and useful expressions.


    C macros are purely textual rewriting macros. There's nothing terribly C about them aside from that being where they came from – you can use the C preprocessor cpp(1) on any text. Consequently, it's easy to generate non-C forms using the C preprocessor, and you often have to jump through hoops to do fairly trivial things as far as C itself goes. C macros are full of pitfalls because of this.

    Clojure macros are Clojure code that executes using a different set of rules than regular Clojure functions. Instead of receiving evaluated arguments and returning a result, they receive unevaluated forms and return a form, which might eventually be evaluated during the course of normal execution.

    链接地址: http://www.djcxy.com/p/33630.html

    上一篇: 美元符号($)在clojure符号名称

    下一篇: Clojure宏如何与C宏不同?