Common Lisp:如何引用SBCL中的括号

时间:2015-02-27 11:31:38

标签: lisp common-lisp sbcl quote

在Common Lisp中,特殊运算符 quote 会生成未评估的内容,例如

(quote a) -> a
(quote {}) -> {}

但是为什么表单(quote())给了我 nil ?我使用的是SBCL 1.2.6,这是我在REPL中得到的:

CL-USER> (quote ())
NIL

有关此问题的更多信息:这是PCL第24章中的一些代码

(defun as-keyword (sym)
  (intern (string sym) :keyword))

(defun slot->defclass-slot (spec)
  (let ((name (first spec)))
    `(,name :initarg ,(as-keyword name) :accessor ,name)))

(defmacro define-binary-class (name slots)
  `(defclass ,name ()
     ,(mapcar #'slot->defclass-slot slots)))

当宏展开以下代码时:

(define-binary-class id3-tag
    ((major-version)))

(DEFCLASS ID3-TAG NIL
      ((MAJOR-VERSION :INITARG :MAJOR-VERSION :ACCESSOR MAJOR-VERSION)))
在课程名称 ID3-TAG 之后

NIL 而不是()

2 个答案:

答案 0 :(得分:7)

nil()是表达相同概念的两种方式(空列表)。

传统上,nil用于强调布尔值“false”而不是空列表,而()则用于反过来。

Common LISP HyperSpec says

  

()['nil],n。用于编写符号nil的备选表示法   强调使用 nil 作为空列表

答案 1 :(得分:3)

您的观察是由于对象有多个表示。在Common Lisp中,读者(读取代码和读取表达式)将文本解析为结构和数据。当它的数据时,编写者可以再次打印出来,但是在最初读入数据时,它不会确切地知道数据是如何表示的。编写器将按照默认值和设置以一种方式打印一个对象,即使有多个表示对于那个对象。

您注意到nilNILnILNiL,...,'nil'NIL,{{1} }和()都被读作同一个对象。我不确定标准是否应该确切地说明它的默认表示应该如何,所以我猜一些实现选择'()NIL或甚至nil之一。

有缺点,表示取决于()是否为缺点:

cdr

通过数字,读者可以获得有关您正在使用哪个基础的提示。如果文本中没有使用任何基础,它将使用'(a . nil) ; ==> (a) '(a . (b . c)) ; ==> (a b . c) '(a . (b . nil)) ; ==> (a b)

*read-base*

(let ((*read-base* 2)) ; read numbers as boolean (read-from-string "(10 #x10)")) ; ==> (2 16) 告诉读者将其余部分解释为十六进制值。现在,如果你的 print-base 已经是4,那么上面的答案将被视为#x

总结一下.Common Lisp中的单个值可能有几个很好的表示形式,所有这些值都会产生相同的值。如何打印值将遵循生成它们的函数的实现,设置甚至参数。它不接受作为值的内容或者它可以使值可视化的不同方式都没有说明值实际如何在内部存储。