HOWTO определение и использование пакетов (библиотек) Common Lisp?

Я разработал некоторые функции Common Lisp в нескольких исходных файлах Lisp, которые я хотел бы легко сделать доступными для других функций, которые я пишу, или сделать доступными на github, если я думаю, что они будут полезны для кого-то еще. На данный момент я просто помещаю их в какую-то заранее определенную папку и использую (require "/path/to/my/modules/module.lisp").

Я хочу понять, каков правильный (канонический) способ определения библиотеки модулей Lisp. И вторая часть вопроса - как их использовать (определил ли я их или получил ли я их от кого-то другого).

Я много читал о defpackage, defsystem и asdf. Но все, что я прочитал, похоже, сосредоточено на каком-то конкретном уголке вселенной этой задачи. Мне сложно увидеть общую картину создания, развертывания и использования настраиваемых модулей. Итак, если у меня есть среда Lisp (CLISP или SBCL) и один или несколько файлов .lisp, из которых я хотел бы создать пакет или библиотеку, есть ли где-нибудь документ, объясняющий, какие шаги необходимы для этого? Вероятно, это то, что я уже читал, но не отслеживал из-за непонимания контекста. То, что я читал об ASDF, похоже, функционально является тем, что мне нужно, но я не понимаю, является ли ASDF моим единственным вариантом или это просто стандарт де-факто и то, что использует большинство других людей, или что-то еще. Я немного поигрался с ним в SBCL и не был уверен, что использую его правильно, и не видел информации о том, как настроить его в CLISP. Итак, я хочу понять, каков ванильный подход к этой задаче.

Я знаю, что это большой и небрежный набор подвопросов. Опять же, если есть хорошие ссылки, я могу их прочитать. У меня просто возникают проблемы с получением общей картины того, как это должно работать, и есть ли какой-нибудь «лучший» подход, или в Lisp это что-то вроде «Дикого Запада», выбирающего библиотеку. -Менеджер-тебе нравится подход. Я использовал Google и читал все, что казалось актуальным, но мой мозг крутится от всего этого.

Спасибо.


person lurker    schedule 06.01.2014    source источник
comment
Спустя 6 лет общепринятого ответа нет. И я думаю, что знаю причину. Ни один из ответов не показывает пример того, на чем, вероятно, застрянет любой новичок в LISP: определите пакет в одном файле, затем а) ​​используйте этот пакет из repl и б) используйте этот пакет из другого файла. Это примерно 5 строк кода, и ни одно из очень подробных руководств и книг в Интернете и ответы здесь не удосуживаются показать это.   -  person BitTickler    schedule 30.01.2020


Ответы (5)


Система - это набор файлов и подсистем. Такую систему можно скомпилировать или загрузить. Возможны и другие операции. Он отслеживает зависимости и пытается выполнить минимальный объем работы.

Если вы используете SBCL и CLISP, то вам следует выбрать ASDF. См. http://www.cliki.net/asdf

ASDF предоставляет, помимо прочего, макрос DEFSYSTEM для описания таких систем.

Не используйте PROVIDE / REQUIRE-, если не знаете, что делаете. ASDF - это то, что вам нужно.

Чтобы опубликовать свой код и упростить его загрузку другими пользователями, используйте QUICKLISP. См .: http://www.quicklisp.org/beta/

person Rainer Joswig    schedule 06.01.2014
comment
Спасибо, Райнер. Являются ли QUICKLISP и ASDF двумя разными способами выполнения одного и того же действия или они работают вместе? - person lurker; 06.01.2014
comment
Последний. Quicklisp использует определения системы ASDF. - person Philipp Matthias Schäfer; 07.01.2014
comment
@mbratch Также, если вам нужен простой способ создания проектов, совместимых с quicklisp, я настоятельно рекомендую quickproject. Это даст вам хороший шаблонный проект с настроенной системой и пакетами. - person Baggers; 07.01.2014

Пакет в Common Lisp не похож на пакет во многих других смыслах. Это не архив файлов списков, это больше похоже на то, что большинство других языков назвали бы модулем или пространством имен, которое позволяет вам выбирать, какие символы (имена) из вашего кода вы хотите показать внешнему миру кода.

Если у вас есть только один файл для вашей маленькой библиотеки, вы можете просто распространить его. Если у вас есть несколько файлов, то в этом случае используется такой инструмент, как ASDF, чтобы, например, убедиться, что файлы, определяющие макросы, загружаются до файлов, которые используют эти макросы.

Вот несколько хороших ресурсов для вас, обе главы из Practical Common Lisp:

person Linuxios    schedule 06.01.2014
comment
Спасибо! Я проверю эти ссылки еще раз. Я читал их раньше, но не понимал всей картины. Я должен был уточнить, что я действительно понял, что пакет был скорее определением пространства имен, поэтому я немного злоупотребил этим термином в своем вопросе. Я тоже столкнулся с defsystem. Моя проблема в том, что мне было трудно собрать все это по кусочкам. Предположим, у меня есть коллекция библиотек Lisp, каждая в своем собственном файле, функционально не связанная, но может иметь некоторую взаимозависимость (одна может включать другую), является ли моя схема стандартного дома для них и использование require по мере необходимости подходящим подходом? - person lurker; 06.01.2014
comment
@mbratch: Я не очень хорошо разбираюсь в этом вопросе, но по опыту работы с другими языками могу предположить, что для вашего собственного использования это совершенно нормально. Однако, если вы упаковываете свою библиотеку для использования другими, вы можете изучить ASDF. - person Linuxios; 06.01.2014

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

ASDF разработан для автоматизации компиляции и загрузки набора исходных файлов. make для Unix - это для CL. Совершенно верно писать и распространять программу без make, так же как это нормально писать программу на CL, которая не использует ASDF.

Если ваш проект достаточно прост, достаточно предоставить файл (например, load.lisp), содержащий инструкции для загрузки зависимых файлов вашего проекта в правильном порядке. Поэтому ASDF не участвует в концепции библиотеки.

В провокационной манере я бы сказал, что канонический способ определения модуля в CL - использовать объявление defpackage, потому что это языковая единица, которая позволяет программисту изолировать свои объявления от чужих.

Тогда возникает вопрос, как сделать это доступным для других. Если вы пишете переносимый код CL, то ASDF является наиболее популярным средством определения системы, и вы должны его использовать. Если вы хотите облегчить другим доступ, тогда Quicklisp - это инструмент, который изменил лицо CL за последние несколько лет.

Наконец, я хотел бы добавить, что ни ASDF, ни Quicklisp не являются стандартами, это инструменты (что не снижает их полезности). ANSI Common Lisp - это стандарт, и я хотел бы, чтобы определение системы было стандартизировано в CL.

person tuscland    schedule 07.01.2014
comment
Спасибо за это (+1). Каждый ответ помог мне собрать больше кусочков головоломки, связанной с моим вопросом. Итак, если я начну с просмотра моей собственной частной библиотеки утилит lisp, то иметь их как файлы lisp где-нибудь в общей папке и делать (load ...), когда они мне нужны, - это канонический способ сделать это? - person lurker; 07.01.2014
comment
Я бы не сказал канонический, но минимальный, да, в основном, так вы бы сделали, чтобы вещи были максимально простыми (а иногда и лучшими для обучения). - person tuscland; 08.01.2014

Да, ASDF - это стандарт де-факто, а Quicklisp - еще один стандарт.

С точки зрения Лиспа вам нужно определить одно или несколько пространств имен (пакетов). Это регулируется стандартом ANSI. С точки зрения вашего кода вы хотите организовать кучу файлов так, чтобы они стали единым целым, и каким-то образом предоставить эти пакеты. Вот где подключается ASDF. Quicklisp позволяет вам управлять системами ASDF самым простым и понятным способом. Вы можете как загрузить множество библиотек из репозитория Quicklisp, так и управлять своими локальными системами, создавая символические ссылки в папке quicklisp / local-project.

Если у вас установлен Quicklisp, вы можете ввести

(ql:quickload :cl-fad)

в REPL и таким образом загрузить библиотеку CL-FAD (возможно, загрузив ее); тогда становятся доступными пакеты CL-FAD и PATH, вы забываете об ASDF-системах и придерживаетесь логики пакетов.

Хорошей идеей будет посмотреть asd-файлы нескольких проектов, загруженных с помощью Quicklisp.

person Stanislav Kondratyev    schedule 06.01.2014
comment
Я, конечно, пристрастен, но UIOP значительно превосходит CL-FAD по большей части (всему?) Того, что делает CL-FAD, то есть обеспечивает переносимый доступ к файловой системе. А UIOP намного более портативен и повсеместен (часть ASDF 3). - person Faré; 09.01.2014

Я настраиваю свои собственные библиотеки, которые я часто использую, используя определения системы ASDF и связываю их с local-projects (или с похожим именем) папкой Quicklisp. Это позволяет мне загружать их с помощью quicklisp, как любой опубликованный пакет.

Если вы хотите узнать, как настроить такую ​​систему ASDF, я бы посоветовал установить Quicklisp (что на этот раз действительно легко, когда дело доходит до установки «незавершенного» программного обеспечения из Интернета), быстро загрузить один или два хорошо известных пакета и посмотреть на его .asd файл, обращаясь к документации, если сомневаетесь.

Таким образом, ваши библиотеки уже настроены для публикации, как и большинство известных пакетов CommonLisp.

person Philipp Matthias Schäfer    schedule 07.01.2014