The difference comes to life when you don't want to evaluate your arguments unless needed.
Consider this example:
(defn unless [pred body]
(when (not pred)
body))
This doesn't work since arguments to a function are eagerly evaluated. So body always runs, as shown below:
(unless (zero? 2)
(prn "Not zero!"))
;; "Not zero!"
(unless (zero? 0)
(prn "Not zero!"))
;; "Not zero!"
Both executions above print "Not zero!", which is clearly wrong.
The only way to write our unless utility is by using a macro:
(defmacro unless [pred body]
`(when (not ~pred)
~@body))
Now if we give it a try, we'll see it works as expected:
(unless (zero? 2)
(prn "Not zero!"))
;; "Not zero!"
(unless (zero? 0)
(prn "Not zero!"))
;; this prints nothing
Macros only evaluate its arguments when the developer decides to.
You'll notice some special characters in the macro such as `, ~ and ~@. They stand for syntax-quote, unquote and unquote-splicing, respectively and are explained here.
I suggest you study these symbols.
Hope this helps.