为什么这会导致无限循环 [SICP]?

Why does this result in an infinite loop [SICP]?

我正在处理来自 SICP 的问题。我不确定为什么这个函数会导致无限循环。有人可以对此有所了解吗?我确信可能有更好的方法来编写此循环,但我是函数式编程的新手,并且仍在尝试编写这样的循环。

(define (search-for-primes a b)
        (if (> a b) (display " Done"))
        ((timed-prime-test a) (search-for-primes (+ a 1) b)))

程序一直为这个输入打印“完成”:(search-for-primes 2 10),这是没有意义的。 'timed-prime-test' 是一个检查输入是否为质数的函数。或不。这就是我的想法:程序一直调用自身直到 a = 11,此时它会退出。然而,即使是前 9 次迭代(a=2 到 a=10),我也看不到 'timed-prime-test' 函数的输出,这向我表明控件甚至没有到达第二行,但是函数调用发生无限次?

编辑:我再次查看书中 'if' 的语法,我注意到两件事:a) 'alternative' 是我的代码在 if 块之外,这是错误的。我修复了这个问题,但是 a = 10 的程序输出。 b) 一个脚注说它应该只有一个表达式。我程序的这种行为是否与 b) 有关?如果是,在这种情况下程序执行是如何发生的?

如果您正确地格式化您的代码,答案将立即明确。 这就是正确格式化代码的重要性。这是格式更好的定义:

(define (search-for-primes a b)
  (if (> a b)
      (display " Done"))
  ((timed-prime-test a) (search-for-primes (+ a 1) b)))

所以,(search-for-primes 1 1):

  • 测试 1 是否大于 1 ...不是;
  • 然后开始评估 ((timed-prime-test a) (search-for-primes (+ a 1) b)),要执行以下操作:
    • 以某种顺序评估 (timed-prime-test 1)(search-for-primes 2 1),这至少意味着评估 (search-for-primes 1 1),其中:
      • 测试 2 是否大于 1 ...
        • 所以它打印“完成”;
      • 然后开始评估...哎呀。

现在问题出在哪里应该很明显了。

((timed-prime-test a) (search-for-primes (+ a 1) b))

(search-for-primes (+ a 1) b) 的递归调用的当前延续是 ((timed-prime-test a) _) 但它永远不会到达 _ 因为你永远不会填充它的值,即 _ 的值是一个bottom type。所以 ((timed-prime-test a) _) 的值也是一个底部。

但是search-for-primes的值就是((timed-prime-test a) _)的值。所以它没有任何价值。