0

このコードセグメントを取得したとします。

(defparameter *islands* '((1 9 8 5) (6 4 2 3)))

(defun edge-pair (a b)
  (unless (eql a b)
    (list (cons a b) (cons b a))))

(defun connected-with-bridges (islands)
  (when (cdr islands)
    (append (edge-pair (caar islands) (caadr islands))
            (connected-with-bridges (cdr islands)))))

さて、インタプリタ(SBCL)を渡すと:

(connected-with-bridges '((1 9 8 5) (6 4 2 3)))

結果は次のとおりです。

((1 . 6) (6 . 1))

クラッシュしません。ただし、私が渡す場合:

;; '(6 4 2 3) is actually (cdr '((1 9 8 5) (6 4 2 3)))
(caar '(6 4 2 3)) 

クラッシュします。関数に(connected-with-bridges)応じて、リストのcdrは、*islands*続行できなくなるまで渡され続けます。に初めて*islands*渡される(connected-with-bridges)と、リストはになります'((1 9 8 5) (6 4 2 3)。ただし、再帰が進むにつれて、2回目はになります'(6 4 2 3)。これは(append)関数内で次のようになります。

(append (edge-pair (caar '(6 4 2 3)) (caadr '(6 4 2 3)))
                (connected-with-bridges (cdr islands)))

(append)インタープリターで単独で実行すると明らかにクラッシュしますが、内部(ブリッジで接続)の内部で実行するとクラッシュしません。

4

2 に答える 2

2

(caar '(6 4 2 3))実行しようとしているエラーの原因を示します(car 6)。6はリストではありません。

関数内には(caar'(6 4 2 3))はありませんが、(caar '((6 4 2 3)))

cdrがどのように機能するかを見てください: (cdr '((1 9 8 5) (6 4 2 3))))=> '((6 4 2 3))'(6 4 2 3) そうではありません...(caar'((6 4 2 3)))=> 6、および(car '(6 4 2 3))=> 6

あなたはあなたの間違いを見ますか?

于 2012-03-05T19:27:20.670 に答える
2
;; '(6 4 2 3) is actually (cdr '((1 9 8 5) (6 4 2 3)))

いいえ、試してみてください。

(caar '(6 4 2 3) (caadr '(6 4 2 3))

それは有効なLispではありません。

Lispも「クラッシュ」しません。エラーを通知するだけです。

SBCLも通訳ではありません。コンパイラを使用します。

于 2012-03-05T19:02:59.807 に答える