Scheme 为什么这个代码工作正常?

Scheme 为什么这个代码工作正常?,scheme,racket,Scheme,Racket,我认为下面的代码不能正确地删除前导零和尾随零,但它确实可以: (define f (λ (l) (let loop () ; 1 (code line no.) (when (= 0 (first l)) ; 2 (set! l (rest l)) ; 3 (loop))

我认为下面的代码不能正确地删除前导零和尾随零,但它确实可以:

(define f
  (λ (l)
    (let loop ()                             ; 1 (code line no.)
      (when (= 0 (first l))                  ; 2
        (set! l (rest l))                    ; 3
        (loop))                              ; 4
      (set! l (reverse l) )                  ; 5
      (when (= 0 (first l)) (loop)))         ; 6
    (reverse l)))                            ; 7

(f '(0 0 2 5 0 6 8 9 0 0 0))
输出:

'(2 5 0 6 8 9)
我认为删除前导零后,列表将在第5行中反转;然后从第6行开始,它将递归到第1行,并删除尾随的零(现在在反向列表中处于前导位置)。然后这个列表将再次反转(第二次在第5行),最后它将在第7行再次反转(第三次)


由于列表被反转了3次,所以输出应该是一个反转的列表(不带零),但是,输出中显示的是非反转列表。解释中的缺陷在哪里?

您必须记住,当循环返回时,程序将在第4行之后继续执行。循环的每次调用都会发生这种情况。因此,如果有n个前导零和m个尾随零,
反向
将被称为
n+1+m+1+1=n+m+3
(最后一个
1
是程序结束时的反向),在本例中为8

然而,你是对的,程序不能像运行一样工作

(f '(0 0 2 5 0 6 8 9 0 0))
将输出

'(9 8 6 0 5 2)

因此,我的直觉是正确的,这个代码不是完全正确的。你发布的代码不是你链接到的代码。这一个结合了变异和递归,这是一个令人不快的组合。你链接的那个完全是功能性的。我在发现链接有缺陷后更改了链接中的代码。我已经从我的问题中删除了链接。谢谢你指出这个疏忽。