GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/eintr/No-Deferment.html ・ emacs-doc.conao3.com

11.3.7 デファーメントなしの再帰

triangle-recursively関数で何が起こるのか、改めて考えてみましょう。中間計算は、すべて完了するまで延期されることがわかります。

関数の定義は以下の通りです。

(defun triangle-recursively (number)
  "Return the sum of the numbers 1 through NUMBER inclusive.
Uses recursion."
  (if (= number 1)                    ; do-again-test
      1                               ; then-part
    (+ number                         ; else-part
       (triangle-recursively          ; recursive call
        (1- number)))))               ; next-step-expression

この関数に引数7を渡して呼び出すと、どうなるでしょうか?

triangle-recursively 関数の最初のインスタンスは、引数 6 が渡された triangle-recursively の2番目のインスタンスが返す値に数値 7 を加算します。つまり、最初の計算は次のようになります。

(+ 7 (triangle-recursively 6))

triangle-recursivelyの最初のインスタンス――小さなロボットのようなものと考えてよいでしょう――は、自身の処理を完了することができません。そのため、(triangle-recursively 6)の計算をプログラムの2番目のインスタンス、つまり2台目のロボットに引き継がなければなりません。この2台目の個体は、1台目とは全く別物です。専門用語で言えば、「別のインスタンス化」にあたります。言い換えれば、別のロボットということです。モデルは1台目と同じで、三角数を再帰的に計算しますが、シリアル番号が異なります。

では、(triangle-recursively 6)は何を返すのでしょうか?それは、引数5を指定してtriangle-recursivelyを評価して得られた値に6を加えた数値を返します。ロボットの比喩で言えば、また別のロボットに助けを求めていることになります。

これで合計は:

(+ 7 6 (triangle-recursively 5))

それで、この後はどうなるの?

(+ 7 6 5 (triangle-recursively 4))

triangle-recursivelyが呼び出されるたびに、最後の一回を除いて、プログラムの別のインスタンス—別のロボット—を生成し、計算を行わせる。

最終的に、加算処理全体がセットアップされ、実行されます:

(+ 7 6 5 4 3 2 1)

この関数の設計では、最初のステップの計算を2番目のステップが可能になるまで延期し、さらにそれを3番目のステップが可能になるまで延期する、という具合に繰り返されます。延期が行われるたびに、コンピュータは何を待っているのかを記憶しておく必要があります。この例のようにステップ数が少ない場合は問題になりません。しかし、ステップ数が多くなると問題になる可能性があります。