OK, after some trying with small code examples and reading (obscure)
Common Lisp documentation, I finally understand the context of this bug.
So, what we intend to do: (due to still existed issue on the Aldor side)
we want to "shadow" definition of "in-package" from Lisp implementation,
and use our version instead. We want this updated definition of
"in-package" to be used in "FRICAS-LISP" package and any packages that
derive from it.
What we did before: "(do-symbols (x "FRICAS-LISP") (export (list x)))"
This line basically exports every symbol from "COMMON-LISP" again in
"FRICAS-LISP".
This is highly unusual, because normally a package will only export its
new definitions. And this is where sbcl-2.3.2 breaks: it doesn't export
the updated "in-package" definition somehow.
Putting the sbcl "bug" aside, the "do-symbols" line looks like a hack
to me, and the proper solution comes from documentation:
http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/fun_use-package.html
"A name conflict in use-package between two external symbols inherited
by the using package from other packages may be resolved in favor of
either symbol by importing it into the using package and making it a
shadowing symbol."
Again, rephrasing the problem:
We'd like to simply use
(make-package "BOOT" :use '("COMMON-LISP" "FRICAS-LISP"))
But we can't because of symbol conflict on "in-package".
So the proper solution is this:
(defmacro make-package-with-fricas-lisp (package)
`(progn
(make-package ,package)
(import 'FRICAS-LISP:IN-PACKAGE ,package)
(shadow "IN-PACKAGE" ,package)
(use-package '("COMMON-LISP" "FRICAS-LISP") ,package)))
Fist, make an empty package. Then, import the symbol we want to use.
Then shadow it and use "use-package" after that.
Full patch attached.
- Qian
diff --git a/src/lisp/fricas-package.lisp b/src/lisp/fricas-package.lisp
index c0dfc4ef..da8eb442 100644
--- a/src/lisp/fricas-package.lisp
+++ b/src/lisp/fricas-package.lisp
@@ -34,12 +34,10 @@
#+gcl
(shadow "QUIT")
-(do-symbols (x "FRICAS-LISP") (export (list x)))
-
(export '(quit chdir |getEnv| |getCLArgs| |load_quietly|
get-current-directory
trim-directory-name pad-directory-name
file-kind makedir fricas_compile_file fricas_compile_fasl
- |fricas_probe_file|
+ |fricas_probe_file| IN-PACKAGE
DEFCONST exit-with-status MEMQ |quiet_load_alien|
|handle_input_file| |handle_output_file| |maybe_delete_file|
|remove_directory| |writeablep| |openServer| |sockGetInt|
@@ -61,13 +59,28 @@
(eval-when (:execute :compile-toplevel :load-toplevel)
(setf *features* (delete :CCL *features*)))
+(defmacro make-package-with-fricas-lisp (package)
+ `(progn
+ (make-package ,package)
+ (import 'FRICAS-LISP:IN-PACKAGE ,package)
+ (shadow "IN-PACKAGE" ,package)
+ (use-package '("COMMON-LISP" "FRICAS-LISP") ,package)))
+
;;; Package containing Shoe to Lisp translator
-(make-package "BOOTTRAN" :use '("FRICAS-LISP"))
+(make-package-with-fricas-lisp "BOOTTRAN")
+
+;;; Package containing support routines for code generated
+;;; by Aldor compiler.
+(make-package-with-fricas-lisp "FOAM")
+
+;;; Package for code output by Aldor.
+(make-package-with-fricas-lisp "FOAM-USER")
+(use-package '("FOAM") "FOAM-USER")
;;; Main FriCAS package. The interpreter and the algebra are run
;;; after switching to the boot package (in-package "BOOT") so any
;;; symbol that the interpreter or algebra uses has to appear here.
-(make-package "BOOT" :use '("FRICAS-LISP"))
+(make-package-with-fricas-lisp "BOOT")
(in-package "BOOT")
@@ -78,10 +91,3 @@
(import '(BOOT::MAKE_HASHTABLE BOOT::QSETVELT BOOT::SETELT_BVEC
BOOT::STR_ELT))
-
-;;; Package containing support routines for code generated
-;;; by Aldor compiler.
-(make-package "FOAM" :use '("FRICAS-LISP"))
-
-;;; Package for code output by Aldor.
-(make-package "FOAM-USER" :use '("FRICAS-LISP" "FOAM"))