多个包装和符号的包装阴影-如何使用cl21

时间:2019-05-18 21:25:08

标签: package common-lisp shadowing

加载Quicklisp系统:cl21(21世纪的通用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 ...))

但是,我不确定如何从Quickclp系统(如:cl21)中获取要插入宏的软件包的完整列表。 (:cl21软件包的手动计数为30,每个软件包中导出符号的数量有所不同。)

从更一般的角度来看,这是解决冲突的最简单方法吗?请注意,Use package shadowing symbols上还有另一篇文章处理类似的问题,但是我发现很难遵循(也许是因为使用阅读器宏来拼接一长串: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)

1 个答案:

答案 0 :(得分:3)

不要同时usecl cl21。只需使用cl21

Cl21都针对其相对于cl更改的功能导出符号,并重新导出任何未更改的符号。它的设计类似于替换的“基本”程序包。