2

私は LISP の初心者で、いくつかの基本的な合計関数で遊んでいます。

(defun suma (&rest L)
  (cond
    ((null L) 0)
    (T (+ (CAR L) (EVAL (CONS 'suma (CDR L)))))
))


(defun suma2 (&rest L)
  (cond
   ((null L) 0)
   (T (+ (car L) (suma2 (cdr L))))
))

最初の関数は問題なく動作します。2 番目の関数では、SB-KERNEL::CONTROL-STACK-EXHAUSTED というエラーが発生します。

私の質問は、なぜ最初の関数は問題なく、2 番目の関数は本質的に同じことをしているのにそうでないのですか?

4

2 に答える 2

7

を呼び出すと、(suma2 1 2 3)Lリストになります(1 2 3)(suma2 (cdr L))次に、を呼び出します(suma2 '(2 3))。その呼び出しLでは list ((2 3))、つまり単一の要素を含むリストになります: list (2 3)。今度は(suma2 (cdr L))再度呼び出しますが、今回(cdr L)は空のリストであるため、次の呼び出しLでは空のリストを含むリストになります。それはまだ1つの要素を含むリストであるため、何度も何度も再帰しま​​す。が常に 1 つの要素を含むリストになるLため、 が空の場合には決して到達しません: の結果です。L(cdr L)

そのため、可変数の引数の代わりにリストを受け入れるように関数を変更するsuma2(そして、 の代わりに(suma2 (list 1 2 3))またはとして呼び出す) か、リスト自体の代わりにリストの内容を引数として呼び出すように使用する必要があります。(suma2 '(1 2 3))(suma2 1 2 3)applysuma2

于 2013-10-09T23:05:04.360 に答える
5

2 番目の関数 (-> suma2) での関数呼び出しが間違っています。

関数が次のように呼び出されることを期待しています。

(suma2 1 2 3 4)

しかし、最初の再帰呼び出しはこれと同等です:

(suma2 '(2 3 4))

個々の要素が期待されるリストを渡します。のドキュメントを参照してくださいAPPLY

于 2013-10-09T23:04:55.430 に答える