2 Stimmen

"Fehler: ist nicht vom Typ LIST"

Ich führe Übung 14.11 in "A Gentle Introduction to Symbolic Computation" durch und habe folgende Funktion geschrieben:

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

Wenn ich (compile-machine *nodes*) aufrufe, wobei *nodes* eine Liste von NODE Strukturen ist, erhalte ich folgenden Fehler:

Fehler: *NODES* ist nicht vom Typ LIST.

Also sehe ich, was *nodes* ist, und

CL-USER 116 > *nodes*
(# # # # # # #)

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

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

Es scheint, als wäre *nodes* tatsächlich eine Liste. Was mache ich hier falsch?

EDIT: Mehr Code, der vielleicht Klarheit schaffen kann

(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)) ;ist das nicht im Grunde dasselbe?
           (t (error "Kein Bogen von ~A mit Bezeichnung ~A."    ;und dennoch beschwert sich Lisp nicht
                     ',(node-name node) this-input)))))

3voto

Svante Punkte 49287

Sie schreiben keine Funktion, sondern ein Makro.

Ein Makro arbeitet mit Code. Ihr Code (compile-machine *nodes*) wird makroexpandiert zu anderem Code, der dann ausgeführt wird. Das Argument Ihres Makros ist das nicht ausgewertete Symbol *nodes*. Sie können kein Symbol mapcar.

Es scheint mir, dass Sie tatsächlich eine Funktion schreiben möchten. Verwenden Sie dafür defun:

(defun compile-machine (nodes)
  (mapcar #'compile-node nodes))

2voto

Will Hartung Punkte 110997

Knoten ist in diesem Fall keine Liste, sondern ein Symbol. Das "magische" an Makros ist, dass du, der Makro-Schreiber, die Argumente auswerten kannst - nicht der Lisp-Interpreter.

Also, du übergibst Knoten, was ein Symbol ist. Du musst es dereferenzieren, um seinen Wert zu erhalten.

Vielleicht so (Achtung, ich bin wirklich nicht mehr so fit darin, das könnte falsch sein, aber das Grundkonzept stimmt ungefähr)

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

2voto

Rainer Joswig Punkte 131198

Der Wert von *NODES* ist eine Liste, aber selbst ist es ein Symbol.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X