Иногда при рефакторинге пакеты переставляются местами по порядку сборки. Тогда может получиться так, что из пакета :клиент вызывается символ сервер:символ, а пакета :сервер ещё нет. В интерактивном режиме это сработает, а при пересборке образа возникнет ошибка чтения из несуществующего пакета. Чтобы обострить эту проблему и сделать зависимости между пакетами декларативной, можно в определении пакета :клиент писать
(:import-from :сервер) - тогда нельзя будет создать :клиент раньше, чем :сервер
В принципе, такие зависимости должны описываться в asdf-системах, но бывает несколько пакетов на asdf-систему, тогда asdf не поможет.
У меня также есть функция budden-tools:*fn-before-return-symbol-from-reader-hook*, к-рая позволяет перехватить момент, когда reader возвращает символ, и проверить, что если *package* == :клиент, а прочитано сервер:символ, то (assert (пакет-клиент-использует-или-импортирует-пакет-сервер)). На данный момент - только SBCL, в прошлом был и Lispworks. С помощью такого перехвата можно сделать так, что и при интерактивной разработке будет ругаться.
Правда, нельзя делать такую проверку тотальной, ведь иногда граф зависимостей пакетов не является деревом - из :сервер тоже может быть прочитан символ клиент:имя. Т.е. нужно ещё расширить defpackage, чтобы ему можно было указать, является ли ссылка на пакет обязательной для того, чтобы прочитать символ из этого пакета с квалификатором.
https://bitbucket.org/budden/budden-tools/src/46d10362973a75672921281e33d2d34af8136eff/careful-token-reader.lisp?at=default&fileviewer=file-view-default
Реализация такой идеи слегка улучшает модульность в лиспе. Пока что я начал в новых пакетах писать (import-from пакет), но переделывать остальное руки не дойдут ли когда-нибудь.
За участие в разработке идеи спасибо linkfly.