What is the difference between defn and defmacro? What is the difference between a function and a macro?
In general, a macro language function processes one or more arguments and produces a result. You can use all macro functions in both macro definitions and open code. Macro functions include character functions, evaluation functions, and quoting functions.
defn
defines a function, defmacro
defines a macro.
The difference between functions and macros is that on a function call first the arguments of the function are evaluated then the body of the function is evaluated using the arguments.
Macros on the other hand describe a transformation from one piece of code to another. Any evaluation takes place after the transformation.
This means that arguments may be evaluated multiple times or not at all. As an example or
is a macro. If the first argument of or
is false, the second argument will never be evaluated. If or
were a function, this would not be possible, because the arguments would always be evaluated before the function runs.
Another consequence of this is that the arguments of a macro need not be a valid expression before the macro is expanded. For example you could define a macro mymacro
such that (mymacro (12 23 +))
expands to (+ 23 12)
, so this will work even though (12 23 +)
on its own would be nonsense. You couldn't do that with a function because (12 23 +)
would be evaluated, and cause an error, before the function runs.
A small example to illustrate the difference:
(defmacro twice [e] `(do ~e ~e)) (twice (println "foo"))
The macro twice
gets the list (println "foo")
as an argument. It then transforms it into the list (do (println "foo") (println "foo"))
. This new code is what gets executed.
(defn twice [e] `(do ~e ~e)) (twice (println "foo"))
Here println "foo"
is evaluted right away. Since println
returns nil
, twice is called with nil
as its argument. twice
now produces the list (do nil nil)
and returns that as its result. Note that here (do nil nil)
is not evaluated as code, it's just treated as a list.
The Other answers cover this well in depth so I'll try to cover it as succinctly as I can. I would appreciate edits/comments on how to write it more succinctly while keeping it clear:
a function transforms values into other values.(reduce + (map inc [1 2 3])) => 9
a macro transforms code into other code.(-> x a b c) => (c (b (a x))))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With