Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function persistence in Common Lisp

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.

like image 922
AticusFinch Avatar asked Nov 15 '08 20:11

AticusFinch


2 Answers

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.

like image 161
Rich Avatar answered Oct 01 '22 09:10

Rich


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*))
like image 42
kmkaplan Avatar answered Oct 01 '22 11:10

kmkaplan