Clojure macros and quotes

I am trying to "get" clojure macros and write a modified version of the macro are

in terms of an existing macro are

. The setting I want is to have a signature [argv expr args]

instead of [argv expr & args]

So I tried

(defmacro are2 [argv expr args] `(clojure.test/are ~arg ~expr ~@args))

      

what kind of works, except that it expects an unquoted list:

(are2 [input] (= 0 input) (1 2 3))

      

where I would rather expect the quoted list:

(are2 [input] (= 0 input) '(1 2 3))

      

But this leads to:

Unable to resolve symbol: quote in this context.

      

If i try

(are2 [input] (= 0 input) (list 1 2 3))

      

and then list

itself is processed as a test case.

What I didn't understand / how do I get past a quote in a macro

+3


source to share


1 answer


'(1 2 3)

expands into (quote (1 2 3))

, which has an extra character quote

and too many list levels, which you can see with macro instance-1:

user> (macroexpand-1 '(are2 [input] (= 0 input) '(1 2 3)))
(clojure.test/are [input] (= 0 input) quote (1 2 3)) 

      

you can remove a quote from the list by first wrapping it in an int and rest



 user> (defmacro are2 [argv expr args] 
          `(clojure.test/are ~argv ~expr ~@(first (rest args))))
#'user/are2
user> (macroexpand-1 '(are2 [input] (= 0 input) '(1 2 3)))
(clojure.test/are [input] (= 0 input) 1 2 3) 

      

which is then run as a test:

user> (are2 [input] (= 0 input) '(1 2 3)

FAIL in clojure.lang.PersistentList$EmptyList@1 (NO_SOURCE_FILE:1)
expected: (= 0 1)
  actual: (not (= 0 1))

FAIL in clojure.lang.PersistentList$EmptyList@1 (NO_SOURCE_FILE:1)
expected: (= 0 2)
  actual: (not (= 0 2))

FAIL in clojure.lang.PersistentList$EmptyList@1 (NO_SOURCE_FILE:1)
expected: (= 0 3)
  actual: (not (= 0 3))
false 

      

+5


source







All Articles