Сохранение функции в Common Lisp - PullRequest
9 голосов
/ 15 ноября 2008

Есть ли какое-либо решение для персистентности для Common Lisp, такое как Elephant, которое позволяет сохранять функцию? В настоящее время мое приложение хранит идентификатор в БД, а затем выполняет поиск в таблице функций, которая есть, но этот метод не позволяет хранить динамически созданные функции.

Ответы [ 6 ]

4 голосов
/ 16 ноября 2008

Это не механизм сохранения базы данных, но у большинства 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>)

Вы можете записывать в поток (здесь я для удобства использовал файл), поэтому вы можете тривиально записать эти байты и поместить их в базу данных, если хотите.

3 голосов
/ 18 ноября 2008

Паскаль Бургиньон дал стандартное решение на 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*))
2 голосов
/ 16 ноября 2008

Простуда может быть тем, что вы хотите. Он включает в себя сериализуемые замыкания и сериализуемые продолжения.

1 голос
/ 16 ноября 2008

Вы можете посмотреть на сохранение изображений Lisp. Это позволяет сохранить «достаточно информации, чтобы перезапустить процесс Lisp позднее». Вы можете сохранить свои функции после того, как загрузите их в свое изображение.

Это также может быть немного сложнее, чем вы искали, но вот (очень) краткое введение в процесс: Сохранение основного образа

1 голос
/ 16 ноября 2008

Функции являются непрозрачными объектами, поэтому вам не повезет, если вы сохраните их в файлах или что-то в этом роде. Однако вы можете хранить списки и компилировать их после извлечения из базы данных.

Конечно, это не поможет вам закрывать магазины. Это повлечет за собой хранение лексической среды вместе с кодом, к которому у вас нет (портативного) доступа. Код, который вы компилируете из хранимых списков, должен полностью полагаться на глобальные данные или данные, хранящиеся в базе данных.

Кстати, обратите внимание, что вы можете funcall символов, поэтому вам не нужна таблица функций для глобальных функций.

0 голосов
/ 26 ноября 2008

Будьте осторожны, хранение кода может быть не очень хорошим. Разработчики Zope научились этому нелегко.

...