CLISP中引用符号的明显'eval'

djh*_*djh 3 lisp clisp common-lisp

CLISP REPL的一些输出:

[1]> (list 'list 1 2 3)
(LIST 1 2 3)

[2]> (list 'list '(1 2 3))
(LIST (1 2 3))

[3]> (list 'quote 1 2 3)
(QUOTE 1 2 3)

[4]> (list 'quote '(1 2 3))
'(1 2 3)
Run Code Online (Sandbox Code Playgroud)

前三个,我完全理解发生了什么:list函数传递一个符号('list'quote),因此结果是一个以listquote符号开头的列表.这是让我困惑的第四个问题.为什么不回来(QUOTE (1 2 3))

我意识到,如果你进入(QUOTE '(1 2 3))REPL,你会'(1 2 3)回来,所以表达在这个意义上是等价的.但是(LIST 1 2 3)相当于(1 2 3),但第一个表达式并没有返回.

似乎不一致的是(list 'quote 1 2 3)返回一个列表,第一个项目是一个quote符号,但(list 'quote (1 2 3))返回一个带引号的列表.特别是因为表达(list 'list ...)似乎总是返回一个以符号开头的列表 - 至少到目前为止,这quote是唯一的'特殊情况'.

这不是最容易表达的问题,所以我希望我能够解决这个问题.谁能解释为什么报价会以这种看似独特的方式得到对待?

Syl*_*ter 5

'something(quote something)与lisp阅读器相同.即使嵌套也是如此.下面的表达式我将双引号,以便在评估之后其中一个引号仍在那里.

当打印的实现可以选择什么来输出,其中有几个可能的表示,所以一些实现将打印的评价''something (quote something),而其他人可能使用缩写'something.

'(quote 1 2 3)不能缩写,因为引用的形式只有一个参数.因此,这两个lisp系统都会打印出来(quote 1 2 3).

这是查看最后一个表达式的方法:

(let ((data (list 'quote '(1 2 3))))
  (format nil 
          "whole thing: ~a first element: ~a second-element: ~a" 
          data 
          (car data) 
          (cadr data)))
Run Code Online (Sandbox Code Playgroud)

这将评估为"whole thing: '(1 2 3) first element: QUOTE second-element: (1 2 3)""whole thing: (QUOTE (1 2 3)) first element: QUOTE second-element: (1 2 3)".

由于打印机从未看到输入是否缩写且数据在内存中具有相同的结构,因此输出不会受输入数据的影响.因此(quote (quote (1 2 3)))将打印相同''(1 2 3).

您对cons单元格具有相同的行为,但标准规定了规则.(cons 1 (cons 2 (cons 3 '())))将是(1 . (2 . (3 . ())))但实际上只是打印(1 2 3)但是如果(cons 1 2)你得到(1 . 2)显示,print以不同的方式对待输出cdr.然而,读者可以阅读这些中的任何一个,并且它们将全部打印相同的例如.'(1 . (2 . (3 . ()))) ==> (1 2 3)(+ . (2 . ( 3 . ()))) ; ==> 5

数字可以具有与所讨论的数字之下的基数一样多的视觉形式.

(let ((*print-base* 16))
  (print 255)) ; prints FF (255 in hexadecimal)
Run Code Online (Sandbox Code Playgroud)

list在Lisp中没有任何缩写或特殊性.它甚至不是一个原始的功能,但它非常有用,因为它消除了每次必须手工使用的不便.它可以这样定义:

(defun my-list (&rest lst)
  lst)

(my-list 1 2 3 4) ; ==> (1 2 3 4)
Run Code Online (Sandbox Code Playgroud)