Lisp、cons和(number.number)差异

Lisp、cons和(number.number)差异,lisp,quote,cons,Lisp,Quote,Cons,两者的区别是什么 (cons 2 3) 及 口齿不清 (2.3)是一个点对 (cons 2 3)也会创建一个点对。因此,这些应该评估为相同的东西 因此,一个是点对的文本,另一个创建点对。它们并不完全相同,即使它们在REPL中的计算值相同。考虑这些例子,其中CONS单元被破坏性修改: TEST> (defun literal-cons () (let ((cons '(1 . 2))) (incf (cdr cons)) cons)

两者的区别是什么

(cons 2  3)

口齿不清

(2.3)是一个点对

(cons 2 3)
也会创建一个点对。因此,这些应该评估为相同的东西


因此,一个是点对的文本,另一个创建点对。

它们并不完全相同,即使它们在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)
(1 2 3)

从:

字面的。(指对象)在程序中直接引用而不是 而不是由程序计算;也就是说,以数据形式出现在 引用表单,或者,如果对象是自评估对象,则显示 作为未引用的数据``在形式(cons“one”(“two”))中 “一”、“二”和“二”是文字对象

(1.2)
cons
单元格的s表达式语法。cons单元有1个作为
car
,2个作为
cdr

”(1.2)
前面带有引号字符是
(引号(1.2))
的一种简短表示法。
引号
指示求值器不要(!)求值它所包含的表单,而只返回原样。这个被引用的表单的值就是表单本身<代码>报价表示:不要评估。在公共Lisp中,这可以被视为常量文字数据


(cons 1 2)
是一种Lisp格式,前面有函数
cons
,有两个参数:1和2。如果我们对这个表单求值,函数
cons
将被参数1和2调用
cons
根据定义返回一个新的cons单元格,其参数为
car
cdr
。因此,
(cons12)
在我们对其求值时返回一个新的cons单元格。

两者都是具有相似结构的对象。也就是说,它们都是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)等等。它们不相同,而且是相同的

simbol引号(')是一个函数,它说:“创建这个列表,而不计算它。” 例如:“(*2);它将创建列表(*2) (list(*2);它将创建(4),因为该列表是经过计算的

函数cons创建关联的对,仅此而已。 示例:(cons(abc)(1233));create(abc.1233) (反对a(1234));创造(a.1234)

在本例中,您使用的两个函数执行相同的操作,但使用不同的方法执行。
因为quote(')只需在simbol quote(')前面创建列表,cons函数只需创建与“iten”关联的对你给了函数什么。

第二个表达式中是句点还是逗号?@David:不知道是否可以更改你的答案选择。我喜欢danlei比我的好。你的
文本cons
函数的行为必须特定于你的实现。在SBCL上,我得到的结果是你的
非文本cons
。这是好奇之余,我提出了一个新的问题:@OpenLearner Right;修改文字数据的后果在标准中没有定义。任何事情都有可能发生。我认为这个答案中显示的示例很常见,但SBCL似乎在这里做了一些有趣的事情……事实上,
cons
会有不同生成一个可设置的位置,
quote
将生成一个不应修改的常量值。
(defun a () 
  (let ((v (cons 2 3))) 
   (incf (car v))
   v)

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