Common LISP中Export、unintern与符号访问的规范符合性疑问——SBCL下导出非当前包可访问符号的行为探究
export Behavior and Common Lisp Specification Let's break down exactly what's happening here, and confirm that this behavior is fully compliant with the Common Lisp standard.
The Root of Your Issue
Your confusion comes from a small but critical detail in how you're calling export: you didn't specify the target package, so it defaulted to your current package (COMMON-LISP-USER). Here's the play-by-play:
When you run:
CL-USER> (export (find-symbol "BAR" (find-package "FOO")))You're asking
exportto makeFOO::BARaccessible from the default package (which isCL-USERright now). But according to the Common Lisp HyperSpec (CLHS),exportcan only operate on symbols that are present in (or inherited by) the target package. SinceFOO::BARexists solely in theFOOpackage (andCL-USERdoesn't use or import anything fromFOO), SBCL correctly errors out—you can't export a symbol that doesn't belong to the target package.When you run:
CL-USER> (export 'foo::bar (find-package "FOO"))You explicitly tell
exportto target theFOOpackage. SinceFOO::BARis present inFOO, the operation succeeds as expected, marking the symbol as external so it can be accessed viafoo:barlater.
Why describe Works Even When the Symbol Is Inaccessible
The describe function doesn't have the same package constraints as export. It accepts any symbol object (whether your current package can access it or not) and reports its metadata. When you run (describe 'foo::bar), you're using a package-qualified name to directly reference the FOO::BAR symbol—Lisp's reader resolves this correctly regardless of your current package's access rules, hence why describe can find it.
Does This Follow the CL Specification?
Absolutely. The CLHS clearly states for export:
If any symbol in symbols is not present in package (and not inherited), an error of type package-error is signaled.
SBCL's error message ("These symbols are not accessible in the COMMON-LISP-USER package") is just its specific way of enforcing this rule—telling you the symbol you tried to export doesn't belong to (or isn't inherited by) the target package (which defaulted to CL-USER).
This isn't an ambiguous edge case or SBCL-specific behavior; it's a strict adherence to the standard's requirements for package operations.
内容的提问来源于stack exchange,提问作者CL-USER

