Modification of the basic if expression in Scheme. Why does it go into an infinite loop?

拥有回忆 提交于 2019-12-01 22:09:25

Scheme has eager evaluation. This means that, unless you're using a special form (like if) or a macro (like cond or case) that delegates to such a special form, all subexpressions are evaluated first.

That means for your expression

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

the (* n (factorial (- n 1))) is evaluated first, before modified-if is run. (It may be run before or after (= n 0), but it doesn't matter either way, the recursive call still happens regardless.) And since this is a recursive call, that means that your program will infinitely recurse, and you will eventually run out of stack.

Here's a simple example: consider this:

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

Because if is a special form, and it only evaluates the necessary branch, in this case it will only evaluate (display "Yay!") and not evaluate (error "Oh noes!"). But if you switch to using your modified-if, both expressions will be evaluated, and your program will raise an error.

Use the stepper in DrRacket to see how your modified-if behaves.

Choose the "Beginner" language. Enter the program below, and then click the stepper icon:

(define (modif predicate then-clause else-clause)
  (if predicate then-clause else-clause))
(define (factorial n)
  (modif (= n 0) 1 (* n (factorial (- n 1)))))
(factorial 5)

You can now step for step see how the computation evolves. Notice that modif follows the rule of function application.

For an example of how the DrRacket stepper looks like:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!