语境:
我已经启动了一个 CL 长期项目,其中一个子组件是惰性编程框架,旨在尽可能与外部 CL 代码兼容。
其中一门课是lazy-cons.
(defclass lazy-cons (thunk sequences:sequence)
((head :initform nil :initarg :head :accessor :head)
(tail :initform nil :initarg :tail :accessor :tail))) ;; slot 'gen is defined in the thunk superclass, as well
Run Code Online (Sandbox Code Playgroud)
然而,当尝试对超过 100 万个数字的惰性列表进行排序时,SBCL 不断耗尽堆空间并崩溃。
尝试的方法:
我已经实现了另一个类,可以通过缓存向量减少这个问题。
但我仍然想让lazy-cons自己更加节省空间,因为这个项目旨在成为其他计算项目的后台框架,其中一些项目需要高性能计算。即使最高性能的代码最终传递给 CFFI,Lisp 端仍然应该尽可能高效和可扩展。
对于这个项目,我还需要能够扩展类并用于defmethod专门化某些功能(例如,这样我就可以使用该trivial-extensible-sequences库)。这排除了使用structures较小的表示,因为structure元类不允许从普通类继承。
问题:
是否有可能(例如通过 MOP?)更有效地控制对象的内部表示,同时仍然允许类继承和方法专门化?
如果没有,是否有某种方法至少可以防止 Lisp 实现耗尽堆空间?
(我知道你可以增加分配的堆,但这仍然不能保证你不会意外地陷入LDB;理想情况下,当堆被分配时,代码应该陷入一种情况(可以自动解决)即将失败,而不仅仅是崩溃。)