Kannan Ramamoorthy
Kannan Ramamoorthy

Reputation: 4180

How this Clojure macro expansion works?

I am in the process of learning Clojure, through "Clojure for the Brave and True".

In macro lessons, I was trying the below macro,

(defmacro report
  [to-try]
  `(let [result# ~to-try]
     (if result#
       (println (quote ~to-try) "was successful:" result#)
       (println (quote ~to-try) "was not successful:" result#))))

And below are couple of my experiments with the macro and the respective outputs.

1

(map #(report %) ['(= 1 2) '(= 1 1)])
; p1__26622# was successful: (= 1 2)
; p1__26622# was successful: (= 1 1)

2

map #(report %) ['false 'true])
; p1__26612# was not successful: false
; p1__26612# was successful: true

And my questions are,

Upvotes: 1

Views: 98

Answers (1)

Taylor Wood
Taylor Wood

Reputation: 16194

Why in the former case the macro printed true for both values?

Your report macro is receiving quoted lists as inputs, not expressions that can be evaluated to true/false. Any list is truthy, even if it contains an expression that would evaluate to false. This would give you the expected result:

(report (= 1 2)) ;; evaluates to false

In my understanding the second is exactly equivalent to the former. But why it gives a different result?

It's not exactly equivalent because the first example is examining lists and the second is examining quoted booleans. Your second example evaluates 'false as false because that's how if treats it:

(if 'false 0 1) => 1

Upvotes: 4

Related Questions