代码之家  ›  专栏  ›  技术社区  ›  Prasoon Saurav

带有cons()的意外输出

  •  11
  • Prasoon Saurav  · 技术社区  · 14 年前

    我来自一个势在必行的背景,但这些天我在尝试我的Lisp(普通Lisp)

    我读 here 关于 cons 那个

    (CONS X L):

    给定lisp对象x和列表l,evaluation(cons x l)创建一个包含x的列表,后跟l中的元素。

    当我故意不使用列表作为第二个论点时,即当我使用

    (cons 'a 'a) 我以为会出错,但哇!我得到了 (A . A) .

    我错过了什么,错过了什么 (a)a) ?

    3 回复  |  直到 14 年前
        1
  •  7
  •   Svante    14 年前

    Cons 构造一个“cons cell”。这一开始与列表无关。cons单元格是两个值的对。cons单元以书面形式由“点对”表示,例如 (A . B) ,它保存两个值 'A 'B .

    cons单元中的两个位置称为“car”和“cdr”。您可以将这样一个cons单元格可视化为一个平分块:

      car   cdr
    +-----+-----+
    |  A  |  B  |
    +-----+-----+
    

    在Lisp中,值也可以是对其他内容的引用,例如,另一个cons单元格:

    +-----+-----+       +-----+-----+
    |  A  |   --------> |  B  |  C  |
    +-----+-----+       +-----+-----+
    

    这将以“点对”形式表示为 (A . (B . C)) . 您可以这样继续:

    +-----+-----+       +-----+-----+       +-----+-----+
    |  A  |   --------> |  B  |   --------> |  C  |  D  |
    +-----+-----+       +-----+-----+       +-----+-----+
    

    这是 (A . (B . (C . D))) . 如您所见,在这种结构中,值总是在 car 一个囚室,和 cdr 指向结构的其余部分。异常是最后一个值,它在最后一个值中 CDR . 不过,我们不需要这个例外:有一个特殊的值 NIL 在Lisp中,它表示“无”。通过放 进入最后 CDR ,你有一个方便的哨兵值,和 全部的 你的价值观在 汽车 S:

    +-----+-----+       +-----+-----+       +-----+-----+       +-----+-----+
    |  A  |   --------> |  B  |   --------> |  C  |   --------> |  D  | NIL |
    +-----+-----+       +-----+-----+       +-----+-----+       +-----+-----+
    

    这就是在Lisp中构造列表的方式。自从 (A . (B . (C . (D . NIL)))) 有点笨拙,也可以简单地表示为 (A B C D) . 也被称为空列表 () 这些是同一事物的可交换符号。

    现在你可以明白为什么 (cons x list) 返回另一个列表。 欺骗 只需使用 x 汽车 以及对 list CDR :

    +-----+-----+
    |  X  |   --------> list
    +-----+-----+
    

    如果 列表 (A B) ,计算结果如下:

    +-----+-----+       +-----+-----+       +-----+-----+
    |  X  |   --------> |  A  |   --------> |  B  | NIL |
    +-----+-----+       +-----+-----+       +-----+-----+
    

    所以, (cons x '(a b)) 评估为 (x a b) .

    列表只是cons单元格的一种非常常见的用法。实际上,还可以从cons单元格、循环列表或任何有向图构造任意树。

        2
  •  1
  •   msw    14 年前

    'a 是一个Lisp原子 (A . A) 是一个退化列表,称为 cons cell 或“点对”。因为你没有传递参数列表 L 在里面 (cons x L) 你回了一个牢房。

        3
  •  1
  •   Rainer Joswig mmmmmm    14 年前

    (CONS X L)

    给定x和l,cons返回一个新的cons单元格,其中x是该单元格的car,l是该单元格的cdr。

    列表是cons单元格的链接链。

    CL-USER 141 > (sdraw '(a b c))
    
    [*|*]--->[*|*]--->[*|*]---> NIL
      |        |        |
      v        v        v
      A        B        C
    
    CL-USER 142 > (sdraw (cons 'foo '(a b c)))
    
    [*|*]--->[*|*]--->[*|*]--->[*|*]---> NIL
      |        |        |        |
      v        v        v        v
     FOO       A        B        C
    

    如果cons得到两个符号作为参数,则如下所示:

    CL-USER 143 > (sdraw (cons 'foo 'bar))
    
    [*|*]---> BAR
      |
      v
     FOO