SICPを読む(64)

The problem with this program is that the only procedure that is important to users of sqrt is sqrt. The other procedures (sqrt-iter, good-enough?, and improve) only clutter up their minds. They may not define any other procedure called good-enough? as part of another program to work together with the square-root program, because sqrt needs it. The problem is especially severe in the construction of large systems by many separate programmers. For example, in the construction of a large library of numerical procedures, many numerical functions are computed as successive approximations and thus might have procedures named good-enough? and improve as auxiliary procedures. We would like to localize the subprocedures, hiding them inside sqrt so that sqrt could coexist with other successive approximations, each having its own private good-enough? procedure. To make this possible, we allow a procedure to have internal definitions that are local to that procedure. For example, in the square-root problem we can write

(define (sqrt x)
  (define (good-enough? guess x)
    (< (abs (- (square guess) x)) 0.001))
  (define (improve guess x)
    (average guess (/ x guess)))
  (define (sqrt-iter guess x)
    (if (good-enough? guess x)
        guess
        (sqrt-iter (improve guess x) x)))
  (sqrt-iter 1.0 x))


このプログラムの問題点は、sqrtのユーザにとって重要なのはsqrtプロシージャだけだということです。
そのほかのプロシージャ(sqrt-iter, good-enough?, そしてimprove)は彼らにとってはウザいだけです。
彼らはgood-enough?プロシージャを呼ぶような別のプロシージャを平方根プログラムとともに働くプログラムの一部として定義したりはしないでしょう、
sqrtがそれを必要とするからです。
この問題は大勢のプログラマによって巨大なプログラムが構築される場合に特にシビアになります。
例えば、巨大な算術ライブラリの構築において、多くの算術機能が近似値の計算を行い、それに対してgood-enough?と命名し、補助プロシージャとして
それを改良していきます。私たちは、サブプロシージャを局所化して、sqrtの内側に隠し、sqrtがそれぞれ自前のgood-enough?プロシージャを
持っているほかの近似値プロシージャと共存できるようにしたいと思います。
これを可能にするために、私たちはプロシージャに、プロシージャに対して局所的な内部定義を許します。
例えば、平方根問題はこう書くことができます。

(define (sqrt x)
  (define (good-enough? guess x)
    (< (abs (- (square guess) x)) 0.001))
  (define (improve guess x)
    (average guess (/ x guess)))
  (define (sqrt-iter guess x)
    (if (good-enough? guess x)
        guess
        (sqrt-iter (improve guess x) x)))
  (sqrt-iter 1.0 x))