代码之家  ›  专栏  ›  技术社区  ›  Galladite

为什么(nil.nil)在SBCL中评估为(nil)而不是仅为nil?

  •  1
  • Galladite  · 技术社区  · 2 年前

    在SBCL REPL中,为什么输入(nil.nil)的结果是(nil)而不仅仅是nil?

    如果一个空列表是cons单元格的两个“元素”都为零的列表,为什么它们不相同?

    我对此的假设是,SBCL进行了以下评估:

    (car '()) => nil
    (cdr '()) => nil
    (car '(nil . nil)) => nil
    (cdr '(nil . nil)) => nil
    

    然而:

    '() => nil
    '(nil . nil) => (nil)
    
    1 回复  |  直到 2 年前
        1
  •  2
  •   Silvio Mayolo    2 年前

    car cdr 回来 nil 如果给定 作为论据。让我们先入为主 等一下,看看你有什么价值观 事实上 看着。

    (car '()) == '()
    (cdr '()) => nil
    

    汽车 cdr 得到一个空列表,所以我们返回 () .

    (car '(nil . nil)) => nil
    (cdr '(nil . nil)) => nil
    

    现在 (nil . nil) (() . ()) 。也就是说,这是一个cons cell,它的car和cdr都是 .

    当我们有 . () 在cons单元格的末尾,我们可以通过省略尾部来用符号缩短它 。这只是一个符号上的方便,所以通过我们的符号 (() .()) 可以写成 (()) (nil) 。请注意,确实如此 更改值。最明确的写作方式仍然是 (() .()) ,但为了可读性,我们也可以将其写得更短。

    如果一个空列表是cons单元格的两个“元素”都为零的列表,为什么它们不相同?

    这是不对的。空列表是 一个囚犯牢房。空列表就是原子 。这是一个象征,就像 'foo 'pizza 'common-lisp 。这只是我们选择用于此目的的一个符号。但是 汽车或cdr电池。碰巧的是,让 (car nil) (cdr nil) 作为算法的角落案例,因此 功能 汽车 cdr 在上有特殊行为 但是 一个囚犯牢房。

    > (consp nil)
    nil
    > (consp '())
    nil
    > (consp '(1 . 2))
    T
    

    根据 system class LIST 这个 list 类型可以描述为

    类型 cons null 形成类型列表的详尽分区。

    所以 列表 在Common Lisp中,它被定义为“cons单元格或特殊值 ”。值得注意的是, 本身并不是一个cons细胞。