schemeまとめ(4:繰り返し処理) | SU-Ⅲ 電脳紀 Second

SU-Ⅲ 電脳紀 Second

基本的に雑記ですが、情報系の事も書きます。

繰り返しは再帰で書く(forも無くはないが) 例えば
(define fact
    (lambda (x)
        (if (= x 1) 1 (* x (fact (- x 1))))
    )
)
とした場合、引数として渡した自然数の階乗が得られる(この関数は引数として自然数を想定している。)
評価の過程を書くと、
(fact 4)
(* 4 (fact 3))
(* 4 (* 3 (fact 2)))
(* 4 (* 3 (* 2 (fact 1))))
(* 4 (* 3 (* 2 1)))
(* 4 (* 3 2))
(* 4 6)
24

となるが、次のようにプログラムを書き換えると評価の過程は変わってくる。
次のようにプログラムを書き換える。
(define fact
    (lambda (x)
        (define inner
            (lambda (n x)
                (if (= n 1) x (inner (- n 1) (* x n)))
            )
        )
        (inner x 1)
    )
)

と、計算過程はこうなる。
(fact 4)
(inner 4 1)
(inner 3 4)
(inner 2 12)
(inner 1 24)
24

注目すべきは前者は過程が横に膨らんでいた(与える値を大きくするともっと横に長くなる)が、後者は常にinner関数が呼び出されるだけで、ある階層における計算でそれより先の計算結果を利用していません。

前者を再帰的プロセス、後者を反復的プロセスと言う。
同じ結果が得られるとしても反復的プロセスの方が内部的に効率的に実行することができる。