多个包和符号的包阴影 - 如何使用 cl21
Package Shadowing for Multiple Packages and Symbols - how to use cl21
加载 Quicklisp 系统 :cl21(21 世纪的 Common Lisp)会与 :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 ...))
但是,我不确定如何从 :cl21 等 Quicklisp 系统获取要插入宏中的完整包列表。 (手动计数 :cl21 包的数量为 30,每个包的导出符号数量不同。)
在更一般的层面上,这是解决冲突的最简单方法吗整体?请注意,在 Use package shadowing symbols 处还有另一个 post 处理类似的问题,但我发现它很难理解(除了使用 reader 宏拼接的想法: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)
不要 use
cl
和 cl21
。如果需要,只需使用 cl21
。
Cl21
都导出其相对于 cl
和 re-exports 任何未更改符号更改的功能的符号。它被设计成类似替代“基础”包的东西。
加载 Quicklisp 系统 :cl21(21 世纪的 Common Lisp)会与 :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 ...))
但是,我不确定如何从 :cl21 等 Quicklisp 系统获取要插入宏中的完整包列表。 (手动计数 :cl21 包的数量为 30,每个包的导出符号数量不同。)
在更一般的层面上,这是解决冲突的最简单方法吗整体?请注意,在 Use package shadowing symbols 处还有另一个 post 处理类似的问题,但我发现它很难理解(除了使用 reader 宏拼接的想法: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)
不要 use
cl
和 cl21
。如果需要,只需使用 cl21
。
Cl21
都导出其相对于 cl
和 re-exports 任何未更改符号更改的功能的符号。它被设计成类似替代“基础”包的东西。