2.31 Package-Local Nicknames

Package-local nicknames are similar to package nicknames, except the nickname applies only when *package* is set to the desired package that has defined local nicknames.

For example, a short nickname can be used for a long package name as follows, using the new :local-nicknames option that takes a list of lists of the form (local-nickname actual-package) that describes the local nickname and the corresponding actual package:

(defpackage "A-VERY-LONG-PACKAGE-NAME"
  (:intern "A-SYMBOL"))
(defpackage "MY-PACKAGE"
  (:use "CL")
  (:local-nicknames ("SHORTY" "A-VERY-LONG-PACKAGE-NAME")))
...
(let ((*package* (find-package "MY-PACKAGE")))
  (find-symbol "A-SYMBOL" "SHORTY")) => A-VERY-LONG-PACKAGE-NAME::A-SYMBOL

Thus, when *package* is the package "MY-PACKAGE", we can use "SHORTY" to refer to symbols from "A-VERY-LONG-PACKAGE-NAME".

Support for package-local nicknames in CMUCL is indicated by having :package-local-nicknames in *features*.

A continuable error is signaled if any of the following are true for the local nickname for the actual-package (see add-package-local-nickname).

Macro: defpackage defined-package-name {options}*

To support package-local nicknames, defpackage has a new option named :local-nicknames that takes a list of lists specifying the local nickname for the actual package. For example

(defpackage my-package
  (:local-nicknames {(local-nickname global-package-designator)}*))

defines local-nickname as a package-local nickname for the package global-package-designator. local-nickname must be string-designator and global-package-designator must be a string-designator or package object. Any number of such pairs is allowed. However, the values of local-nickname and global-package-designator must satisfy the same constraints as mentioned in add-package-local-nickname.

Local nicknames affect the reading and printing of symbols in the defined-package-name allowing you to use (potentially) shorter names to reference other packages with longer names. The nickname is used when printing the symbols as well.

For example

(defpackage :bar (:intern "X"))
(defpackage :foo (:intern "X"))
(defpackage :quux (:use :cl) (:local-nicknames (:bar :foo) (:foo :bar)))
(find-symbol "X" :foo) ; => FOO::X
(find-symbol "X" :bar) ; => BAR::X
(let ((*package* (find-package :quux)))
  (find-symbol "X" :foo))               ; => BAR::X
(let ((*package* (find-package :quux)))
  (find-symbol "X" :bar))               ; => FOO::X

The package :quux defines two local nicknames: :bar and :foo. When *package* is set to the package :quux, the package prefix foo:: is a nickname for the package :bar. Hence, the symbol with the name “X” in the package :foo is really the symbol BAR::X.

Function: extensions:package-local-nicknames designated-package

Returns an alist of (local-nickname . actual-package) describing all of the nicknames local to the designated-package.

From the example above, we have

(package-local-nicknames :quux) =>
(("FOO" . #<The BAR package, 1/9 internal, 0/2 external>)
 ("BAR" . #<The FOO package, 1/9 internal, 0/2 external>))

When in the designated-package, calls to find-package with any of the local nicknames will return the actual-package instead.

When printing a symbol with a local-nickname, the local-nickname is printed for the package instead of the actual-package.

Thus,

(let ((*package* (find-package :quux)))
  (print (find-symbol "X" :foo))
  (values)) =>
FOO::X 
Function: extensions:package-locally-nicknamed-by-list designated-package

Returns a list of packages which have a local nickname for designated-package.

Function: extensions:add-package-local-nickname local-nickname actual-package &optional {(package *package*)}

For the given package, the local-nickname is added as a local nickname for actual-package. Both actual-package and package must be a package designator. local-nickname should be a string designator.

Returns the package.

A continuable error is signaled if any of the following are true:

  • local-nickname is already a local nickname for a different actual-package
  • local-nickname is one of “CL”, “COMMON-LISP”, or “KEYWORD”
Function: extensions:remove-package-local-nickname old-nickname &optional {(package *package*)}

If package has old-nickname as a local nickname, it is removed from the list of package-local nicknames in the package package. Returns non-nil if old-nickname existed. Otherwise returns nil.