4

和有什么区别

(cons 2  3)

'(2 . 3)

在 Lisp 中?

4

5 回答 5

10

它们并不完全相同,即使它们在 REPL 中评估为相同的值。考虑这些示例,其中 cons 单元被破坏性地修改:

TEST> (defun literal-cons ()
        (let ((cons '(1 . 2)))
          (incf (cdr cons))
          cons))
LITERAL-CONS
TEST> (literal-cons)
(1 . 3)
TEST> (literal-cons)
(1 . 4)
TEST> (literal-cons)
(1 . 5)

与此相比:

TEST> (defun non-literal-cons ()
        (let ((cons (cons 1 2)))
          (incf (cdr cons))
          cons))
NON-LITERAL-CONS
TEST> (non-literal-cons)
(1 . 3)
TEST> (non-literal-cons)
(1 . 3)

在第一个版本中,您正在更改代码本身中的文字cons 单元格(因此,这是自修改代码)。在第二个版本中,cons 单元格不是文字的。每次调用代码时都会生成它,并且只会更改这个新的 cons 单元格。

TEST> (function-lambda-expression #'literal-cons)
(LAMBDA NIL
  (DECLARE (CCL::GLOBAL-FUNCTION-NAME LITERAL-CONS))
  (BLOCK LITERAL-CONS (LET ((CONS '(1 . 5))) (INCF (CDR CONS)) CONS))) ;; notice the '(1 . 5)
NIL
LITERAL-CONS

由于在使用破坏性操作时这可能会导致细微的错误,因此应该小心代码中的此类文字对象。这也会影响由 cons 单元构建的列表文字('(1 2 3)vs. )。(list 1 2 3)

超规格

字面上的形容词。(对象的)在程序中直接引用而不是由程序计算;也就是说,以引用形式显示为数据,或者,如果对象是自评估对象,则显示为未引用的数据。``在 (cons "one" '("two")) 形式中,表达式 "one"、("two") 和 "two" 是文字对象。''

于 2011-07-28T21:46:28.663 回答
2

两者都是具有相似结构的对象。也就是说,它们都是 cons 单元,其中 2 个在 CAR 位置,3 个在 CDR 位置。

它们之间的主要区别在于 '(2 . 3) 是一个常数,而 (cons 2 3) 生成一个新的 cons 单元格。如果您采用以下两个(外观相似的)功能,则它们之间的区别应该变得明显:

(defun a () 
  (let ((v (cons 2 3))) 
   (incf (car v))
   v)

(defun b () 
  (let ((v '(2 . 3))) 
   (incf (car v))
   v)

当您继续调用 b 时,相当多的实现将返回 '(3 . 3) '(4 . 3) 等等。

于 2011-07-29T11:56:19.640 回答
1

'(2 . 3)是一个点对。

(cons 2 3)也创建了一个虚线对。所以这些应该评估为同一件事。

所以一个是一个点对的文字,另一个创建一个点对。

于 2011-07-28T20:22:04.183 回答
0

(1 . 2)cons单元格的 s 表达式语法。cons 单元格有 1 作为 thecar和 2 作为cdr.

'(1 . 2)前面有引号字符是 . 的简写(quote (1 . 2))。指示评估者不要(!)评估它所包含的quote表单,并按原样返回它。这个引用表单的值就是表单本身。quote说:不评价。在 Common Lisp 中,这可以被认为是常量文字数据。

(cons 1 2)是一个 Lisp 形式,cons前面有函数和两个参数:1 和 2。如果我们评估这种形式,函数cons会被调用,参数为 1 和 2。cons根据定义返回一个新的 cons 单元格,其参数为carand cdr。因此(cons 1 2),每当我们评估它时,都会返回一个新的 cons 单元格。

于 2011-07-29T01:08:32.183 回答
0

它们不一样而且是一样的。

simbol 引号 (') 是一个函数,它说:“创建这个列表而不评估它。” 例如:'(* 2 2); 它将创建列表 ( * 2 2 ) (list (* 2 2) ; 它将创建 (4) 因为列表已被评估。

函数 cons 创建关联的对,仅此而已。示例: (cons (abc) (1 2 3) ) ;create (abc . 1 2 3) (cons a (1 2 3 4) ) ;create (a. 1 2 3 4)

您使用的两个函数在这种情况下执行相同的操作,但使用不同的方法来执行此操作。因为引号 (') 只是在 simbol 引号 (') 前面创建列表,而 cons 函数只是创建与您给函数的“itens”相关的对。

于 2011-07-31T04:00:00.987 回答