Загрузка пакета quicklisp для использования в другом файле lisp

Я скачал большой программный проект FriCAS, который я скомпилировал из исходного кода с использованием SBCL. Это был просто вопрос использования GNU .configure - я полный новичок в Lisp.

Однако, чтобы добавить некоторые дополнительные функции, я установил quicklisp и несколько дополнительных пакетов, тщательно следуя инструкциям. Все идет нормально.

Вот моя проблема: я пытаюсь скомпилировать внешний файл lisp для использования в системе. Мне нужно сделать quicklisp и его пакеты видимыми для компилятора. Итак, я скопировал свой файл .sbclrc в начало моего файла lisp:

#-quicklisp
(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
                                       (user-homedir-pathname))))
  (when (probe-file quicklisp-init)
    (load quicklisp-init)))

Я следил за этим с

(eval-when (:compile-toplevel)
  (ql:quickload "f2cl-lib"))

Я уже установил f2cl-lib с quicklisp. Однако мой компилятор (внутри FriCAS) немедленно прерывается с

; caught ERROR:
;   READ error during COMPILE-FILE:
;   
;     Package QL does not exist.

Я немного запутался здесь - возможно, чего-то тривиального и очевидного не хватает, но, как я говорю с точки зрения новичка, я не знаю, что это такое.


person Alasdair    schedule 24.10.2015    source источник


Ответы (1)


Похоже на FAQ. См. также документацию для eval-when.

Компилятор файлов

Помните, что компилятор файлов компилирует формы, а не выполняет их. Он просто генерирует код для последующего выполнения. В общем. Хотя в Common Lisp есть некоторые исключения из этого правила: например, макрос, используемый в исходном коде, будет выполняться компилятором файлов. Но Common Lisp также позволяет нам указать компилятору файлов выполнять код во время компиляции, что является одним из вариантов использования eval-when.

Ваш пример упрощен

Если у вас есть файл:

(load "file-which-creates-package-foo")

(eval-when (:compile-toplevel)
  (foo:bar)) 

Затем компилятор файла сгенерирует код для загрузки файла, но не загрузит файл.

Затем компилятор файла видит вторую форму, в которой компилятор файла получает указание выполнить оператор в во время компиляции (и только в во время компиляции), поэтому (foo:bar) будет выполняться во время компиляции. Но хуже: Поскольку код загрузки еще не выполнен, пакет FOO неизвестен, а форма (foo:bar) будет прочитана в время компиляции, читатель уже жалуется на время компиляции< /em> пакет FOO не существует.

Использование EVAL-WHEN

Что вам нужно сделать, так это сообщить компилятору файлов, чтобы он действительно загружал то, что ему нужно во время компиляции. Файл уже содержит форму eval-when, поэтому дать вам подсказку: используйте eval-when. Он имеет три ситуации:

  • :compile-toplevel -> компилятор файлов выполняет вложенные формы
  • :load-toplevel -> компилятор файла генерирует код, чтобы код выполнялся при загрузке кода
  • :execute

Убедитесь, что упомянуты те ситуации, когда код должен выполняться.

Возможные решения

Итак, возможные решения:

  • как и выше, используйте EVAL-WHEN, чтобы иметь возможность выполнять формы с помощью компилятора файлов
  • запишите код загрузки в отдельный файл и скомпилируйте/загрузите этот файл перед использованием пакета. Можно также добавить этот файл в систему, чтобы он загружался при компиляции системы до компиляции используемого кода.
person Rainer Joswig    schedule 24.10.2015
comment
Большое спасибо за ваш подробный ответ, который я в основном понимаю. Я чувствую, что Лисп слишком сложен для такого некомпетентного халтурщика, как я; так что я попробую еще немного, а затем изящно сдаюсь. - person Alasdair; 24.10.2015
comment
@Alasdair: этому можно научиться, и такие места, как stackoverflow, могут помочь с проблемами программирования. FriCAS/Axiom — действительно сложная часть программного обеспечения, и расширение его реализации требует некоторого обучения. Существует также список рассылки для FriCAS, где можно получить дополнительную помощь по его расширению. - person Rainer Joswig; 24.10.2015
comment
О, да, я доставлял себе массу неприятностей в списке рассылки FriCAS! - person Alasdair; 24.10.2015