したがって、そのようなテストのための関数呼び出しをプログラムソースに コメントあるいはドキュメントとして埋め込んでおくのが良い。
Stepper commands: n (or N or Newline): advances to the next form. 次のフォームに進む s (or S): skips the form. このフォームを飛ばす。実行するけどステップはしない。 p (or P): pretty-prints the form. 今のフォームを可愛く(pretty)表示する。 f (or F) FUNCTION: skips until the FUNCTION is called. 今呼ばれてる関数が終わる/答を返すまで飛ばす。 q (or Q): quits. ステップを止めて一挙に実行する。 u (or U): goes up to the enclosing form. f と同じだけど、飛ばすところが少し異なる。 e (or E) FORM: evaluates the FORM and prints the value(s). LISPの式を評価する(eval)。変数を表示したりするのに使う。 r (or R) FORM: evaluates the FORM and returns the value(s). 今、実行している関数の返り値を指定する。 b (or B): prints backtrace. どういう関数から呼ばれてきたか履歴を表示する。 ?: prints this. これを(英語だけだけど)表示する。step は小さいプログラムを理解するのには向いている。初心者向き、 いや、非常に細かくプログラムを調べるのに向いている。 大きなプログラムになると、すべてをステップ実行することはできない。 たとえ、1pageのプログラムでもいやになるのが普通だ。
(trace sum-until integer-generator) としてから、 (sum-until 0 100 (integer-generator 0) を動かしてみよう。
さらに、trace にはいろいろなオプションを付けることができる。例えば、 (trace (sum-until :depth 5)) とすると、最初の5つの再帰呼び出しだけが トレースされる。
コンパイルされたコードでもトレースはできることが多い。
`:DEPTH' DEFAULT: No depth limit FORM is simply a positive integer specifying the maximum nesting of traced calls of FN, i.e. of calls of FN in which the :COND form evaluated to non-NIL. For calls of FN in which this limit is exceeded, even the :COND form is not evaluated, and the call is not traced.しかし、これと同じことは、例えば(print x)とかをプログラムにつけ加える ことでも実現できる。これは特にデバッグ環境が整ってない場合に有効で ある。新しいアーキテクチャ、あるいは、OSを作っている時、そして お金がなくて良い環境を買えない時、そういう時に使おう。また、traceや stepよりも簡易で高速なのも大きな利点だ。
あるいは、プログラムの途中からstep実行するというのも便利だ。
しかし、実際にはプログラムが自分の理解できる範囲に収まるとは 限らない。そういう時は、関数の持つ意味に立ち戻る。
とにかく、なんかの方法で答が間違っていることは分かっているはずである。 (でなければデバッグしていない) そこで、最初の入力から明らかなエラー までを2分探索法で探していく。そのためには、break, trace などを使う。 特に、値が異なりはじめる部分を見つけるような条件文を入れるのが良い。
(if (not (equal answer variable)) (break))
などとすれば良い。
実はそれは可能あでる。何故なら、プログラムの大部分は短い部分の寄せ集め だからである。もちろん、それは、そのようにプログラムするからだが。 そのためにはプログラムを適切な要素に分割しなければならない。その 分割パターンを調べるのがソフトウェア工学だとともいえる。 sum-until, tree-insert は、そのような分割の例である。その他、