[cl-store-devel] Writing functions into files

Gustavo gugamilare at gmail.com
Sun Mar 1 22:43:41 UTC 2009


Hello,

Just reporting something I've managed to do. I've created a project named
storable-functions, it is in my github account:

http://github.com/gugamilare/storable-functions/tree/master

I've managed to successfully write portable code (needs trivial-garbage,
metatilities and cl-store) that can write functions into files - with the
restriction of using a small set of macros to "mark" closures and the
functions themselves. I believe it would be possible to add other
serialization libraries as the backend (I programmed for that purpose - the
code which depends on cl-store is small and separated in a asdf system named
cl-store+functions) but right now only code for cl-store has been written.
An extensive test suite has also been written, it needs lift.

This is the most simple storable function:

(st (lambda (a b)
      (the fixnum (+ (the fixnum a)
                     (the fixnum b)))))

It is possible to use (st-lambda ...) instead of (st (lambda ...)). The next
one uses a closure:

(st (let ((acc 0))
  (declare (fixnum acc))
  (st (lambda (&optional (diff 1))
        (the fixnum (incf acc (the fixnum diff)))))))

Declarations are kept after restorage. Again, you can use (st-let ...)
instead of (st (let ...)). And the next one ilustrates the most important
achievement, multiple functions sharing a closure:

(st (let ((acc 0))
  (declare (fixnum acc))
  (list (st (lambda (&optional (diff 1))
              (incf acc (the fixnum diff))))
        (st (lambda (&optional (value 0))
              (setf acc (the fixnum value)))))))

The two functions returned there share the same closure, and that will be
true after restorage IF they are stored in the same file, e.g., in a list or
in slots of a class instance. Nothing is guaranteed if you store one
function in one file and the other function in another file and restore
them.

Other closures supported are let*, labels, flet, macrolet and
symbol-macrolet (the last two were not tested yet). Another feature is using
st around a function call that possibly return a function. For instance:

(st (compose #'cadr #'reverse))
(st (curry #'list 1 2 3 4))

The arguments of the functions compose and curry can be easily stored in a
file using cl-store. That is what this macro do here: it evaluates all the
arguments of the function calls (binding them to a some variables), calls
the function (e.g. compose) with the arguments (#'cadr and #'reverse) and,
if the call returns a function (say, the function f), it makes the
arrangements for storing the arguments when the function is to be stored. In
order to restore the function f, it calls again the same function (e.g.
compose) with the "same" arguments (#'cadr and #'reverse) and takes the
returned values as being f. Fortunatelly, compose and curry do not have side
effects, so there is no problem calling them every time the function f is
stored to or restored from a file.

There is also a macro stq which stores the entire form (it does not evaluate
and store the function arguments, instead it stores the whole form - it is
intended to be used with macros), but it is not working yet, and I am tired
to see what is going on right now.

In order to store / restore functions, the backend named
cl-store+functions:cl-store+functions should be used. This backend is
compatible with the default backend cl-store (except that register-code
won't work for the new backend after loading the system cl-store+functions).

I guess that's all for now. Any suggestions, comments, bug fixes are
welcome, as usual. Just e-mail me: gugamilare at gmail.com.

Gustavo.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cl-store-devel/attachments/20090301/9a357179/attachment.html>


More information about the cl-store-devel mailing list