Common Lisp中分配内存的操作有哪些? (在语言实现的最小版本中)

What are the operations to allocate memory in Common Lisp? (in the minimal version of the language implementation)

我以为唯一的操作是cons,但好像还有其他操作。

任何创建新对象的操作都必然为其分配某种资源。列举这些东西几乎是不可能的,其中有些甚至没有名字。例如

(defun c (a)
  (lambda (b)
    (+ b a)))

可能会在每次调用时分配内存,当然有时必须这样做,但也可能没有什么能阻止 (eq (c 1) (c 1)) 是正确的。

(defun d ()
  (lambda (b)
    b))

永远不需要分配内存但可能会这样做(在实现中我试过它在解释代码中这样做,但在编译代码中不需要这样做)。

(defun e (a)
  (lambda (b)
    (incf a b))

必须始终分配(因此 (eq (e 1) (e 1)) 不可能为真)。

Lisp 系统必须以某种方式为其提供的所有对象类型提供内存分配和管理。 cons 函数是一个专用的 allocator/constructor 函数,仅适用于 cons 单元,以及由一个或多个 cons 单元组成的对象。 Common Lisps 还具有通常不是由 cons 单元构成的各种对象。

Common Lisp 标准语言不公开任何 low-level 内存分配。各种对象以三种方式产生:通过专用函数构造,如make-symbol;通过 reader 语法构建,并通过将现有值转换为新值。例如 (subseq "abcd" 1 3) 产生 "bc",这是一个新分配的字符串对象,其 bc 数据也可能是新分配的内存。

Common Lisp 实现者必须盘点要提供的所有各种类型的对象,为它们选择表示,并以某种方式实现所有这些功能,以及一些底层内存管理策略。可以有不止一个内存管理系统。一些对象可以由来自不同分配器的片段组成。例如。字符串对象可能来自与 conses 类似的分配器,利用所有此类对象的大小相等,但字符串的原始字符数据(由字符串对象引用)可能来自不同的分配器,用于字符串。