Fixed indentation.

This commit is contained in:
Gerd Heber 2018-01-28 12:01:14 -06:00
parent 77fed9943d
commit fec84282fe

View File

@ -87,7 +87,7 @@
we give a complete mathematical definition of this system as a set of we give a complete mathematical definition of this system as a set of
mathematical formulas. mathematical formulas.
** Main sets of objects. * Main sets of objects.
The first part of the packaging system is made of three disjoint sets: The first part of the packaging system is made of three disjoint sets:
@ -115,7 +115,7 @@
Lisp session, and they are an essential component of the /current/ Lisp session, and they are an essential component of the /current/
environment. environment.
** Packages * Packages
There is a simple, almost bijective (one-to-one), correspondence between There is a simple, almost bijective (one-to-one), correspondence between
strings and packages, and a convenient place to start our subject. First, at strings and packages, and a convenient place to start our subject. First, at
@ -182,7 +182,7 @@
nicknames, two different packages must have disjoint sets of nicknames, two different packages must have disjoint sets of
/name + nicknames/. /name + nicknames/.
** Tracking a symbol. * Tracking a symbol.
The Lisp symbols are very particular when compared to the identifiers of The Lisp symbols are very particular when compared to the identifiers of
other programming languages. They persist throughout the runtime of an other programming languages. They persist throughout the runtime of an
@ -199,7 +199,7 @@
(multiple-value-list (find-symbol "X" "COMMON-LISP-USER")) (multiple-value-list (find-symbol "X" "COMMON-LISP-USER"))
#+END_SRC #+END_SRC
#+BEGIN_SRC lisp :session pcl :exports both #+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
(multiple-value-list (ignore-errors x)) (multiple-value-list (ignore-errors x))
#+END_SRC #+END_SRC
@ -288,7 +288,7 @@
the value of the last expression. The symbol's accessibility via the the value of the last expression. The symbol's accessibility via the
="COMMON-LISP-USER"= package is /internal/, which is to be explained later. ="COMMON-LISP-USER"= package is /internal/, which is to be explained later.
** Examining a symbol. * Examining a symbol.
A symbol is a Lisp object with a rich internal structure and there are A symbol is a Lisp object with a rich internal structure and there are
several functions for exploring symbols and their properties. Let us several functions for exploring symbols and their properties. Let us
@ -319,7 +319,9 @@
be evaluated before being used and generate an error: be evaluated before being used and generate an error:
#+BEGIN_SRC lisp :session pcl :exports both :results value verbatim #+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
(multiple-value-list (ignore-errors (symbol-name x))) (multiple-value-list
(ignore-errors
(symbol-name x)))
#+END_SRC #+END_SRC
The package which /owns/ a symbol, its /home package/, can be determined The package which /owns/ a symbol, its /home package/, can be determined
@ -396,14 +398,16 @@
Don't forget to quote the symbol! See the following error: Don't forget to quote the symbol! See the following error:
#+BEGIN_SRC lisp :session pcl :exports both :results value verbatim #+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
(multiple-value-list (ignore-errors (symbol-value x))) (multiple-value-list
(ignore-errors
(symbol-value x)))
#+END_SRC #+END_SRC
A symbol can also have a /functional value/. This does not mean that the A symbol can also have a /functional value/. This does not mean that the
value we just discussed could be a function (which it could be!). It means value we just discussed could be a function (which it could be!). It means
that /besides/ the previous value, a symbol can also have an /additional/ that /besides/ the previous value, a symbol can also have an /additional/
value, a function, which can be used independently of the "ordinary" value value, a function, which can be used independently of the "ordinary" value
of this symbol. For example the function $n \mapsto 10−n$ could be recorded of this symbol. For example the function $n \mapsto 10 - n$ could be recorded
as the /functional/ value of the same symbol, and this function could then as the /functional/ value of the same symbol, and this function could then
be used as shown below. be used as shown below.
@ -458,7 +462,7 @@
+-----------------+ +-----------------+
#+END_EXAMPLE #+END_EXAMPLE
** But what the hell is a package? * But what the hell is a package?
Now we attack the heart of our subject.\\ Now we attack the heart of our subject.\\
@ -467,4 +471,118 @@
- A list $InS(p)$ of its internal symbols. - A list $InS(p)$ of its internal symbols.
- A list $ExS(p)$ of its external symbols. - A list $ExS(p)$ of its external symbols.
- A list $ShgS(p)$ of its shadowing symbols. - A list $ShgS(p)$ of its shadowing symbols.
- A list $U(p)$ of its used packages. - A list $U(p)$ of its used packages.\\
The first important fact toward understanding the subject is this: the first
three lists are lists of /symbols/ or, more precisely, lists of pointers
(machine addresses) aimed at the symbols. Every symbol has a /unique/
"existence": a symbol is a unique machine object in the environment, but
/several/ packages may /see/ the same symbol, that is, include the machine
address of this symbol. In particular these lists are not lists of symbol
names (strings). There is another mechanism that allows Lisp to reach a
symbol given its name. Every symbol can be accessed directly via a suitable
package, and several packages can in general play this role for the same
symbol at a given moment in a Lisp session. For example, all the
[[http://clhs.lisp.se/Front/X_Symbol.htm][standard Lisp symbols]] in the ="COMMON-LISP"= package typically are
accessible via any package.
No duplicate symbol (more precisely, no duplicate pointer) is to be found in
each of these lists. Also the relations $InS(p)\cap ExS(p)=\emptyset$ and
$ShgS(p)\subset InS(p)\cup ExS(p)$ must be satisfied, for reasons to be
studied later.\\
**Fact 2:** Given the current set of packages, assumed /coherent/, and given
the current state of all the fundamental lists of these packages, the
function =find-symbol= can unambiguously determine /whether/ a symbol of a
given name (some string) is /accessible/ via some package; if so, this
symbol is unique.\\
The importance of the package argument of =find-symbol= could make the
reader believe the function =symbol-package= will be useful for various
tests. This is not the case: All this function returns is the "birth place"
of the symbol, technically called its /home package/, which says almost
nothing about the current status of this symbol with respect to any package.
All it says is that at least it is /interned/ in this package. In
particular, a symbol can be accessible via several packages, possibly
different from its home package. Here is a simple illustration:
#+BEGIN_SRC lisp :session pcl :exports both
(symbol-package 'nil)
#+END_SRC
#+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
(multiple-value-list (find-symbol "NIL" "COMMON-LISP"))
#+END_SRC
#+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
(multiple-value-list (find-symbol "NIL" "COMMON-LISP-USER"))
#+END_SRC
#+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
(eq (find-symbol "NIL" "COMMON-LISP")
(find-symbol "NIL" "COMMON-LISP-USER"))
#+END_SRC
The /home package/ of =nil= is ="COMMON-LISP"=, and this symbol of name
="NIL"= is accessible via ="COMMON-LISP"=, but also via
="COMMON-LISP-USER"=, though not with the same status. It is /external/ in
the first case and /inherited/ in the second case, points to be examined
later. The value (=T=) of the last expression /proves/ that both symbols,
determined by =find-symbol= via different packages, in fact are the same.
Fact 2 can be made a little more precise: At any given time during a Lisp
session, a set $P$ of packages and a set $Sm$ of symbols are defined. The
various lists of symbols $InS(p)$, $ExS(p)$ and $ShgS(p)$, and the list
$U(p)$ of packages used by a package $p\in P$ together define without any
ambiguity which symbols are accessible via the package $p$. In other words,
there is a well defined function $\rho$:
$$
\rho: P \longrightarrow [St \longrightarrow Sm \cup \{\mathtt{nil}\}]
$$
We chose the letter $\rho$ for reader, because this function is mainly used
by the reader. Our "mathematical" function $\rho$ is nothing but an avatar
of the Lisp function =find-symbol=. Let $p\in P$ be a package and
$st\in St$ be a string. Then:
$$
\rho(p)(st) = (\mathtt{find-symbol}\; st\; p)
$$
The left-hand side uses the standard mathematical functional notation, and
the right-hand one uses the Lisp notation. If no symbol is found for a pair
$(st, p)$, the symbol (!) =nil= is returned and the second value of
=find-symbol=, the symbol =nil= again, tells the user that the symbol search
did not return anything. A package $p$ is nothing but a way of defining the
function $\rho(p):St\longrightarrow Sm\cup\{\mathtt{nil}\}$. In other words,
the four fundamental lists of a package determine what character strings
appear as the names of the symbols accessible via this package.
This approach is described in detail now.
* Internal symbols.
The first fundamental list of a package is the list of its /internal
symbols/. It is a pity that no standard Lisp function can produce this list,
but here is a simple solution to the problem:
#+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
(defun package-internal-symbols (package)
(let ((rslt))
(do-symbols (s package)
(when (eq (second
(multiple-value-list
(find-symbol (symbol-name s) package)))
:internal)
(push s rslt)))
rslt))
#+END_SRC
We can list now all the internal symbols of a package:
#+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
(package-internal-symbols "COMMON-LISP-USER")
#+END_SRC
In fact, only the first ten internal symbols are displayed. We see in
particular the symbols =package-internal-symbols=, =s= and =rslt= used in
the definition of our function. Some are rather esoteric, strictly speaking
illegal: at the beginning of a Lisp session, the ="COMMON-LISP-USER"=
package should in principle be void of symbols. To make our experiments more
understandable it is better to allocate and use toy packages. The
[[http://clhs.lisp.se/Body/m_defpkg.htm][=defpackage=]] function (a macro) allocates a package of a given name.