.c	Thursday  Dec 1,1983  23:00  LQ+4D.17H.7M.4S.  -*- Bolio -*-

.chapter "Packages"
.setq package-section-page section-page

Sketchy.  This is all going to break, either as a result of
lan{common lisp} or complete reimplementation and redesign or both.

2understanding of simple obarrays/oblists and interning is assumed
below*

The basic idea of term_i{packages} is that if all programs in a
large messy environment like lan{nil} use the same name-space for
symbols (the traditional term_i{oblist} or term_i{obarray}), then
either they will probably run into problems with naming conflicts, or
every programmer is going to have to go out of his way to ensure that
each program's names will be unique to that program.  For example, by
having naming conventions like 3reader-do-this* and
3reader-frob-uncertainly* or (heh heh) 3pkg-find-package* and
3pkg-create-package*.  (I didn't name them, they came from
lan{lisp machine lisp}.)

Packages are an attempt to solve this by allowing each program (or
"package") to have its own name-space, but allowing inheritance of
symbols from other name-spaces.  Each package may be considered to be
a symbol table (or oblist or obarray), which has a "superior"
package.  The act of interning a string in a package (to find or
create the symbol it should correspond to) involves looking in that
package's symbol table.  If there is a symbol with that print name
there, then that symbol is returned.  Otherwise, try the package's
superior package, etc.  If one gets to the "top of the tree" and no
symbol has been found, then a symbol is created with the given print
name, and inserted into the symbol table of the original package.

The lan{nil} package hierarchy looks approximately like this:
.lisp
keyword
global
  *
  sys
    system-internals
    compiler
    file-system
    gc
  format
  user
.end_lisp
The lan{global} package has in it all of the symbols which are
intended to be used (shared) by everyone.  They include function names
like 3car* and variable names like 3char-code-limit*.  The
3user* package is the package which lan{nil} starts out in, for
users to randomly use.  New isolated packages should be created under
3global*, like 3user* and 3format* are.

The 3sys* package is sort of a 3global* package for the
lan{nil} system.  It is initialized to contain those symbols which
modules in 3system-internals*, 3file-system*, etc. should
share.

The 3keyword* package is for keywords:  symbols like
3:which-operations*.  Note that it is 2not* under
3global*.  The result of this is that typing in 3:open*
results in a different symbol from typing in 3open* in any other
package, resulting in the symbol 3:open* being identified with the
keyword package, and the printing functions then being able to print
it as 3:open* rather than 3open*.

A little thought about the use of the 3sys* and 3global*
packages in the above description will show that they should not be
ordinary packages like the "terminal nodes" of the package-tree.
Adding symbols to them results in significant behavior change.  For
this reason, it is supposed to be disallowed by normal interning, and
only done by the fun_i{globalize} function ((globalize-fun)).
This check is not done currently.  Anyway, it is likely that a
different scheme will be concocted eventually.

.defun pkg-find-package name-or-package &optional losing-mode under-pkg
If 2name-or-package* is not a package, then the name is looked up
and the package returned.

...
.end_defun

.defun pkg-create-package name superior-package
.end_defun

.defun pkg-goto &optional name
Setqs 3pakcage* to the 3pkg-find-package* of 2name*;
convenient for setting the toplevel value (for which it is intended).
.end_defun

.defvar package
.end_defvar

.defun globalize name &optional in-package
.end_defun


.defun intern string-or-symbol &optional package
.end_defun

.defun intern-soft string-or-symbol &optional package
Non-side-effecting version:  if no existing symbol is found, nothing
is done and (false) is returned.
.end_defun

.defun mapatoms function &optional (pkg package) (do-superiors? t)
Calls 2function* on all symbols in 2pkg* (which is run through
3pkg-find-package* first, so may be a package name).  If
2do-superiors?* is not 3nil*, then the "superior" packages
of 2pkg* are examined also.  More generally, if
2do-superiors?* is 3nil*, the "internal" symbols only of
2pkg* are iterated over;  otherwise, all symbols accessible from
2pkg* are.  2function* could conceivably be called more than
once on the same symbol.

This is not open-compiled by the lan{nil} compiler, so may suffer
from lexical vs local variable problems.
.end_defun


.section "Modules"

lan{Common lisp} defines a fairly simple way in which one may name
2modules*, declare that they have been loaded, and cause them to
be loaded if they have not been.  While this is intended to be used as
a part of the lan{common lisp} package system, it is fairly
independent and can be used without it.  Here it is.

In this sense, a module (not to be confused with the lan{nil} data
type 3module* which will be renamed someday) is simply an
independent subsystem which is treated as a unit.  A module can
come from one or more files;  the number is irrelevant other than to
the loading process.  lan{Common lisp} modules are referenced by
name;  functions which take a module name may be given either a string
or a symbol.  In the module name, 2case matters*, so, for
instance, 3"LSB"* is not the same module name as 3"lsb"*.

.defvar *modules*
This variable has as its value a list of the names of all the modules
which have been 3provide*d (see below).  The implication is that
these modules have been loaded.
.end_defvar

.defun provide module-name
This puts 2module-name* on the list 3*modules**.  A file
loaded as part of a module should contain a call to 3provide* to
tell lan{nil} that that module has been provided.
.end_defun

.defun require module-name &optional pathname
3require* is used to load a module if it has not already been
loaded.  If 2module-name* is already provided, then 3require*
does nothing.  If 2pathname* is unspecified or 3nil*, then the
pathname (or pathnames) which need to be loaded in order to provide
2module-name* are determined in some system-dependent manner;  the
method lan{nil} uses is described below.  Otherwise, 2pathname*
may be either a single pathname or a list of pathnames;  those
pathnames are loaded.

3require* signals an error if after loading the pathname(s),
2module-name* has not been provided.
.end_defun

In lan{nil}, there is an in-core "directory" of module names and the
pathnames which must be loaded to provide those modules.  This
directory can be augmented by the 3note-module-pathname* function
(below).  If the desired module name is not there, then 3require*
will check for some out-of-core files, and load them if it has not
done so already;  these files should contain calls to
3note-module-pathname*.  The files checked for are all named
7MODULES.DAT*, and are searched for on the following directories,
in order:
.table 2 250 250 0 0 0
.item (1)
The user's home directory (see 3user-homedir-pathname*,
(user-homedir-pathname-fun))
.item (2)
The user's working directory (3user-workingdir-pathname*,
(user-workingdir-fun))
.item (3)
and 7NIL$DISK:[NIL.SITE]*, which is the directory where files
specific to a particular lan{nil} installation are kept.
.end_table
It is allowable, of course, for any or all of these files to be
missing.

.defun note-module-pathname module-name pathname
This declares that in order to provide 2module-name*,
2pathname* must be loaded.  2pathname* may also be a list of
pathnames.

Eventually, higher-level ways of defining packages, systems, and
modules will be defined, and use of 3note-module-pathname* will be
phased out.
.end_defun

The only modules known about in advance by the lan{nil} system right
now 7LSB* and 7SIMP*.  Of course, as of this writing, the
facilities documented in this section haven't even been installed yet,
so there will probably be several more shortly.

