Dealing w/ packages in Org.
This commit is contained in:
parent
fec84282fe
commit
c0a5a2b7da
@ -586,3 +586,173 @@
|
||||
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.
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
|
||||
(defpackage "P1" (:use "CL"))
|
||||
#+END_SRC
|
||||
|
||||
A package ="P1"= is now present in our environment, without any internal
|
||||
symbols.
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
|
||||
(package-internal-symbols "P1")
|
||||
#+END_SRC
|
||||
|
||||
(The symbol =nil= also represents the empty list.) Let's allocate a few
|
||||
symbols and make them internal in the package ="P1"=! The current default
|
||||
package is ="COMMON-LISP-USER"= and we switch it to ="P1"= like this:
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :results value verbatim
|
||||
(in-package "P1")
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1"
|
||||
*package*
|
||||
#+END_SRC
|
||||
|
||||
From now on, the default package is ="P1"=. If we write down a symbol then it
|
||||
will be understood by the Lisp reader as accessed via the package ="P1"=,
|
||||
that is, unless we use a special syntax. Let us create a list of three
|
||||
symbols and assign it to the symbol =list=, and then examine the internal
|
||||
symbols of the package ="P1"=:
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1"
|
||||
(multiple-value-list
|
||||
(ignore-errors
|
||||
(setf (symbol-value 'list) '(symb1 symb2 symb3))))
|
||||
#+END_SRC
|
||||
|
||||
The reader probably would prefer =(defvar list)= followed by
|
||||
=(setf list ...)=, which is rejected by some Lisp implementations, in
|
||||
particular SBCL, because in principle the symbol =list=, owned by the package
|
||||
="COMMON-LISP"=, is "locked". It is possible to unlock such a symbol, which
|
||||
is a little technical, but using =(symbol-value 'list)= as above gets the job
|
||||
done.
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1"
|
||||
(multiple-value-list
|
||||
(ignore-errors
|
||||
(package-internal-symbols "P1")))
|
||||
#+END_SRC
|
||||
|
||||
Oops! What happened? We've successfully used the function
|
||||
=package-internal-symbols= earlier and suddenly it seems to have disappeared
|
||||
from the environment. The point is that it was /defined when/
|
||||
="COMMON-LISP-USER"= was the default package. Let us examine the situation!
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1" :results value verbatim
|
||||
(multiple-value-list (find-symbol "PACKAGE-INTERNAL-SYMBOLS" "COMMON-LISP-USER"))
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1" :results value verbatim
|
||||
(multiple-value-list (find-symbol "PACKAGE-INTERNAL-SYMBOLS" "P1"))
|
||||
#+END_SRC
|
||||
|
||||
A symbol with the given name is found in both packages. Before encountering
|
||||
the undefined functional value error, Lisp ( more precisely, the Lisp reader)
|
||||
had interned a /new/ symbol with the name ="PACKAGE-INTERNAL-SYMBOLS"= in the
|
||||
current default package, ="P1"=, for the sole reason that it was present in
|
||||
the source text. Let us verify that both symbols are different!
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1"
|
||||
(eq (find-symbol "PACKAGE-INTERNAL-SYMBOLS" "COMMON-LISP-USER")
|
||||
(find-symbol "PACKAGE-INTERNAL-SYMBOLS" "P1"))
|
||||
#+END_SRC
|
||||
|
||||
The symbols are different. Compare that with the status of =nil=, where the
|
||||
same symbol =nil= was accessible via ="COMMON-LISP"= and via
|
||||
="COMMON-LISP-USER"=. In our present situation both symbols are /different/,
|
||||
and so are their respective properties. For example, the first symbol does
|
||||
have a functional value and the second does not, which can be tested with the
|
||||
function [[http://clhs.lisp.se/Body/f_fbound.htm][=fboundp=]]x:
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1"
|
||||
(fboundp (find-symbol "PACKAGE-INTERNAL-SYMBOLS" "COMMON-LISP-USER"))
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1"
|
||||
(fboundp (find-symbol "PACKAGE-INTERNAL-SYMBOLS" "P1"))
|
||||
#+END_SRC
|
||||
|
||||
This is the first time we have seen the double-colon =‘::’= notation: When
|
||||
the symbol =package-internal-symbols= was searched via ="COMMON-LISP-USER"=,
|
||||
the answer was positive but the returned symbol was a little lengthy:
|
||||
=COMMON-LISP-USER::PACKAGE-INTERNAL-SYMBOLS=. The current default package is
|
||||
="P1"=, via which /this/ symbol is not accessible. However, we may access it
|
||||
using the double-colon notation:
|
||||
|
||||
#+BEGIN_CENTER
|
||||
=package-name::symbol-name=
|
||||
#+END_CENTER
|
||||
|
||||
This is one of the methods which allows the user or Lisp to refer to a symbol
|
||||
not accessible via the default package. The Lisp reader is told: "We mean the
|
||||
symbol =symbol-name= via the package =package-name=." In contrast, for the
|
||||
symbol with the same name but interned in the different ="P1"= package,
|
||||
because ="P1"= is the current default package, the double colon notation is
|
||||
not necessary. The longer notation lets us access a symbol interned in the
|
||||
="COMMON-LISP-USER"= package and its functional value as follows:
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1" :results value verbatim
|
||||
(cl-user::package-internal-symbols "P1")
|
||||
#+END_SRC
|
||||
|
||||
The =cl-user::= prefix tells Lisp to look for the symbol via the ="CL-USER"=
|
||||
package (Remember that ="CL-USER"= is a nickname for ="COMMON-LISP-USER"=?)
|
||||
and, because of its position just after a left parenthesis, to use its
|
||||
functional value. Currently, there are four internal symbols in the package
|
||||
="P1"= and they are returned in an arbitrary order. By the way, what about
|
||||
the symbol =list=, to which we assigned a list (!) of symbols?
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1" :results value verbatim
|
||||
(multiple-value-list (find-symbol "LIST" "P1"))
|
||||
#+END_SRC
|
||||
|
||||
The symbol is accessible via the package ="P1"= but with a different status,
|
||||
the status /inherited/. We will examine this situation later. In fact, the
|
||||
symbol =list=, one of the most important symbols in Lisp, is already present
|
||||
in the package ="COMMON-LISP"= at the beginning of a session, and by default
|
||||
accessible from any package.
|
||||
|
||||
We must mention also that our function $\rho$, or the function =find-symbol=
|
||||
if you prefer, is (almost) injective /with respect to/ $st$. Let $p_1$ and
|
||||
$p_2$ be two packages, $st_1$ and $st_2$ two strings. Then if
|
||||
$\rho(p_1, st_1) = \rho(p_2, st_2)\neq\mathtt{nil}$, then $st_1 = st_2$. Pay
|
||||
attention to the fact that the equality is an equality between /symbols/.
|
||||
This is a consequence of $\mathtt{symbol-name}(\rho(p, st)) = st$; in other
|
||||
words, there is no possibility of nicknames for a symbol name. In particular,
|
||||
there is a 1-1 correspondence between the internal symbols of a package and
|
||||
their respective names.
|
||||
|
||||
* Importing a symbol.
|
||||
|
||||
Instead of using the lengthy notation =cl-user::xxx= to make an internal
|
||||
symbol in ="CL-USER"= accessible from ="P1"=, we may opt to /import/ this
|
||||
symbol in the package ="P1"=. However, in doing so there is another problem
|
||||
due to a name conflict, a point which will be examined in detail later:
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1" :results value verbatim
|
||||
(multiple-value-list
|
||||
(ignore-errors
|
||||
(import 'cl-user::package-internal-symbols "P1")))
|
||||
#+END_SRC
|
||||
|
||||
The problem is a "collision" between two /different/ symbols, which cannot
|
||||
coexist as internal symbols in the /same/ package ="P1"= with the /same/
|
||||
name. Importing the symbol internal in ="CL-USER"= into the package ="P1"= is
|
||||
not compatible with the current presence of /another/ symbol in ="P1"= with
|
||||
the same =symbol-name=. We must first [[http://clhs.lisp.se/Body/f_uninte.htm][=unintern=]] the accidental, pre-existing
|
||||
symbol in ="P1"= to "make room" for the symbol from ="CL-USER"=.
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1" :results value verbatim
|
||||
(unintern 'package-internal-symbols "P1")
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1" :results value verbatim
|
||||
(import 'cl-user::package-internal-symbols "P1")
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC lisp :session pcl :exports both :package "P1" :results value verbatim
|
||||
(package-internal-symbols "P1")
|
||||
#+END_SRC
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user