1

The Little Schemer(第 4 版)中,声称一个错误的列表null?至少包含一个 atom,或者我从阅读文本中了解到。

这对我来说没有意义,因为(atom '())它是错误的,我们可以将它们粘贴到一个列表中以使其非空:

> (null? '(()))
#f

所以我的问题是,这是我的阅读错误,还是定义问题?由于它不在勘误表中,我认为这样一本经过充分研究的书不会有这样的错误。

如果我们认为(())与原子相同(() . ())或什 (cons '() '())至然后考虑cons原子,那么我可以看到您如何到达那里,但我认为这不是正在发生的事情。

(这是在 Racket 7.0 中测试的,atom?书中给出的定义,即

(define atom?
  (lambda (x)
  (and (not (pair? x)) (not (null? x)))))

我知道这不包括有趣的球拍功能,但在这里应该足够了。)

4

3 回答 3

2

lat假定为书中该点的原子列表。

如果它不是空的,根据定义它包含一些原子。

这不是关于 Lisp,而是关于这本书的介绍。

于 2018-12-13T13:05:27.383 回答
1

我认为lat表示原子列表。因此,如果latis not null?,则它需要包含至少一个原子。

有一个称为lat?定义的过程:

(define lat?
  (lambda (l)
    (cond
      ((null? l) #t)
      ((atom? (car l)) 
       (lat? (cdr l)))
      (else #f))))

(lat? '(()) ; ==> #f所以根据定义'(())不是 a lat,因此该声明不适用于该列表。

列表可以包含任何类型的元素,包括空列表和其他列表,它们都不是原子。lat是一个仅限于只有原子元素的平面列表。

于 2018-12-13T13:16:59.130 回答
1

作为一个概念,“原子”是不能分解成更小部分的东西。数字 42 是一个原子,一个列表 (42 43) 不是一个原子,因为它包含两个较小的部分(即数字 42 和 43)。由于空列表不包含任何较小的部分,因此按此逻辑它是一个原子。

现在让我们尝试实现一个atom?谓词,确定它的输入是否是一个原子。

(define (atom? x)
  (cond
     [(number? x) #t]
     [(symbol? x) #t]
     [(char? x)   #t]
     ...
     [else #f]))

这里 ... 需要替换为实现支持的每种原子数据类型的测试。这可能是一个很长的列表。为了避免这种情况,我们可以尝试聪明一点:

(define (atom? x)
  (not (list? x)))

对于非空列表,这将正确返回 false,对于数字、字符等返回 true。但是,对于空列表,它将返回 false。

由于由本书的作者来定义术语“原子”(这个词没有出现在语言标准中),他们可能选择了上述简单的定义。

请注意,当语言包含其他复合数据结构(例如向量和结构)时,作为非列表的定义会产生误导。如果我没记错的话,书中讨论的唯一复合数据结构是列表。

于 2018-12-13T16:45:43.050 回答