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

冷暖自知 提交于 2019-12-04 04:22:44

问题


In Scheme, I modified the basic 'if' command as:

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

And then I defined a simple factorial generating program using the modified version of if:

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

Now, when I call the above function, it goes into an infinite loop. Why does that happen?


回答1:


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.




回答2:


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:



来源:https://stackoverflow.com/questions/16275157/modification-of-the-basic-if-expression-in-scheme-why-does-it-go-into-an-infini

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