9

是否有任何 Common Lisp 的持久性解决方案,例如 Elephant,允许函数持久性?目前我的应用程序在数据库上存储一个标识符,然后在它所在的函数表中进行搜索,但是这种方法不允许存储动态创建的函数。

4

6 回答 6

4

它不是一种数据库持久性机制,但大多数 Common Lisps 都有一种为各种对象(包括函数)编写 FASL的方法。例如:

cl-user(1): (compile (defun hello () (format t "~&Hello~%")))
hello
nil
nil
cl-user(2): (excl:fasl-write (symbol-function 'hello) "/tmp/hello.fasl")
t
cl-user(3): (excl:fasl-read "/tmp/hello.fasl")
(#<Function hello @ #x1000a964d2>)

您可以写入流(为了方便起见,我在这里使用了文件),因此您可以轻松捕获这些字节并将它们填充到数据库中,如果您愿意的话。

于 2008-11-15T22:04:25.627 回答
3

Pascal Bourguignon在 comp.lang.lisp 上给出了标准解决方案。基本上,您必须将源表单写入文件,COMPILE然后再写入文件LOAD

(defvar *anon*)

(defun save-anonymous-function (fname args body)
  (let ((fname (make-pathname :type "LISP" :case :common :defaults fname)))
     (with-open-file (src fname :direction :output
                     :if-does-not-exist :create :if-exists :supersede)
       (print `(defparameter *anon* (lambda ,args ,body)) src))
     (compile-file fname)))

然后您必须读取该文件并将其存储在您的数据库中。要取回它,您需要从数据库中获取它并在加载之前将其写入文件中。

(defun load-anonymous-function (fname)
   (let ((*load-verbose* nil)
         (*anon* nil)) ; to avoid modifying the global one.
     (load fname)
     *anon*))
于 2008-11-18T08:47:01.753 回答
2

普通感冒可能是你想要的。它包括可序列化的闭包和可序列化的延续。

于 2008-11-16T19:14:29.010 回答
1

函数是不透明的对象,所以你不会很幸运地将它们存储在文件或类似的东西中。但是,您可以存储列表并在从数据库中检索时对其进行编译。

当然,这不会帮助您存储闭包。这将需要将词法环境与代码一起存储,而您都没有(可移植的)访问权限。从存储列表编译的代码必须完全依赖全局数据或存储在数据库中的数据。

顺便说一句,请注意您可以调用符号,因此您不需要用于全局函数的函数表。

于 2008-11-15T21:08:05.583 回答
1

您可以查看保存 Lisp 图像。这允许保存“足够的信息以在以后重新启动 Lisp 进程”。您可以在将函数加载到图像后保存它们。

这也可能比您所寻找的更高级,但这里是对该过程的(非常)简要介绍:保存核心图像

于 2008-11-15T21:23:12.807 回答
0

请注意,存储代码可能不是那么好。Zope 开发人员是通过艰难的方式学会了这一点的。

于 2008-11-26T14:21:28.877 回答