在方案中,我修改了基本的“如果”命令:
(define (modified-if predicate then-clause else-clause)
(if predicate
then-clause
else-clause))
然后,我使用的,如果修改后的版本中定义的简单阶乘生成程序:
(define (factorial n)
(modified-if (= n 0)
(* n (factorial (- n 1)))))
现在,当我调用上面的函数,它进入一个无限循环。 为什么会这样?
方案有急切的评价。 这意味着,除非您使用的是特殊形式(如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
,两个表达式将被评估,你的程序将引发一个错误。
使用步进在DrRacket怎么看你的修改,如果行为。
选择“新手”的语言。 输入下面的程序,然后单击该图标步进:
(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)
现在,您可以一步一步的看到的计算如何演变。 请注意, modif
如下的功能应用的规则。
对于的DrRacket步进看起来像一个例子:
文章来源: Modification of the basic if expression in Scheme. Why does it go into an infinite loop?