ошибка "не типа LIST" - PullRequest
       21

ошибка "не типа LIST"

2 голосов
/ 11 сентября 2011

Я делаю упражнение 14.11 в разделе «Нежное введение в символические вычисления» и написал следующую функцию:

(defmacro compile-machine (nodes)
  `(progn ,@(mapcar #'compile-node nodes)))

При вызове (compile-machine *nodes*), где *nodes* - это список NODE структур, я получаю следующую ошибку:

Error: *NODES* is not of type LIST.

Итак, я вижу, что *nodes* является , а

CL-USER 116 > *nodes*
(#<Node START> #<Node HAVE-5> #<Node HAVE-10> #<Node HAVE-15> #<Node HAVE-20> #<Node HAVE-25> #<Node END>)

CL-USER 117 > (type-of *nodes*)
CONS

CL-USER 118 > (listp *nodes*)
T

Кажется, что *nodes* действительно список. Что я здесь не так делаю?

РЕДАКТИРОВАТЬ: больше кода, который может уточнить,

(defun compile-arc (arc)
  `((equal this-input ',(arc-label arc))
    (format t "~&~A" ,(arc-action arc))
    (,(node-name (arc-to arc)) (rest input-syms))))

(defun compile-node (node)
  `(defun ,(node-name node) (input-syms &aux (this-input (first input-syms)))
     (cond ((null input-syms) ',(node-name node))
           ,@(mapcar #'compile-arc (node-outputs node)) ;isn't this basically the same?
           (t (error "No arc from ~A with label ~A."    ;and yet Lisp doesn't complain
                     ',(node-name node) this-input)))))

Ответы [ 3 ]

3 голосов
/ 11 сентября 2011

Вы пишете не функцию , а макрос .

Макрос работает с кодом .Ваш код (compile-machine *nodes*) получает макро-расширен в другой код, который затем выполняется.Аргументом для вашего макроса является неоцененный символ *nodes*.Вы не можете mapcar символ.

Мне кажется, что вы действительно хотите написать функцию.Для этого используйте defun:

(defun compile-machine (nodes)
  (mapcar #'compile-node nodes))
2 голосов
/ 11 сентября 2011

Значение *NODES* является списком, но само по себе это символ.

2 голосов
/ 11 сентября 2011

узлов в данном случае это не список, это символ.«Магия» макросов заключается в том, что вы, писатель макросов, можете оценить аргументы, а не читатель Lisp.

Итак, вы передаете узлов , что являетсяусловное обозначение.Вам нужно будет почтить его, чтобы получить его значение.

Возможно, вот так (предостережение, что я здесь действительно ржавый, это может быть неправильно, но основная предпосылка близка)

(defmacro compile-machine (nodes)
  `(progn ,@(mapcar #'compile-node ,nodes)))
...