非空 Scheme 列表是否包含至少一个原子?

Does a non-null Scheme list contain at least one atom?

The Little Schemer (4th Ed.) it is claimed that a list for which null? is false contains at least one atom,或者我看课文是这样理解的

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

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

所以我的问题是,这是我阅读的错误,还是定义的问题?因为它不在勘误表中,所以我认为这样一本研究得很好的书不会有这样的错误。

如果我们将 (()) 视为与 (() . ()) 甚至 (cons '() '()) 相同,然后将 cons 视为一个原子,那么我可以看到您如何到达那里,但我不认为这是怎么回事。

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

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

我知道这没有涵盖有趣的 Racket 功能,但在这里应该足够了。)

lat 假设一个原子列表书中的点。

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

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

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

有一个名为 lat? 的过程定义如下:

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

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

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

作为一个概念,“原子”是不能分解成更小部分的东西。数字 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)))

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

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

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