Lisp plist 仅在符号的 属性 列表单元格的上下文中?

Lisp plist only in context of symbol's property list cell?

基本上,我想知道在内置符号 属性 列表的概念之外,Common Lisp 中是否存在 plist 这样的东西。所以如果我有

(setq Joe '(:fav-season  "Fall" :fav-color  "Blue"))

然后我做

(setf (get 'Joe 'fav-season) "Summer")
(setf (get 'Joe 'fav-color) "Green")

我有两个单独的 plists 与 Joe 相关联,一个是临时的,另一个 "official" 因为它绑定到 符号 Joe.

(get 'Joe 'fav-color)
"Green"

(symbol-plist 'Joe)
(FAV-COLOR "Green" FAV-SEASON "Summer")

所以我假设直接将类似 plist 的结构分配给 Joe(分配给符号 Joes 的值单元格)不是真正受支持的数据结构(如 getgetf 等),就像符号 Joe 的 属性 列表一样。也不是作为一个列表,它始终是一个变量的值并且具有 assocrassoc 等。因此我可以得出结论,除了内置之外,在现实世界中确实没有使用 plist 概念-在 属性 列表的符号单元格中?所以经常在教程中,plist 被自动描述为符号的 属性 列表,并且没有进一步讨论这个概念。

我想以一种倒退的方式,我正在追求关于 Lisp 中什么是好的、最佳实践数据结构的相当模糊、参差不齐的想法。

使用 GETF 从列表中检索值,这是一个 属性 列表。

CL-USER 141 > (let ((joe '(:fav-season  "Fall"
                           :fav-color  "Blue")))
                (list (getf joe 'fav-color)
                      (getf joe :fav-color)))
(NIL "Blue")

请注意,您需要正确设置 指标

你已经使用了GET,可以按照GETF:

来实现
(defun get (x y)
  (getf (symbol-plist x) y))

因此可以使用 属性 列表,而不仅仅是在符号 属性 列表中 - 有一个基本的运算符。

另请注意,还有许多其他数据结构允许通过键访问值:关联列表、CLOS 类、哈希表。这些用例略有不同。

属性 当需要在列表中使用简单的键和值数据时,通常会使用列表 - 例如在源代码中。

函数使用 属性 类似列表的关键字参数列表,可以操作:

(let ((foo (list 'window :x 100 :y 200)))
   (setf (getf (rest foo) :x) 200)
   (apply #'make-instance foo))

有时 属性 列表会添加到 CLOS 类 或结构中。 Common Lisp 中的结构在运行时可能不可扩展——它们不能用额外的槽重新定义。所以通常一些 类 和结构有一个属性槽,其中一个可以在运行时 add/remove/updated key/value 对。

不,它们作为轻量级“地图”结构被无处不在地使用。例如,在流行的库 alexandria 中,有一些函数可以在 alists、plists 和哈希表之间进行转换。而是 symbol-plists 已经不再使用了。

如果您将符号用作一种“对象”,而不仅仅是用作变量的名称,那么它的 plist 会非常有用。例如,在构建表示偏序(偏序集)的数据结构时,我使用符号作为偏序集元素。偏序集的给定元素 x 将有过去,但也有未来等。这些“值”中的一个或两个可以方便地保留在 plist 上。如果你想“标记”一个元素,也可以使用 plist;这种技术在编写算法时非常有用,例如找到偏序集的最小值。