Загрузка системы Quicklisp: cl21 (Common Lisp для 21-го века) вызывает много конфликтов с пакетом: cl.(Но это сделано намеренно.) Есть ли удобный способ указать, что любые конфликты должны быть разрешены в пользу: cl21?Следующее определение разрешает конфликты по отдельности, но это утомительно, так как сотни символов нуждаются в теневом копировании:
(defpackage :my-pkg
(:use :cl :cl21)
(:shadowing-import-from :cl21.core.hash-table :hash-table-count)
(:shadowing-import-from :cl21.core.sequence :position :substitute-if)
(:shadowing-import-from :cl21.core.package :rename-package :use-package)
(:shadowing-import-from :closer-mop :standard-generic-function)
...)
У меня есть решение написать макрос под названием defpackage*
, который расширяется до defpackage
как выше:
(defun package-externals (pkg-name)
"Returns the external symbols in a named package."
(let (pkg-syms)
(do-external-symbols (sym (find-package pkg-name) pkg-syms)
(push (list pkg-name sym) pkg-syms))))
(defmacro defpackage* (pkg-name use-list shadow-pkg-names)
"Adds shadowing imports from a list of package names."
(let ((shadow-externals (loop for pkg in shadow-pkg-names
append (package-externals pkg))))
`(defpackage ,pkg-name ,use-list
,@(loop for ext in shadow-externals
collect `(:shadowing-import-from ,@ext)))))
Третий аргумент shadow-pkg-names
- это список имен пакетов, из которых будут извлечены экспортированные символы.Например, вызов макроса может выглядеть следующим образом:
(defpackage* :my-pkg
(:use :cl :cl21)
(:cl21.core.hash-table :cl21.core.sequence :cl21.core.package ...))
Однако я не уверен, как получить полный список пакетов для вставки в макрос из системы Quicklisp, например: cl21.(Ручной подсчет пакетов: cl21 составляет 30 с различным количеством экспортируемых символов из каждого пакета.)
На более общем уровне это самый простой способ разрешения конфликтов массово?Обратите внимание, что есть еще один пост на Использование символов затенения пакета , который имеет дело с аналогичной проблемой, но мне трудно это понять (за исключением, возможно, идеи использования макроса читателя для склеивания в длинном спискеof: shadowing-import-from пункты).Также обратите внимание, что загрузка: cl21 не кажется простой, поскольку мне приходилось каждый раз начинать с нуля (но не знаю почему):
(let ((quicklisp-init (merge-pathnames "quicklisp\\setup.lisp" (user-homedir-pathname))))
(when (probe-file quicklisp-init)
(load quicklisp-init)))
(ql-dist:install-dist "http://dists.cl21.org/cl21.txt")
(ql:quickload :cl21)