In Graham's book “ANSI Common Lisp” (1996) p. 137 the example illustrating the use of defpackage and in-package goes like
(defpackage "MY-APPLICATION"
(:use "COMMON-LISP" "MY-UTILITIES")
(:nicknames "APP")
(:export "WIN" "LOSE" "DRAW"))
(in-package my-application)
The defpackage invocation uses of character strings to convey package names and list exported symbols. While this style can be seen in older codes the dominant usage today seems to be
(defpackage :my-application
(:use :common-lisp :my-utilities)
(:nicknames :app)
(:export :win :lose :draw))
(in-package :my-application)
The regularity resulting from using the :my-application
keyword both in the defpackage and in the in-package invocations is a minor but appreciable difference.
I speculate, the second forms reduces the size of the program in memory because the keywords are all interned in the keyword package while literal character strings stand for themselves and literal character strings with identical contents do not need to share their memory representations. (And if they did, strange results could follow from mutating one of these character strings!)
What are the actual differences between these two forms, and why is the latter preferred over the former?
Besides this, I occasionally see
;; Pay attention to the :export line
(defpackage :my-application
(:use :common-lisp :my-utilities)
(:nicknames :app)
(:export #:win #:lose #:draw))
(in-package :my-application)
The #
introduces a reader macro but I am not sure which effects it has on a keyword and not sure how it modifies the defpackage declaration.
Use uninterned symbols, like #:my-package
.
Common lisp has a notion of a string designator (see also designators).
This means that operationally symbols in
defpackage
are equivalent to
their names.
You have 4 options:
E.g.,
(defpackage my-package)
Brevity
Namespace pollution: the symbol my-package
is now
interned in the current
*package*
.
E.g.,
(defpackage :my-package)
Moderate brevity (one extra character)
Namespace pollution: the symbol :my-package
is now
interned in the standard package
KEYWORD.
E.g.,
(defpackage "MY-PACKAGE")
No namespace pollution.
E.g.,
(defpackage #:my-package)
No namespace pollution.
2 extra characters
The "ugly prefix" is actually a desirable feature because this is the only context where I use uninterned symbols, and emacs highlights them nicely if you add
(font-lock-add-keywords
'lisp-mode
'(("\\(#:\\)\\(\\(\\s_\\|\\sw\\)*\\)"
(1 font-lock-comment-delimiter-face)
(2 font-lock-doc-face))))
to your ~/.emacs
.