Reputation: 4184
I observed a macro expansion I do not fully understand:
(defmacro test (cons-list)
`(list
,@(mapcar #'(lambda(elem)
elem)
cons-list)))
(defmacro test-2 ()
`(list ,@(list (cons "a" "b"))))
(defmacro test-3 (cons-list)
`(list ,@cons-list))
I'd expect both macros to expand in the same fashion, as I just use mapcar in a fancy way of creating the same list again and then use that list. But the results observed in SBCL are:
(test (list (cons "a" "b")))
expands to (LIST LIST (CONS "a" "b"))
(test-2)
expands to (LIST ("a" . "b"))
(test-3 (list (cons "a" "b")))
again expands to (LIST LIST (CONS "a" "b"))
Why don't these macro expansions behave the same?
Upvotes: 1
Views: 53
Reputation: 51501
Test-2
evaluates the form (list (cons "a" "b"))
, the other two do not.
Remember: the arguments to a macro are the forms read, unevaluated.
In order to get the same behaviour from test-2
, you would have to quote the form: ,@'(list (cons "a" "b"))
.
EDIT: Here is a step-by-step expansion of test
:
`(list
,@(mapcar #'(lambda (elem)
elem)
cons-list))
Removing the backquote syntactic sugar:
(list* 'list (mapcar #'(lambda (elem)
elem)
cons-list)
Argument substitution in your example:
(list* 'list (mapcar #'(lambda (elem)
elem)
'(list (cons "a" "b")))
Evaluate the mapcar
form:
(list* 'list '(list (cons "a" "b")))
Evaluate the `list*' form:
'(list list (cons "a" "b"))
Upvotes: 2