それは(複数の評価などの危険性があるので)Lispのフォームにテキスト置換を適用することが危険なことができますが、この場合には、それはそれは一緒にどのように適合するか、このフォームを見て、見に役立つことがあります。
を
((lambda (len)
(lambda (l)
...))
eternity)
は、アプリケーション、つまり関数呼び出しです。呼び出される関数はlen
という1つの引数をとり、1つの引数をとる別の関数l
を返します。呼び出される関数はeternity
で呼び出されます。呼び出しが完了すると、結果はこの関数です。
(lambda (l)
(cond
((null? l) 0)
(else (+ 1 (eternity (cdr l))))))
は今、この関数はリストl
を取り、それが空の場合、0
を返します。それ以外の場合は、(cdr l)
(残りのリスト)を計算し、その値でeternity
を呼び出します。その結果が返されると、1
が結果に追加され、それが関数全体の戻り値になります。問題は、もちろん、また
(define (eternity x)
(eternity x))
のように書くことができeternity
(define eternity
(lambda (x)
(eternity x)))
は、単に引数x
をとり、その後、x
とeternity
を呼び出すことです。それは無限ループです。上記では、私は "返すとき"と書いたが、実際には、(eternity (cdr l))
は決してが返ってくる。だから、
((lambda (len)
(lambda (l)
(cond
((null? l) 0)
(else (+ 1 (len (cdr l)))))))
eternity)
は空のリストで呼び出された場合0
を返し、非空のリストと無限ループに入る機能(lambda (l) …)
を返す関数呼び出しです。
プログラム分析側からは、はであり、これは無限ループには入りません。たとえば、文字列で呼び出すと、(cdr l)
はエラーになります。
"len"はラムダ式のパラメータであるため、再帰型ではありません。その価値は何でもかまいません。ここは「永遠」です。また、最初の式は定義ではありません。最初の式が評価されるとき、 '永遠性 'はまだ定義されていません。 –
ありがとうございます。理解しました。 – liu