Ran*_*eer 3 lisp recursion scheme infinite-loop racket
在Scheme中,我将基本的"if"命令修改为:
(define (modified-if predicate then-clause else-clause)
(if predicate
then-clause
else-clause))
Run Code Online (Sandbox Code Playgroud)
然后我使用if的修改版本定义了一个简单的阶乘生成程序:
(define (factorial n)
(modified-if (= n 0)
(* n (factorial (- n 1)))))
Run Code Online (Sandbox Code Playgroud)
现在,当我调用上面的函数时,它会进入无限循环.为什么会这样?
Scheme急切评估.这意味着,除非您使用特殊形式(如if
)或委托给这种特殊形式的宏(如cond
或case
),否则首先评估所有子表达式.
这意味着你的表达
(modified-if (= n 0)
1
(* n (factorial (- n 1))))
Run Code Online (Sandbox Code Playgroud)
在运行(* n (factorial (- n 1)))
之前首先评估modified-if
.(它可以在之前或之后运行(= n 0)
,但无论哪种方式都无关紧要,递归调用仍然会发生.)因为这是一个递归调用,这意味着你的程序将无限递归,你最终会用完堆.
这是一个简单的例子:考虑一下:
(if #t
(display "Yay!")
(error "Oh noes!"))
Run Code Online (Sandbox Code Playgroud)
因为它if
是一种特殊的形式,它只评估必要的分支,在这种情况下它只会评估(display "Yay!")
而不是评估(error "Oh noes!")
.但是如果你切换到使用你的modified-if
,那么两个表达式都将被评估,你的程序将引发错误.