「printfデバッグ」を使用する
関数定義を変更することで、Emacsに理解を助けてもらうことができます。
(defun triangle-using-cond (number)
(message (format "called with %d" number))
(cond ((<= number 0) 0)
((= number 1) 1)
((> number 1)
(+ number (triangle-using-cond (1- number))))))
バッファーに(message ...)証跡を出力する場所を追加してください*Messages*。
Edebugを使用する
関数定義内の任意の場所にポイントを置き、ヒットC-u C-M-xして「計測」します。そして、後にポイントを置くことによって、機能、例えばを評価(triangle-using-cond 3)して打ちますC-x C-e。
これで、Edebugモードになりました。スペースバーを押して、機能をステップスルーします。各式の中間値がエコー領域に表示されます。Edebugモードを終了するには、を押してくださいq。インストルメンテーションを削除するには、定義内の任意の場所にポイントを置き、ヒットC-M-xして定義を再評価します。
標準のEmacsデバッガーを使用する
M-x debug-on-entry triangle-using-cond、その後、triangle-using-condが呼び出されると、Emacsデバッガー(バッファー*Backtrace*)に配置されます。
を使用して評価をステップ実行しますd(またはc、興味のない評価をスキップします)。
中間状態(変数値など)を表示するには、eいつでも使用できます。評価するためにsexpを入力するように求められ、評価結果が出力されます。
デバッガーを使用している間、ソースコードのコピーを別のフレームに表示しておくと、何が起こっているのかを追跡できます。
また、ソースコードの任意の場所で明示的な呼び出しを挿入して、デバッガー(多かれ少なかれブレークポイント)に入ることもできます。(debug)またはを挿入し(debug nil SOME-SEXP-TO-EVALUATE)ます。後者の場合、デバッガが入力SOME-SEXP-TO-EVALUATEされると評価され、結果が出力されます。(このようなコードをソースコードに挿入し、C-M-x評価に使用してから元に戻すことができます。編集したファイルを保存する必要はありません。)
詳細については、ElispマニュアルのノードUsing Debuggerを参照してください。
ループとしての再帰
とにかく、再帰をループと考えてください。定義されている2つの終了ケースがあります:(<= number 0)と(= number 1)。これらの場合、関数は単純な数値を返します。
再帰的な場合、関数はその数との関数の結果の合計を返しますnumber - 1。最終的に、関数は1ゼロ以下のいずれかまたは数字で呼び出されます。
したがって、再帰的なケースの結果は次のとおりです。
(+ number (+ (1- number) (+ (1- (1- number)) ... 1)
例を挙げましょう(triangle-using-cond 4)。最終的な式を蓄積しましょう:
最初の反復でnumberは4であるため、(> number 1)分岐が続きます。私たちは、表現の構築を開始(+ 4 ...し、して関数を呼び出し(1- 4)、すなわち(triangle-using-cond 3)。
現在numberは3であり、結果は(+ 3 (triangle-using-cond 2))です。合計結果式は(+ 4 (+ 3 (triangle-using-cond 2)))です。
numberある2式があるので、今(+ 4 (+ 3 (+ 2 (triangle-using-cond 1))))
numberがあり1、(= number 1)分岐を取り、退屈になり1ます。全体の表現は(+ 4 (+ 3 (+ 2 1)))です。:内部から出ていることを評価し、あなたが得る(+ 4 (+ 3 3))、(+ 4 6)ちょうど、または10。
triangle-using-condが返す値に数値を加算します。引数は数値より1小さい値です。条件は、a、b、cの順になります。最初に一致するものは何でも、降圧が停止します。