Почему ваш пример терпит неудачу
При запуске sbcl --load t.cl --eval '(quit)'
в оболочке, то, что это делает, это раскручивает образ SBCL Lisp в процессе, компилирует файл и запускает его.Затем вы изменяете файл и сохраняете его на свой диск.Это последнее действие не имеет отношения к уже запущенному процессу SBCL, который уже скомпилировал предыдущий файл.SBCL прочитал файл один раз, когда вы попросили его, после того, как у него есть скомпилированные инструкции для запуска, у него нет причин снова просматривать файл, если вы явно не попросите его.
Пример 'live' с Emacs+ SLIME
Чтобы внести «живые» изменения в работающую программу, вы должны взаимодействовать с уже запущенным образом Lisp.Это легко сделать с помощью Emacs + Slime.Например, вы можете создать такой цикл:
(defun foo (x) (+ x 3))
(dotimes (it 20)
(format t "~A~%" (foo it))
(sleep 1))
, а затем перекомпилировать foo
во время выполнения в REPL с новым определением:
(defun foo (x) (+ x 100))
Другой поток будетиспользуется для перекомпиляции функции.Новая функция будет использоваться для будущих вызовов, как только ее компиляция будет завершена.Вывод в REPL будет выглядеть следующим образом:
3
4
5
CL-USER> (defun foo (x) (+ x 100))
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN
FOO
103
104
105
...
Это также будет работать с новым определением foo
, скомпилированным из другого файла, в отличие от ввода непосредственно в REPL.
Работа из системной оболочки
Хотя вы уже можете использовать приведенный выше пример для целей разработки, вы можете захотеть взаимодействовать с запущенным образом SBCL Lisp из оболочки.Я не знаю, как это сделать.Для вашего точного примера вы хотите, чтобы SBCL перезагрузил возможные файлы, которые вы изменили.Краткий взгляд на руководство SBCL , по-видимому, не обеспечивает способы передачи кода lisp в уже запущенный процесс SBCL.