7.3.4 Using packages in interpreted and compiled code

7.3.4.3 Package rules 3 and 4

It is almost always better to fix the exterior package interface of the module from which you desire some internal symbol than to access that symbol with double-colon qualification. Simply go to the place where the package of that module is defined, and add that symbol to the exports list. You should then be able to continue with the program interactively.

Note that the double-colon qualification syntax means one of two things:

This type of access is an information-losing operation; it is not generally possible to determine afterwards whether you freshly created a symbol or merely accessed an existing one. The most damaging and subtle bug that can occur to your package system is to create a fresh symbol this way in a package that should have had it available through inheritance. When you discover this mistake later, such as when you receive the error signal about name conflicts during anexport oruse-package operation, it is typically too late to correct the error.

Occasionally, it is preferable to import the desired symbol into the package where it will be used, rather than altering the exterior interface of the package in which it resides. Compare these two examples:

;;; File 1 looks like this.
;;; -*- Mode: LISP; Syntax: Common-Lisp; Package: ACE;
;;;                                              Base: 10 -*-
(in-package "ACE")
(defun how-wide (x) 
  (check-type x string)
  (+ (user::string-width x) (user::string-width y)))

;;; File 2 looks like this. ;;; -*- Mode: Lisp; Syntax: Common-Lisp; Package: ACE; ;;; Base: 10 -*- (in-package "ACE") (import (or (find-symbol "STRING-WIDTH" "USER") (error "STRING-WIDTH missing from the USER package"))) (defun how-wide (x y) (check-type x string) (+ (string-width x) (string-width y)))

The first file has a much higher potential for compile-time/load-time conflicts than the second file. The second file is more secure because every symbol in the main contents of the file--the part not concerned with creating theace package--is either directly inherited from the very stablelisp package or is directly present in theace package. The call toimport cannot spuriously create any symbols in theuser package. On the other hand, the formatuser::string-width can make additions to theuser package that violate the assumptions made in previously compiled files.

If you are using the Window Tool Kit, theuser package will inherit the symbolstring-width from thewindows package. If you are using an image that does not contain the Window Tool Kit, you do not have awindows package to inherit from; thus, if you read in this example file, subsequent attempts to load in the Window Tool Kit will break with irreconcilable name conflicts. This problem is symptomatic of any situation in which modules or packages are separately compiled and dynamically loaded. If you use the double-colon format on a package before all of its externals are defined or before all of its requisiteuse-package links are established, irreparable damage can occur.


The Advanced User's Guide - 9 SEP 1996

Generated with Harlequin WebMaker