3

Scheme では、基本的な 'if' コマンドを次のように変更しました。

(define (modified-if predicate then-clause else-clause)
  (if predicate
      then-clause
      else-clause))

次に、if の修正版を使用して簡単な階乗生成プログラムを定義しました。

(define (factorial n)
  (modified-if (= n 0)
               (* n (factorial (- n 1)))))

ここで、上記の関数を呼び出すと、無限ループに入ります。なぜそれが起こるのですか?

4

2 に答える 2

7

スキームには熱心な評価があります。これは、特別なフォーム ( など) や、そのような特別なフォームにデリゲートするifマクロ ( またはcondなど) を使用していない限り、すべての部分式が最初に評価されることを意味します。case

それはあなたの表現のために意味します

(modified-if (= n 0)
             1
             (* n (factorial (- n 1))))

が実行される前に、(* n (factorial (- n 1)))が最初に評価されmodified-ifます。( の前または後に実行される可能性がありますが(= n 0)、どちらの方法でも問題ありません。再帰呼び出しは関係なく発生します。) そして、これは再帰呼び出しであるため、プログラムが無限に再帰することを意味し、最終的には不足します。スタック。

ここに簡単な例があります: これを考慮してください:

(if #t
    (display "Yay!")
    (error "Oh noes!"))

は特別な形式であり、必要な分岐のみを評価するためif、この場合は評価のみを行い、 を評価(display "Yay!")しません(error "Oh noes!")。しかし、 を使用するように切り替えるとmodified-if、両方の式が評価され、プログラムでエラーが発生します。

于 2013-04-29T11:57:53.300 に答える