<h1id="title-non-xs"><ahref="index.html">The Common Lisp Cookbook</a>– Packages</h1>
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
<pclass="announce">
📹 <ahref="https://www.udemy.com/course/common-lisp-programming/?couponCode=6926D599AA-LISP4ALL">NEW! Learn Lisp in videos and support our contributors with this 40% discount.</a>
</p>
<pclass="announce-neutral">
📕 <ahref="index.html#download-in-epub">Get the EPUB and PDF</a>
</p>
<divid="content"
<p>See: <ahref="http://www.flownet.com/gat/packages.pdf">The Complete Idiot’s Guide to Common Lisp Packages</a></p>
<h2id="creating-a-package">Creating a package</h2>
<p>Here’s an example package definition. It takes a name, and you
probably want to <code>:use</code> the Common Lisp symbols and functions.</p>
<p>and now, <strong>all</strong> symbols that are exported by <code>cl-ppcre</code> (aka <code>ppcre</code>)
are available to use directly in your package. However, this should be
considered bad practice, unless you <code>use</code> another package of your
project that you control. Indeed, if the external package adds a
symbol, it could conflict with one of yours, or you could add one
which will hide the external symbol and you might not see a warning.</p>
<p>To quote <ahref="https://gist.github.com/phoe/2b63f33a2a4727a437403eceb7a6b4a3">this thorough explanation</a> (a recommended read):</p>
<blockquote>
<p>USE is a bad idea in contemporary code except for internal packages that you fully control, where it is a decent idea until you forget that you mutate the symbol of some other package while making that brand new shiny DEFUN. USE is the reason why Alexandria cannot nowadays even add a new symbol to itself, because it might cause name collisions with other packages that already have a symbol with the same name from some external source.</p>
</blockquote>
<h2id="list-all-symbols-in-a-package">List all Symbols in a Package</h2>
<p>Common Lisp provides some macros to iterate through the symbols of a
package. The two most interesting are:
<ahref="http://www.lispworks.com/documentation/HyperSpec/Body/m_do_sym.htm"><code>DO-SYMBOLS</code> and <code>DO-EXTERNAL-SYMBOLS</code></a>. <code>DO-SYMBOLS</code> iterates over the
symbols accessible in the package and <code>DO-EXTERNAL-SYMBOLS</code> only iterates over
the external symbols (you can see them as the real package API).</p>
<p>To print all exported symbols of a package named “PACKAGE”, you can write:</p>
<pre><codeclass="language-lisp">(do-external-symbols (s (find-package "PACKAGE"))
(print s))
</code></pre>
<p>You can also collect all these symbols in a list by writing:</p>
<pre><codeclass="language-lisp">(let (symbols)
(do-external-symbols (s (find-package "PACKAGE"))
(push s symbols))
symbols)
</code></pre>
<p>Or you can do it with <ahref="http://www.lispworks.com/documentation/HyperSpec/Body/06_a.htm"><code>LOOP</code></a>.</p>
<pre><codeclass="language-lisp">(loop for s being the external-symbols of (find-package "PACKAGE")
collect s)
</code></pre>
<h2id="package-nickname">Package nickname</h2>
<h3id="nickname-provided-by-packages">Nickname Provided by Packages</h3>
<p>When defining a package, it is trivial to give it a nickname for better user
experience. The following example is a snippet of <code>PROVE</code> package:</p>
<pre><codeclass="language-lisp">(defpackage prove
(:nicknames :cl-test-more :test-more)
(:export :run
:is
:ok)
</code></pre>
<p>Afterwards, a user may use nickname instead of the package name to refer to this
package. For example:</p>
<pre><codeclass="language-lisp">(prove:run)
(cl-test-more:is)
(test-more:ok)
</code></pre>
<p>Please note that although Common Lisp allows defining multiple nicknames for
one package, too many nicknames may bring maintenance complexity to the
users. Thus the nicknames shall be meaningful and straightforward. For
;; You can use :nickname instead of :original-package-name
(nickname:some-function "a" "b")
</code></pre>
<p>The effect of <code>PLN</code> is totally within <code>mypackage</code> i.e. the <code>nickname</code> won’t work in other packages unless defined there too. So, you don’t have to worry about unintended package name clash in other libraries.</p>
<p>Another facility exists for adding nicknames to packages. The function <ahref="http://www.lispworks.com/documentation/HyperSpec/Body/f_rn_pkg.htm"><code>RENAME-PACKAGE</code></a> can be used to replace the name and nicknames of a package. But it’s use would mean that other libraries may not be able to access the package using the original name or nicknames. There is rarely any situation to use this. Use Package Local Nicknames instead.</p>
<h3id="package-locks">Package locks</h3>
<p>The package <code>common-lisp</code> and SBCL internal implementation packages are locked
by default, including <code>sb-ext</code>.</p>
<p>In addition, any user-defined package can be declared to be locked so that it
cannot be modified by the user. Attempts to change its symbol table or
redefine functions which its symbols name result in an error.</p>
<p>More detailed information can be obtained from documents of
<ahref="http://www.sbcl.org/manual/#Package-Locks">SBCL</a> and <ahref="https://clisp.sourceforge.io/impnotes/pack-lock.html">CLisp</a>.</p>
<p>For example, if you try the following code:</p>