我记得在Clojure for Lisp Programmers videos中反复提到的一种说法是早期Lisps,特别是Common Lisp,太多东西与Lisps的列表结构结合在一起,特别是
cons
单元。您可以在链接视频的25分钟标记处找到这种说法的一个发生,但我确信我记得在系列其他地方也听过它。重要的是,在视频的同一点上,我们看到了这张幻灯片,向我们展示了Clojure不仅有老派Lispy列表,还有许多其他数据结构:
![enter image description here](https://istack.dev59.com/vpNAL.webp)
cons
单元。您可以在链接视频的25分钟标记处找到这种说法的一个发生,但我确信我记得在系列其他地方也听过它。重要的是,在视频的同一点上,我们看到了这张幻灯片,向我们展示了Clojure不仅有老派Lispy列表,还有许多其他数据结构:
一切,完全的一切,都是列表
但对于Lisp来说,这从来不是真实的。
CL-USER 1 > (defun what-is-it? (thing)
(format t "~%~s is of type ~a.~%" thing (type-of thing))
(format t "It is ~:[not ~;~]a list.~%" (listp thing))
(values))
WHAT-IS-IT?
CL-USER 2 > (what-is-it? "hello world")
"hello world" is of type SIMPLE-TEXT-STRING.
It is not a list.
CL-USER 3 > (what-is-it? #2a((0 1) (2 3)))
#2A((0 1) (2 3)) is of type (SIMPLE-ARRAY T (2 2)).
It is not a list.
CL-USER 4 > (defstruct foo bar baz)
FOO
CL-USER 5 > (what-is-it? #S(foo :bar oops :baz zoom))
#S(FOO :BAR OOPS :BAZ ZOOM) is of type FOO.
It is not a list.
CL-USER 6 > (what-is-it? 23749287349723/840283423)
23749287349723/840283423 is of type RATIO.
It is not a list.
由于Lisp是一种可编程的编程语言,我们可以为非列表数据类型添加外部表示:
为FRAME类添加一个原始符号。
CL-USER 10 > (defclass frame () (slots))
#<STANDARD-CLASS FRAME 4210359BEB>
打印机:
CL-USER 11 > (defmethod print-object ((o frame) stream)
(format stream "[~{~A~^ ~}]"
(when (and (slot-boundp o 'slots)
(slot-value o 'slots))
(slot-value o 'slots))))
#<STANDARD-METHOD PRINT-OBJECT NIL (FRAME T) 40200011C3>
CL-USER 12 > (set-macro-character
#\[
(lambda (stream char)
(let ((slots (read-delimited-list #\] stream))
(o (make-instance 'frame)))
(when slots
(setf (slot-value o 'slots) slots))
o)))
T
CL-USER 13 > (set-syntax-from-char #\] #\))
T
CL-USER 14 > [a b]
[A B]
CL-USER 15 > (what-is-it? [a b])
[A B] is of type FRAME.
It is not a list.
->>
的含义),但我很期待有一天能学会编写自己的宏 :) - Aaron Belllet
符号/表达式对等周围。所有这些都可以用于数据字面量,但与函数调用和宏调用相比,数据字面量在编写Clojure宏时使用较少。代码
是数据
”:即编程语言的代码由该语言的数据结构100%组成,因此可以使用语言中通常用于操作数据结构的函数轻松地进行构建和操作。