Little Schemer:什么是函数或参数的结构?

The Little Schemer: What is a function or argument's structure?

The Little Schemer 的第 3 章中,为什么我们不立即简化 rember 函数的问题的答案是 "because then a function's structure does not coincide with its argument's structure." 我有难以理解什么是函数的结构,什么是参数的结构,以及它们之间的区别。

这是未简化的版本:

(define rember
  (lambda (a lat)
    (cond
      ((null? lat) (quote ()))
      (else (cond
        (( eq? (car lat) a) (cdr lat))
        (else (cons (car lat)
          (rember a
            ( cdr lat)))))))))

这里是简化版:

(define rember
  (lambda (a lat)
    (cond
      ((null? lat) (quote ()))
      ((eq? (car lat) a) (cdr lat))
      (else (cons (car lat)
               (rember a (cdr lat)))))))

据我所知,主要区别在于函数已经从两个 cond 各问一个问题变成了 cond 问两个问题。

函数的参数是原子 "a" 和列表 "lat."

这是第一次,在密密麻麻的前言之外,书中提到了 "structure." 这个词 在我看来,到目前为止 "structure" 这个词的定义是可以解释的。

有人问过这个 exact question here before,但我无法理解答案。为什么二元结构与列表结构重合或不重合?在我看来,列表根本没有任何条件!

条件不是等同于Scheme中的问题吗?也许我误解了什么是条件,这可能是我沮丧的合理根源。无论如何,非常感谢对此的任何澄清!谢谢!

作者这里的“structure of function”大概是指函数体,也就是条件:

(cond
 ((null? lat) ...)
 (else ... (cond... (car lat) ... (cdr lat) ...)))

模式完全符合列表的“递归”定义,如:

  • 空列表,或
  • 一个至少包含一个元素(汽车)和一个列表(cdr)的值。

新定义将两个条件“折叠”在一个条件中,因此函数的“结构”(cond 的结构)不再反映“结构”它的列表参数。

List 是一种可以用一些伪代码定义的类型,如

(define-variant-record list
    ( () )               ; '() is a list
    ((hd . tl)           ; a cons pair (with car field named `hd` and cdr `tl`)
          (list tl)) )   ;  is a list, if `tl` itself is a list

然后,它可以用一个假设的(参见 EOPL)模式匹配结构来处理 variant-case:

(define rember
  (lambda (a lat)        ; an atom and a list of atoms
    (variant-case (lat)  ; follow the `lat` --
      ( ()               ; an empty list case, or
          (quote ()))
      ( (hd . tl)        ; a non-empty list, with car field `hd` and cdr `tl`
          (cond 
             (( eq? hd a) tl)
             (else 
                (cons hd
                      (rember a tl))))))))

其中,通过使用属于 list 数据类型定义的 variant-case,自然而明显地遵循其 结构 (即其定义的两种情况)。

第一个公式(带有嵌套的 conds)只是模拟不存在的 variant-case,可以显式访问具体的数据类型实现,cars和 cdrs 一样。

里面的cond不属于这个,只处理rember的细节。这就是为什么将两个 cond 合二为一可能会被视为将不相关的问题混合成一个大杂烩(一般来说;尽管这里两者都非常简单明了)。