为什么 `-` 参数顺序会导致 Racket REPL 运行 内存不足?
Why does `-` parameter order cause Racket REPL to run out of memory?
我在将参数顺序交换到 -
函数时遇到问题。
; source
(define (compose f g) (lambda (x) (f (g x))))
(define (repeated f n)
(if (= n 1)
f
(compose f (repeated f (- 1 n))) ; causes an out of memory error
(compose f (repeated f (- n 1))) ; runs without issue
))
(define (square n) (* n n))
((repeated square 2) 6) ; 1296
; REPL
> > Racket virtual machine has run out of memory; aborting
Aborted (core dumped)
如果我对值进行硬编码,问题就会出现。此外,如果我使用 +
.
递增 n
,则该问题不适用
当你开始时 n
是 2
,然后你调用 (repeated f (- 1 2))
。 (- 1 2)
是-1
,不等于1
,所以继续(repeated f (- 1 -1))
。 (- 1 -1)
是 2,所以你再次调用 (repeated f 2)
就进入了死循环。
当使用其他顺序时,您从 (- 2 1)
开始,即 1
,因此这就是递归停止的地方。
换句话说:如果您从大于 1
的数字开始,并且不断从 n
中减去 1
,您最终将达到 1
并且递归将停止。如果您改为从 1
中减去 n
,您将进入一个循环并且递归将永远继续(或者更确切地说,直到您 运行 内存不足)。
加法不会出现同样的问题,因为加法是可交换的。也就是说,将 x
添加到 y
并将 y
添加到 x
会产生完全相同的结果。减法则不然。
我在将参数顺序交换到 -
函数时遇到问题。
; source
(define (compose f g) (lambda (x) (f (g x))))
(define (repeated f n)
(if (= n 1)
f
(compose f (repeated f (- 1 n))) ; causes an out of memory error
(compose f (repeated f (- n 1))) ; runs without issue
))
(define (square n) (* n n))
((repeated square 2) 6) ; 1296
; REPL
> > Racket virtual machine has run out of memory; aborting
Aborted (core dumped)
如果我对值进行硬编码,问题就会出现。此外,如果我使用 +
.
n
,则该问题不适用
当你开始时 n
是 2
,然后你调用 (repeated f (- 1 2))
。 (- 1 2)
是-1
,不等于1
,所以继续(repeated f (- 1 -1))
。 (- 1 -1)
是 2,所以你再次调用 (repeated f 2)
就进入了死循环。
当使用其他顺序时,您从 (- 2 1)
开始,即 1
,因此这就是递归停止的地方。
换句话说:如果您从大于 1
的数字开始,并且不断从 n
中减去 1
,您最终将达到 1
并且递归将停止。如果您改为从 1
中减去 n
,您将进入一个循环并且递归将永远继续(或者更确切地说,直到您 运行 内存不足)。
加法不会出现同样的问题,因为加法是可交换的。也就是说,将 x
添加到 y
并将 y
添加到 x
会产生完全相同的结果。减法则不然。