方案的基本表达是否进行修改。 为什么会进入一个无限循环?(Modification of the

2019-09-01 08:04发布

在方案中,我修改了基本的“如果”命令:

(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)))))

现在,当我调用上面的函数,它进入一个无限循环。 为什么会这样?

Answer 1:

方案有急切的评价。 这意味着,除非您使用的是特殊形式(如if )或宏(如condcase )委托给这样一个特殊的形式, 所有的子表达式首先评估。

这意味着你的表达

(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 ,两个表达式将被评估,你的程序将引发一个错误。



Answer 2:

使用步进在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?