Upon using (make-package 'test) (in-package test)
in SBCL and CCL implementations, I've noticed that SBCL requires (cl:defun foo () (...))
or (cl:describe <symbol name here>)
while CCL does not require any colons or double colons to use built-in symbols. It is my understanding that external symbols must be accessed with one colon, even if they are built-in. However CCL seems to work differently in this respect.
This confuses me somewhat regarding the use of external symbols. Are external symbols supposed to be available without any colons or is CCL just using/importing/inheriting automatically for convenience-sake?
Also, are there any more of these small but significant differences between the implementations regarding symbols and packages?
The ANSI CL standard does not define which packages are used when you create a package
At some point in time, SBCL deviated from common practice, but still follows ANSI CL standards.
Using packages
Using packages in some other package means making their symbols available in that package.
You can get a package's use list by calling the function package-use-list
.
It is undefined in the ANSI Common Lisp standard which packages a new package uses by default and also if it uses any at all.
Different common practice in implementations
There are now two common practices in implementations:
Example in CCL:
? (package-use-list (make-package "FOOBAR"))
(#<Package "CCL"> #<Package "COMMON-LISP">)
LispWorks:
CL-USER 17 > (package-use-list (make-package "FOOBAR"))
(#<The COMMON-LISP package, 0/4 internal, 978/1024 external>
#<The HARLEQUIN-COMMON-LISP package, 0/4 internal, 365/512 external>
#<The LISPWORKS package, 0/4 internal, 226/256 external>)
Example in SBCL:
* (package-use-list (make-package "FOOBAR"))
NIL
ABCL:
CL-USER(1): (package-use-list (make-package "FOOBAR"))
NIL
Writing portable code
Thus in SBCL and thus in portable Common Lisp you need to tell Lisp which packages should be used. To get the COMMON-LISP
package used and only that package, you need to write:
(make-package "FOO" :use '("COMMON-LISP"))
Background
The original idea in the first Common Lisp was that one could write (in-package "FOO")
at the REPL and the package was created with sensible defaults and one was directly in that package. The defaults were usually the package for the language (at that time called "LISP") and packages for common extensions (for example with CLOS+MOP, threads, ...).
Later Common Lisp was changed so that IN-PACKAGE did not create a package and it is defined that upon package creation it is undefined which packages are used and it is not required to use any package upon package creation. The SBCL maintainers then thought: instead of supporting common practice (which is not mentioned in the standard), provide a more neutral and predictable behaviour of using no package upon package creation.
Other differences
Most other differences in package systems in Common Lisp are around extensions to the standard. Examples:
hierarchical/nested packages
package prefixes to whole forms (not just symbols)
A bigger and incompatible change provided by some implementations as an option:
Undefined:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With