2011-09-11 8 views
2

私は「記号計算にジェントルはじめに」でエクササイズ14.11を行うと、次の関数を書いています:「List型のではありません」というエラー

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

*nodes*NODEのリストです(compile-machine *nodes*)を呼び出します構造は、私は次のエラーを取得する:

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*がリストであるようです。私はここで間違って何をしていますか?

EDIT:複数コードおそらく

(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))))) 

答えて

2

*NODES*の値がリストであるが、それ自体はありますシンボル。

+0

'* nodes *'が指し示すリストをどうやって得ることができますか? – wrongusername

+0

@wrongusername:シンボルがあるときはいつもと同じです。シンボルの値を計算します。 SYMBOL-VALUEまたはEVALを参照してください。 –

+0

ああ、完璧に働いた、ありがとう!しかし、コンパイルノードで 'eval'を使う必要はありませんでしたか?別の関数を呼び出すとこのエラーを防ぐのに役立ちますか? – wrongusername

2

ノードを明確にすることができ、それはシンボルだ、この場合のリストではありません。マクロの "魔法"は、マクロ作家であるあなたがLispリーダーではなくargumetnsを評価することです。

したがって、シンボルであるノードを渡しています。価値を得るためにはそれを尊重する必要があります。おそらく、このような

(私は本当に錆びてるの注意点ここでは、この上、これはよく間違っているかもしれないが、基本的な前提が近いです)

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

ここでは、カンマを使用することはできません。ネストしたカンマになります。 –

+0

私は参照してください:)しかし、ノードの前にカンマを使用することは役に立たないようです。前の関数でmapcarを使っても、このような関数を呼び出すことに成功しました – wrongusername

3

ファンクションではなく、マクロと書かれています。

マクロはコードで動作します。あなたのコード(compile-machine *nodes*)は、他のコードにマクロ展開されたを取得し、それが実行されます。マクロへの引数は、未評価のシンボル*nodes*です。シンボルはmapcarできません。

実際には関数を記述したいと思うようです。

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

ありがとう!確かにそのように見えますが、 'compile-node'をマクロとして再定義する必要があります。 – wrongusername

+0

@wrongusername:何ですか?なぜそう思うの?関数のようにマクロを渡すことはできません! – Svante

+0

oh、私の 'compile-node'は' compile-machine'によって実行されるはずのリストを作成しますが、それは関数なので返されるリストは評価されません。 'compile-machine'をマクロとして使うべきでしょうか? – wrongusername

関連する問題