Binary 在数据库中存储Lisp编译函数

Binary 在数据库中存储Lisp编译函数,binary,lisp,persistence,common-lisp,clisp,Binary,Lisp,Persistence,Common Lisp,Clisp,CLISP允许我们这样做 (compile nil #'(lambda(x) (+ x 1))) 这将返回已编译的函数对象: #<COMPILED-FUNCTION NIL> # 是否可以将其导出为二进制字符串,以便将其持久化?比如说,将其保存在数据库中,以后可以加载并运行编译后的函数。不在可移植的Common Lisp中 而是将函数写入文件,使用compile-file编译文件。然后您就有了文件系统上的编译代码。您可以稍后加载该文件并运行该函数。您还可以将文件内容存储到数据库

CLISP允许我们这样做

(compile nil #'(lambda(x) (+ x 1)))
这将返回已编译的函数对象:

#<COMPILED-FUNCTION NIL>
#

是否可以将其导出为二进制字符串,以便将其持久化?比如说,将其保存在数据库中,以后可以加载并运行编译后的函数。

不在可移植的Common Lisp中

而是将函数写入文件,使用
compile-file
编译文件。然后您就有了文件系统上的编译代码。您可以稍后加载该文件并运行该函数。您还可以将文件内容存储到数据库中。如果以后需要,则需要将数据从数据库导出到文件中,并调用
LOAD
加载文件。

CLISP 是的,在CLISP中,您可以:

> (defparameter *my-function* (compile nil #'(lambda(x) (+ x 1))))
*MY-FUNCTION*
> *MY-FUNCTION*
#<COMPILED-FUNCTION NIL>
> (write-to-string *my-function* :readably t :pretty nil)
"#Y(|COMMON-LISP|::|NIL| #15Y(00 00 00 00 01 00 00 00 20 02 AD 32 B1 19 02) () (|COMMON-LISP|::|T| |COMMON-LISP|::|NIL| |COMMON-LISP|::|NIL|))"
> (defparameter *my-function-1* (read-from-string (write-to-string *my-function* :readably t)))
*MY-FUNCTION-1*
> (funcall *my-function-1* 10)
11
要恢复该功能,您需要使用:

注释

  • 在给定的实现中,的值可以合法地始终为
    nil
  • 如果实现编译为本机代码,则上述字符串将取决于平台
  • 我掩饰了包裹的问题

  • 我猜在不同的操作系统上使用CLISP是可以移植的,使用相同版本号的CLISP?是的,这在给定的CLISP字节码版本中是可以移植的。@sds所以即使升级CLISP也可能会毁掉它?@Sylwester:极不可能。我们对此非常小心。尽管CLisp的字节码本身是可移植的,但一些宏扩展可能是,而且很多是,依赖于平台的。IIIRC hu.dwim的家伙有一个库,甚至可以将闭包序列化到磁盘,但我不记得是哪一个。
    (defun function-string (func)
      (let ((lambda-expr (function-lambda-expression func)))
        (unless lambda-expr
          (error "no lambda expression for ~S" func))
        (let ((tmp-file "tmp.lisp") comp-file ret)
          (with-open-file (o tmp-file :direction :output)
            (write (list* 'defun my-tmp-func (cdr lambda-expr))
                   :stream o :readably t))
          (setq comp-file (compile-file tmp-file))
          (with-open-file (compiled comp-file :direction :input
                                    :element-type '(unsigned-byte 8))
            (setq ret (make-array (file-length compiled)
                                  :element-type '(unsigned-byte 8)))
            (read-sequence ret compiled))
          (delete-file tmp-file)
          (delete-file comp-file)
          ret)))
    
    (with-input-from-string (s (function-string *my-function*))
      (load s))
    (fdefinition 'my-tmp-func)