Question

Is there any persistence solution for Common Lisp, such as Elephant, that allows function persistence? Currently my app stores an identifier on the db and later searches in a function table which it is, but this method does not allow dynamically created functions to be stored.

Was it helpful?

Solution

It's not a database persistence mechanism, but most Common Lisps have a way of writing FASLs for all kinds of objects, including functions. For example:

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>)

You can write to a stream (here I used a file for convenience), so you can trivially capture those bytes and stuff them into a database if you wished.

OTHER TIPS

Pascal Bourguignon gave a standard solution on comp.lang.lisp. Basically you have to write the source form to a file and COMPILE it then LOAD it.

(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)))

Then you’ll have to read the file and store it in your database. To get it back you’ll need to fetch it from the database and write it in a file before loading it.

(defun load-anonymous-function (fname)
   (let ((*load-verbose* nil)
         (*anon* nil)) ; to avoid modifying the global one.
     (load fname)
     *anon*))

Common Cold might be what you want. It includes serializable closures and serializable continuations.

Functions are opaque objects, so you won't have much luck storing them in files or something like that. You can, however, store lists and compile them upon retrieval from the database.

This won't help you store closures, of course. That would entail storing the lexical environment along with the code, neither of which you have (portable) access to. Code that you compile from stored lists will have to rely entirely on global data or data stored in the database.

By the way, note that you can funcall symbols, so you don't need a function table for global functions.

You can look into saving Lisp images. This allows saving "enough information to restart a Lisp process at a later time." You can have your functions saved after you have loaded them into your image.

This may also be a bit more advanced than what you were looking for, but here is a (very) brief introduction to the process: Saving a Core Image

Be careful that storing code may not be that good. The Zope developers learned it the hard way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top