首页 > 解决方案 > Clojure 比其他 lisps 的同音性更低吗?

问题描述

我记得在Clojure for Lisp Programmers 视频中重复过的一个说法是,早期 Lisp,尤其是 Common Lisp 的一个很大的弱点是,太多地与 Lisps 的列表结构,尤其是cons单元格结合在一起。您可以在链接视频的第 25 分钟处找到一次这种说法,但我确信我记得在该系列的其他地方听到过这种说法。重要的是,在视频的同一点,我们看到了这张幻灯片,它向我们展示了 Clojure 有许多其他的数据结构,而不仅仅是老式的 Lispy 列表: 在此处输入图像描述 这让我很困扰。我对 Lisp 的了解非常有限,但我一直被告知,其传奇的元可编程性的一个关键要素是,一切——是的,一切——都是一个列表,而且这就是防止我们在尝试对其他语言进行元编程时遇到的那种错误的原因。这是否表明通过添加新的一流数据结构,Clojure 降低了其同音性,从而使其比其他 Lisp(例如 Common Lisp)更难进行元编程?

标签: clojurelispcommon-lispmetaprogramminghomoiconicity

解决方案


是不是一切——是的,一切——都是一个清单

这对 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.

推荐阅读