Little Schemer:为什么将(mk-length mk-length)包装为一个函数? [英] Little Schemer: why wrap (mk-length mk-length) into a function?

查看:147
本文介绍了Little Schemer:为什么将(mk-length mk-length)包装为一个函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在第9章的《小策划者》书中,而为任意长输入构建length函数,建议执行以下操作(在第168页本身):

In The Little Schemer book, in Chapter 9, while building a length function for arbitrary long input, the following is suggested (on pages 170-171), that in the following code snippet (from page 168 itself):

((lambda (mk-length)
   (mk-length mk-length))                      
 (lambda (mk-length)
   ((lambda (length)                           
      (lambda (l)
        (cond
          ((null? l) 0)
          (else (add1 (length (cdr l)))))))   
    (mk-length mk-length))))                   

(mk-length mk-length)部分将永远不会返回,并将无限地将其自身应用于自身:

the part (mk-length mk-length), will never return and will be infinitely applying itself to itself:

因为我们一直不断地将mk-length应用于自身...

Because we just keep applying mk-length to itself again and again and again...

但是现在我们已经从使length的函数中提取了(mk-length mk-length),它不再返回任何函数.

But now that we have extracted (mk-length mk-length) from the function that makes length it does not return a function anymore.

现在,要治愈这本书,建议:

Now, to cure this the book suggest:

将最后一个正确版本的length中的mk-length应用程序本身转换为函数.

Turn the application of mk-length to itself in our last correct version of length into a function.

就像这样:

((lambda (mk-length)
   (mk-length mk-length))
 (lambda (mk-length)
   ((lambda (length)
     (lambda (l)
       (cond
         ((null? l) 0 )
         (else 
           (add1 (length (cdr l)))))))
   (lambda (x)
     ((mk-length mk-length) x)))))

我不解的是:

  1. 如果(mk-length mk-length)

不返回函数

does not return a function

我们如何将(mk-length mk-length)的结果应用于某事物,就好像它是一个函数一样?

how we can apply the result of (mk-length mk-length) to something, as if it is a function?

(lambda (x)
  ((mk-length mk-length) x))

  • 如何将(mk-length mk-length)包装到函数中解决永不返回"(即无限递归)问题?我的理解是:

  • How wrapping (mk-length mk-length) into a function solves the 'never returning' (i.e. infinite recursion) problem? My understanding is, that in:

    (lambda (x)
      ((mk-length mk-length) x))
    

  • x将仅传递给永不递归的函数,该函数永远不会返回.

    x will just be passed to infinitely recursive function, which never returns.

    推荐答案

    您可能复制了错误的代码段,即您实际谈论的代码段之前的代码段.您显示的第一个代码完全没问题.循环是这个:

    You probably copied the wrong code snippet, the one before that which you actually talk about. The first code you've shown is totally fine. What loops is, rather, this one:

       ((lambda (mk-length)
          (mk-length mk-length))                      ; (1)
        (lambda (mk-length)
          ((lambda (length)                           ; (2)
             (lambda (l)
               (cond
                 ((null? l) 0)
                 (else (add1 (length (cdr l)))))))    ; (4)
           (mk-length mk-length))))                   ; (3)
    

    已经在此处回答了:应用程序(1)触发应用程序(2),触发应用程序 立即,相当于(1)!因此,循环.

    This is already answered here: the application (1) triggers the application (2) which triggers the application (3) right away, which is equivalent to (1)! Thus, the looping.

    将其包装为lambda(也称为 eta-expansion )会延迟应用程序(3),直到在(4)中对构造的length进行调用为止,这完全可以(您复制了还有一些错别字):

    Wrapping it in a lambda (aka eta-expansion) delays the application (3) until the call to the constructed length is made in (4), and that's fully OK (you copied this with some typos as well):

       ((lambda (mk-length)
          (mk-length mk-length))                      ; (1)
        (lambda (mk-length)                                   ; (5)
          ((lambda (length)                           ; (2)
             (lambda (l)
               (cond
                 ((null? l) 0)
                 (else (add1 (length (cdr l)))))))    ; (4)
           (lambda (x)                                ; (3)
             (mk-length mk-length) x))))
    

    (3)现在是lambda表达式,而不是应用程序.评估此lambda表达式会产生一个匿名函数.当调用length时,此lambda函数 将执行应用程序(mk-length mk-length) 以后.

    (3) is a lambda expression now, not an application. Evaluating this lambda expression produces an anonymous function. This lambda function will perform the application (mk-length mk-length) later, when length is called.

    (更长的解释:) (3)立即返回绑定到length的lambda函数,并愉快地返回(lambda (l) ...),以便将 that (lambda (l) ...) will 应用于一些列表,可能导致此length 1 (4)中被调用,只有 then 在lambda (3)内部的应用程序(mk-length mk-length)才会被实际执行&mdash ;最终为我们提供了新的(lambda (l) ...)匿名函数,该函数将在那里应用到(cdr l).

    (a longer explanation:) (3) just returns the lambda function right away which gets bound to length, and (lambda (l) ...) is happily returned such that when that (lambda (l) ...) will be applied to some list, possibly causing this length1 to be called in (4), only then the application (mk-length mk-length) inside the lambda (3) will actually be performed — giving us the new (lambda (l) ...) anonymous function eventually, which will get applied to the (cdr l) there.

    1 length(lambda (x) ((mk-length mk-length) x)),这意味着(length (cdr l))((mk-length mk-length) (cdr l))相同(mk-length绑定到整个lambda表达式(5)),并最终,((lambda (l) ...) (cdr l)).

    1length is (lambda (x) ((mk-length mk-length) x)) which means that (length (cdr l)) is the same as ((mk-length mk-length) (cdr l)) (with mk-length bound to the whole lambda-expression (5)), and eventually, ((lambda (l) ...) (cdr l)).

    尼娜

    这篇关于Little Schemer:为什么将(mk-length mk-length)包装为一个函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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