解释《小骗子》第137页上的延续示例 [英] Explain the continuation example on p.137 of The Little Schemer

查看:102
本文介绍了解释《小骗子》第137页上的延续示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有问题的代码是这样的:

The code in question is this:

(define multirember&co
  (lambda (a lat col)
    (cond
     ((null? lat)
      (col (quote ()) (quote ())))
     ((eq? (car lat) a)
      (multirember&co a
                      (cdr lat)
                      (lambda (newlat seen)
                        (col newlat
                             (cons (car lat) seen)))))
     (else
      (multirember&co a
                      (cdr lat)
                      (lambda (newlat seen)
                        (col (cons (car lat) newlat)
                             seen))))))

我整天盯着眼睛,但我似乎不太明白.当您重复使用该函数时,您将重新定义col,但是在示例中,它们似乎使用了原始定义.为什么它不会改变.如何在不传递参数newlatseen的情况下重复使用它.

I've stared at this all day but I can't quite seem to understand it. When you recur on the function you are re-defining col but in the examples they seem to use the original definition. Why wouldn't it change. How can you recur on it without passing in the parameters newlat and seen.

很难解释我的问题,因为我似乎只是缺了一块.如果也许有人可以给出比这本书更明确的演练,我也许就能理解它的工作原理.

It's hard to explain my question because I seem to just be missing a piece. If perhaps someone could give a more explicit walk-through than the book I may be able to understand how it works.

推荐答案

我们来看一个示例;也许那会有所帮助. :-)为简单起见,我将使用list作为收集器/继续符,它将仅返回包含继续符参数的列表.

Let's step through an example; maybe that will help. :-) For simplicity, I'm just going to use list as the collector/continuation, which will just return a list with the arguments to the continuation.

(multirember&co 'foo '(foo bar) list)

在一开始,

a = 'foo
lat = '(foo bar)
col = list

在第一次迭代中,(eq? (car lat) a)条件匹配,因为lat不为空,并且lat的第一个元素为'foo.这样就将下一个递归设置为multirember&co:

At the first iteration, the (eq? (car lat) a) condition matches, since lat is not empty, and the first element of lat is 'foo. This sets up the next recursion to multirember&co thusly:

a = 'foo
lat = '(bar)
col = (lambda (newlat seen)
        (list newlat (cons 'foo seen))

在下一次迭代中,else匹配:由于lat不为空,并且lat的第一个元素为'bar(而不是'foo).因此,对于下一次递归,我们有:

At the next iteration, the else matches: since lat is not empty, and the first element of lat is 'bar (and not 'foo). Thus, for the next recursion, we then have:

a = 'foo
lat = '()
col = (lambda (newlat seen)
        ((lambda (newlat seen)
           (list newlat (cons 'foo seen)))
         (cons 'bar newlat)
         seen))

为了便于阅读(避免混淆),我们可以重命名参数(由于词法作用域),而无需更改程序的语义:

For ease of human reading (and avoid confusion), we can rename the parameters (due to lexical scoping), without any change to the program's semantics:

col = (lambda (newlat1 seen1)
        ((lambda (newlat2 seen2)
           (list newlat2 (cons 'foo seen2)))
         (cons 'bar newlat1)
         seen1))

最后,(null? lat)子句匹配,因为lat现在为空.所以我们叫

Finally, the (null? lat) clause matches, since lat is now empty. So we call

(col '() '())

扩展为:

((lambda (newlat1 seen1)
   ((lambda (newlat2 seen2)
      (list newlat2 (cons 'foo seen2)))
    (cons 'bar newlat1)
    seen1))
 '() '())

(替换为newlat1 = '()seen1 = '()时)变为

((lambda (newlat2 seen2)
   (list newlat2 (cons 'foo seen2)))
 (cons 'bar '())
 '())

或(评估(cons 'bar '()))

((lambda (newlat2 seen2)
   (list newlat2 (cons 'foo seen2)))
 '(bar)
 '())

现在,用值newlat2 = '(bar)seen2 = '()代替,我们得到

Now, substituting the values newlat2 = '(bar) and seen2 = '(), we get

(list '(bar) (cons 'foo '()))

或者换句话说,

(list '(bar) '(foo))

给出我们的最终结果

'((bar) (foo))

这篇关于解释《小骗子》第137页上的延续示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆