Reputation: 1941
Loading the Quicklisp system :cl21 (Common Lisp for the 21st Century) produces many conflicts with the :cl package. (But this is by design.) Is there a convenient way to specify that any conflicts should be resolved in favor of :cl21? The following definition resolves conflicts individually, but is tedious, since there are hundreds of symbols needing shadowing:
(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)
...)
The solution I have so far is to write a macro called defpackage*
that expands into a defpackage
like that above:
(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)))))
The third argument shadow-pkg-names
is the list of package names from which the exported symbols will be extracted. For example, a macro call might look like:
(defpackage* :my-pkg
(:use :cl :cl21)
(:cl21.core.hash-table :cl21.core.sequence :cl21.core.package ...))
However, I'm not sure how to get the complete list of packages to insert in the macro from a Quicklisp system like :cl21. (A manual count of the :cl21 packages comes in at 30, with varying numbers of exported symbols from each package.)
At a more general level, is this the simplest way to resolve conflicts en masse? Note that there is another post at Use package shadowing symbols which deals with a similar issue, but I'm finding it hard to follow (except perhaps for the idea of using a reader macro to splice in the long list of :shadowing-import-from clauses). Also note that loading :cl21 does not seem straightforward, as I've had to start from scratch every time with (but don't know why):
(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)
Upvotes: 0
Views: 230
Reputation: 51531
Don't use
both cl
and cl21
. Just use cl21
if you want that.
Cl21
both exports symbols for functionality it changed with respect to cl
and re-exports any unchanged symbols. It is designed as something like a replacement “base” package.
Upvotes: 3