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),因此结果是一个以list或quote符号开头的列表.这是让我困惑的第四个问题.为什么不回来(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是唯一的'特殊情况'.
这不是最容易表达的问题,所以我希望我能够解决这个问题.谁能解释为什么报价会以这种看似独特的方式得到对待?
'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)