为什么这会导致无限循环 [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) _)
的值。所以它没有任何价值。
我正在处理来自 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 ...
- 所以它打印“完成”;
- 然后开始评估...哎呀。
- 测试 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) _)
的值。所以它没有任何价值。