Reputation: 12388
I'm trying to 'get' clojure macros and write a tweaked version of the are
macro in terms of the existing are
macro.
The tweak I want is to have signature [argv expr args]
instead of [argv expr & args]
So I've tried
(defmacro are2 [argv expr args] `(clojure.test/are ~arg ~expr ~@args))
which kind of works, except it expects an unquoted list:
(are2 [input] (= 0 input) (1 2 3))
where I'd rather it expect a quoted list:
(are2 [input] (= 0 input) '(1 2 3))
But that results in:
Unable to resolve symbol: quote in this context.
If I try
(are2 [input] (= 0 input) (list 1 2 3))
instead then list
itself gets processed as an test case.
What have I not understood / how can I get past the quote in my macro
Upvotes: 3
Views: 245
Reputation: 91617
'(1 2 3)
is expanding into (quote (1 2 3))
which has an extra quote
symbol and one too many levels of list which you can see with macroexpand-1:
user> (macroexpand-1 '(are2 [input] (= 0 input) '(1 2 3)))
(clojure.test/are [input] (= 0 input) quote (1 2 3))
you can drop the quote from the list by wrapping it int first 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 then runs 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
Upvotes: 5