我正在阅读懒惰的评估,并且无法理解他们给出的基本示例.
#lang racket
(define (bad-if x y z)
(if x y z))
(define (factorial-wrong x)
(bad-if (= x 0)
1
(* x (factorial-wrong (- x 1)))))
(factorial-wrong 4)
Run Code Online (Sandbox Code Playgroud)
我有点困惑为什么这个程序永远不会终止.我知道下面的代码工作得很好:
(define (factorial x)
(if (= x 0)
1
(* x (factorial (- x 1)))))
(factorial 4)
Run Code Online (Sandbox Code Playgroud)
所以我假设它与范围有关.我尝试了一步一步的调试,即使x被映射到0,factorial-wrong也会执行递归函数.
标准 if
(if test-expr then-expr else-expr)
Run Code Online (Sandbox Code Playgroud)
只会评估要么 then-expr 或者 else-expr根据test-expr,因为这if可以是一个特殊形式或句法扩展基于一种特殊形式,这意味着它不遵循正常的评估规则上.
bad-if另一方面,这是一个标准程序.在这种情况下,Scheme首先计算两个表达式,因为它们是实际执行bad-if 前的过程的参数bad-if.因此,即使对于x = 0,(* x (factorial -1))也将在(* x (factorial -2))无限循环中进行评估,然后进行评估,依此类推.