armedbear / abcl

Armed Bear Common Lisp <git+https://github.com/armedbear/abcl/> <--> <svn+https://abcl.org/svn> Bridge
https://abcl.org#rdfs:seeAlso<https://gitlab.common-lisp.net/abcl/abcl>
Other
290 stars 29 forks source link

Problem loading quicklisp serapeum, related to package prefixing in __loader__._ #425

Open alanruttenberg opened 2 years ago

alanruttenberg commented 2 years ago

Here's the form in question, part of a macroexpansion of the form (define-simple-exporter def (var &body (&optional val docs))) in exporting.lisp

(eval-when (:compile-toplevel :load-toplevel :execute)
         (export '(serapeum.exporting::def)
                 (find-package :serapeum.exporting)))

When compiled, I see in the loader

(EXPORT '(SERAPEUM.EXPORTING:DEF) (FIND-PACKAGE :SERAPEUM.EXPORTING))

Notice that a single colon is used for the symbol SERAPEUM.EXPORTING:DEF

The error I get is then The symbol "DEF" is not external in package SERAPEUM.EXPORTING.

SBCL does not get this error.

Is it that there's something funky about eval-when that happens not to evaluate the export in a way that it properly side-effects the run time? Because it ought to be that we've already evaluated the export and so reading the symbol as external when loading the fasl should be fine.

OTOH, I could see there being a problem if the fasl is loaded in an environment in which the compilation is already done happen, i.e. by the first time SERAPEUM.EXPORTING:DEF is seen it isn't exported yet.

It's feeling like this is an ABCL issue having to do with the way our fasls work. Maybe the fix is that when writing to __loader__._ all prefixed symbols should be printed as if they are internal?


Subsequently I get another error while loading The function serapeum/dispatch-case::vars-out is undefined. when compiling range.lisp, but I ran out of time trying to track that one down.

alanruttenberg commented 2 years ago

I just ran into this problem again, this time with defpackage+. Which is ironic, I suppose.

To elaborate: The source code says:

(in-package :defpackage+-user-1)

(defpackage+ :defpackage-plus-1
  (:nicknames #:defpackage+-1)
  (:export-only

   ;; The Macro
   #:defpackage+
   #:defpackage+-dispatch

   ;; Ensuring package qualities
   #:ensure-use-only
   #:ensure-package
   #:ensure-nicknames
   #:ensure-export
   #:ensure-export-only
   #:ensure-export-warning

   ;; Importing/Inheriting
   #:import-from
   #:import-external-from
   #:import-except-conflicts
   #:shadowing-import-from
   #:inherit-from
   #:inherit-package
   #:inherit-package-except

   ;; Utility
   #:package-external-symbols
   #:package-symbols))

This expands to a form that includes (defpackage-plus-1::ensure-package ':defpackage-plus-1)

The form exports ensure-package from defpackage-plus-1

defpackage+-user-1 is defined earlier to use defpackage-plus-1

After the form is evaluated, ensure-package is now available in :defpackage+-user-1.

__LOADER._ says:

(SYSTEM:INIT-FASL :VERSION 43)
(COMMON-LISP:SETQ SYSTEM:*SOURCE* #P"/Users/alanr/quicklisp/dists/quicklisp/software/defpackage-plus-20180131-git/src/package-plus.lisp")
(COMMON-LISP:SETQ SYSTEM::*FASL-UNINTERNED-SYMBOLS* #(#:DEFPACKAGE+-1 #:DEFPACKAGE+ #:DEFPACKAGE+-DISPATCH #:ENSURE-USE-ONLY #:ENSURE-PACKAGE #:ENSURE-NICKNAMES #:ENSURE-EXPORT #:ENSURE-EXPORT-ONLY #:ENSURE-EXPORT-WARNING #:IMPORT-FROM #:IMPORT-EXTERNAL-FROM #:IMPORT-EXCEPT-CONFLICTS #:SHADOWING-IMPORT-FROM #:INHERIT-FROM #:INHERIT-PACKAGE #:INHERIT-PACKAGE-EXCEPT #:PACKAGE-EXTERNAL-SYMBOLS #:PACKAGE-SYMBOLS))

(COMMON-LISP:IN-PACKAGE "COMMON-LISP-USER")
(SYSTEM:%IN-PACKAGE "DEFPACKAGE+-USER-1")
(ENSURE-PACKAGE ':DEFPACKAGE-PLUS-1)  ;;;;; <<--------------------------
(DEFPACKAGE+-DISPATCH ':NICKNAMES '(#0?) ':DEFPACKAGE-PLUS-1)
(DEFPACKAGE+-DISPATCH ':EXPORT-ONLY '(#1? #2? #3? #4? #5? #6? #7? #8? #9? #10? #11? 
#12? #13? #14? #15? #16? #17?) ':DEFPACKAGE-PLUS-1)

Note that the call to ensure-package is not package-prefixed and so the symbol :defpackage+-user-1::ensure-package is not yet exported and so not yet defined. And so we get the error
The function defpackage+-user-1::ensure-package is undefined.