Fnifni
Fnifni

Reputation: 333

(LIST . VALUES) is not a proper list

Here is a sample code :

(defun my-test (&rest values)
  (macrolet ((my-macro (v)
               `(list ,@v)))
    (print values)
    (my-macro values)))

(my-test 1 2 3 4)
;; The goal is to obtain : (1 2 3 4).

When I execute last line, it prints (1 2 3 4), then the function fails. When I execute the defun or try to execute last line, I get the following warning/error (resp.) :

; in: DEFUN MY-TEST
;     (MY-PACKAGE::MY-MACRO VALUES)
; ==>
;   (LIST . VALUES)
; 
; caught ERROR:
;   (LIST . VALUES) is not a proper list.
; 
; compilation unit finished
;   caught 1 ERROR condition

Why does it fails ?

Upvotes: 0

Views: 160

Answers (1)

Sylwester
Sylwester

Reputation: 48745

A macro transform code and it does not know anything about the runtime values, only the literal code. Eg.

(cond (p1 e1) (p2 e2) (t e3))

Turns into

(if p1
    e1
    (if p2
        e3))

And we really don't know p1 is at this moment. Now look at your code:

(defun my-test (&rest values)
  (macrolet ((my-macro (v)
               `(list ,@v)))
    (print values)
    (my-macro values)))

So the macro is expanded when my-test is created. Could you please tell me how my-macro is going to expand (my-macro values) if not (list . values)? (list . values) is not valid Common Lisp and that is the source of your error.

You should perhaps do this without macros. eg. just use values works fine. For calling a function with a list as the argument you can use apply. To copy a list, which is not needed, you could use copy-list or copy-tree

Upvotes: 4

Related Questions