;;; -*- Mode:gate; Fonts:(HL12 HL12I HL12B CPTFONTB HL12BI HL12B HL12I ) -*- =Node: 4Operating on All the Symbols in a Package* =Text: 3OPERATING ON ALL THE SYMBOLS IN A PACKAGE* To find and operate on every symbol present or available in a package, you can choose between iteration macros that resemble 2dolist* and mapping functionals that resemble 2mapcar*. Note that all constructs that include inherited symbols in the iteration can process a symbol more than once. This is because a symbol can be directly present in more than one package. If it is directly present in the specified package and in one or more of the used packages, the symbol is processed once each time it is encountered. It is also possible for the iteration to include a symbol that is not actually available in the specified package. If that package shadows symbols present in the packages it uses, the shadowed symbols are processed anyway. If this is a problem, you can explicitly use 2intern-soft* to see if the symbol handed to you is really available in the package. This test is not done by default because it is slow and rarely needed. 3do-symbols* 1(var* 1package* 1result-form)* 1body...* 1Macro* Executes 1body* once for each symbol findable in 1package* either directly or through inheritance. On each iteration, the variable 1var* is bound to the next such symbol. Finally the 1result-form* is executed and its values are returned. 3do-local-symbols* 1(var* 1package* 1result-form)* 1body...* 1Macro* Executes 1body* once for each symbol present directly in 1package*. Inherited symbols are not considered. On each iteration, the variable 1var* is bound to the next such symbol. Finally the 1result-form* is executed and its values are returned. 3do-external-symbols* 1(var* 1package* 1result-form)* 1body...* 1Macro* Executes 1body* once for each external symbol findable in 1package* either directly or through inheritance. On each iteration, the variable 1var* is bound to the next such symbol. Finally the 1result-form* is executed and its values are returned. 3do-local-external-symbols* 1(var* 1package* 1result-form)* 1body...* 1Macro* Executes 1body* once for each external symbol present directly in 1package*. Inherited symbols are not considered. On each iteration, the variable 1var* is bound to the next such symbol. Finally the 1result-form* is executed and its values are returned. 3do-all-symbols* 1(var* 1result-form)* 1body...* 1Macro* Executes 1body* once for each symbol present in any package. On each iteration, the variable 1var* is bound to the next such symbol. Finally the 1result-form* is executed and its values are returned. Since a symbol can be directly present in more than one package, it is possible for the same symbol to be processed more than once. 3mapatoms* 1function* &optional 1(package* 1*package*)* 1(inherited-p* 1t)* 1function* should be a function of one argument. 2mapatoms* applies 1function* to all of the symbols in 1package*. If 1inherited-p* is non-2nil*, then the function is applied to all symbols available in 1package*, including inherited symbols. 3mapatoms-all* 1function* &optional 1(package* 1"GLOBAL")* 1function* should be a function of one argument. 2mapatoms-all* applies 1function* to all of the symbols in 1package* and all other packages which use 1package*. It is used by such functions as 2apropos* and 2who-calls* (see 4(MISCELL-1)Poking Around in the Lisp World*) Example: 3(mapatoms-all* 3 #'(lambda (x)* 3 (and (alphalessp 'z x)* 3 (print x))))* =Node: 4Packages as Lisp Objects* =Text: 3PACKAGES AS LISP OBJECTS* A package is a conceptual name space; it is also a Lisp object which serves to record the contents of that name space, and is passed to functions such as 2intern* to identify a name space. 3packagep* 1object* 2t* if object is a package. 3*all-packages** 1Variable* The value is a list of all packages, except for invisible ones (see the 1invisble* argument to 2make-package*, 4(PACKAGES-1)Defining Packages*). 3list-all-packages* A Common Lisp function which returns 2*all-packages**. 3pkg-global-package* 1Constant* 3pkg-system-package* 1Constant* 3pkg-keyword-package* 1Constant* Respectively, the packages named 2global*, 2system* and 2keyword*. 3describe-package* 1package* Prints everything there is to know about 1package*, except for all the symbols interned in it. 1package* can be specified as a package or as the name of one. To see all the symbols interned in a package, do 3(mapatoms 'print 1package*)* =Node: 4Common Lisp and Packages* =Text: 3COMMON LISP AND PACKAGES* Common Lisp does not have 2defpackage* or 3-*-* lines in files. One is supposed to use the function 2in-package* to specify which package a file is loaded in. 3in-package* 1name* &key 1nicknames* 1use* Creates a package named 1name*, with specified nicknames and used packages, or modifies an existing package named 1name* to have those nicknames and used packages. Then 2*package** is set to this package. Writing a call to 2in-package* at the beginning of the file causes 2*package** to be set to that package for the rest of the file. If you wish to use this technique for the sake of portability, it is best to have a 3-*-* line with a package attribute also. While 2in-package* does work for loading and compilation of the file, Zmacs does not respond to it. In Common Lisp, the first argument to 2intern* or 2find-symbol* is required to be a symbol. =Node: 4Initialization of the Package System* =Text: 3INITIALIZATION OF THE PACKAGE SYSTEM* This section describes how the package system is initialized when generating a new software release of the Lisp Machine system; none of this should affect users. The cold load, which contains the irreduceable minimum of the Lisp system needed for loading the rest, contains the code for packages, but no packages. Before it begins to read from the keyboard, it creates all the standard packages based on information in 2si:initial-packages*, applying 2make-package* to each element of it. At first all of the packages are empty. The symbols which belong in the packages 2global* and 2system* are recorded on lists which are made from the files 2SYS: SYS2; GLOBAL LISP* and 2SYS: SYS2; SYSTEM LISP*. Symbols referred to in the cold load which belong in packages other than 2si* have strings (package names) in their package slots; scanning through the area which contains all the symbols, the package initializer puts each such symbol into the package it specifies, and all the rest into 2si* unless they are already in 2global* or 2system*. =Node: 4Initial Packages* =Text: 3INITIAL PACKAGES* The initially present packages include: 2global* Contains advertised global functions. 2user* The default current package for the user's type-in. 2sys or system* Contains internal global symbols used by various system programs. Many system packages use 2system*. 2si or system-internals* Contains subroutines of many advertised system functions. Many files of the Lisp system are loaded in 2si*. 2compiler* Contains the compiler. 2compiler* uses 2sys*. 2fs or file-system* Contains the code that deals with pathnames and accessing files. 2fs* uses 2sys*. 2eh or dbg* Contains the error handler and the debugger. Uses 2sys*. 2cc or cadr* Contains the program that is used for debugging another machine. Uses 2sys*. 2chaos* Contains the Chaosnet controller. Uses 2sys*. 2tv* Contains the window system. Uses 2sys*. 2zwei* Contains the editor. 2format* Contains the function 2format* and its associated subfunctions. 2cli* (Common Lisp Incompatible) contains symbols such as 2cli:member* which the same pname as symbols in 2global* but incompatible definitions. There are quite a few others, but it would be pointless to list them all. Packages that are used for special sorts of data: 2fonts* Contains the names of all fonts. 2format* Contains the keywords for 2format*, as well as the code. 2keyword* Contains all keyword symbols, symbols always written with a plain colon as a prefix. These symbols are peculiar in that they are automatically given themselves as values. Here is a picture depicting the initial package inheritance structure 3 global keyword* 3 | * 3 /-----------------------------------\ fonts* 3 | | | | |* 3 user zwei system format (etc) cli* 3 |* 3 /----------------------------------\* 3 | | | | | |* 3 system-internals eh chaos cadr fs compiler* .eof =Node: 4Multiple Instantiations of a Program* =Text: 3MULTIPLE INSTANTIATIONS OF A PROGRAM* This isn't finished yet, which is why we don't say how to do any of this. Suppose a maintainer of ZWEI (the Lisp Machine editor) has made some changes to ZWEI, and would like to debug them. He has a problem: if he reads in the new version, which presumably may be full of bugs, then he will not be able to do any editing! This would be annoying, since the editor is very useful. We would like both the regular and the experimental versions of the editor to 1both* be loaded into the Lisp world. In order for two definitions of each editor function to coexist, we need to load the new version into a separate package, which must have a different name (not named 2zwei*, like the package the original editor is in). If the test version's package is called 2test-zwei*, then the user can try it by calling 2(test-zwei:ed)*, and edit it using 2(ed)*. However, there is a problem to be faced. The editor redefines a few entry-point functions (2ed*, 2edprop*, etc) which reside in 2global*. If the test editor redefined them, the whole point of the separate package would be lost. So, the 2test-zwei* package must 2shadow* all these symbols. Further complications are needed to make it possible to test one program using another instead of by hand. Suppose that there is a program named 2random* residing in its own package, and containing a function named 2number*. Suppose that we have a debugged program 2dp* (Dissociated Press) which uses 2random:number*. And now, we have written a new version of 2random* and want to test it using 2dp*, without installing it and breaking system tools which use 2random*. What we want to do is to load in a test version of 2random*, 2test-random*, and also a 2test-dp* which will refer to it, to test it with. This can be done if we can make the 2test-dp* package take references to 2random* as references to the 2test-random* package. All this takes is an entry on 2test-dp*'s refname-alist, associating the name 2random* with the 2test-random* package. Then, when 2random:number* is seen in the course of reading in the old 2dp* program into 2test-dp*, 2test-random:number* will actually be used. Note that normally 2test-dp* wouldn't have an entry on its own refname-alist for 2random*; it would inherit the association from 2global*. We are actually shadowing in 2test-dp* the definition of 2random* as a package refname which is present in 2global*. Here is what we will get. 3 global [random -> random]* 3 |* 3 /-----------------------------------------------\* 3 | | | |* 3 dp => random test-dp => test-random* 3 [random -> test-random]* (`=>' indicates who calls whom; `->' indicates a refname). So far, every package has had its own name as a refname for itself. A test package, however, shouldn't have its actual name as a refname for itself, but the name its program expects: 2random*, not 2test-random*. This is necessary to handle test packages with subpackages right, together with shadowing. In fact every package has a ``program name'' as well as a ``name''. For ordinary packages, they are the same, but for a test package, the program name is identical to that of the original package. Suppose we have the Macsyma program with all of its sub-packages as described above. Further assume that the 2input* sub-program's author has his own symbol named 2simp*, and he calls 2macsyma:simp* in various places to get the one in the 2macsyma* package. Now, say someone wants to load an experimental 2macsyma* into the machine: he would name the new obarray 2test-macsyma* or something. In order to assure that the reference to 2macsyma:simp* is properly resolved, the refname-alist of 2test-macsyma* must contain 2test-macsyma* under the name 2macsyma*. This, finally, is the reason why each package has a reference to itself on its refname-alist.