Update lispcookbook
This commit is contained in:
parent
570d0f9c9b
commit
aa4aea440e
42 changed files with 1998 additions and 1015 deletions
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Multidimensional arrays</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Multidimensional arrays</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -1101,7 +1106,7 @@ The <code>#i</code> reader macro recognises many of these, and uses the
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Fundamentals of CLOS</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Fundamentals of CLOS</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -880,6 +885,23 @@ closer-mop:standard-accessor-method
|
||||||
|
|
||||||
<h3 id="see-also">See also</h3>
|
<h3 id="see-also">See also</h3>
|
||||||
|
|
||||||
|
<h4 id="slime-export-class-symbols">Slime export class symbols</h4>
|
||||||
|
|
||||||
|
<p>The command <strong>M-x slime-export-class</strong> will add the class symbols to the “:export” clause of your package definition. This way, you can export dozens of symbols all at once.</p>
|
||||||
|
|
||||||
|
<p>Imagine you have this class:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-lisp">(defclass test ()
|
||||||
|
((foo :accessor foo)
|
||||||
|
(bar :reader bar)))
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Using “M-x slime-export-class RET test RET” will export “test”, “foot” and “bar”.</p>
|
||||||
|
|
||||||
|
<p>Removing a slot from the class definition will alas not remove it from the export clause.</p>
|
||||||
|
|
||||||
|
<p>This works also on structures (only on SBCL and Clozure CL).</p>
|
||||||
|
|
||||||
<h4 id="defclassstd-write-shorter-classes">defclass/std: write shorter classes</h4>
|
<h4 id="defclassstd-write-shorter-classes">defclass/std: write shorter classes</h4>
|
||||||
|
|
||||||
<p>The library <a href="https://github.com/EuAndreh/defclass-std">defclass/std</a>
|
<p>The library <a href="https://github.com/EuAndreh/defclass-std">defclass/std</a>
|
||||||
|
@ -1900,7 +1922,7 @@ this new class, and compute new slots intelligently. Use
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Data structures</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Data structures</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -76,8 +81,8 @@ also have many more details:</p>
|
||||||
<li><a href="http://gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing.html">Practical CL</a>, by Peter Seibel</li>
|
<li><a href="http://gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing.html">Practical CL</a>, by Peter Seibel</li>
|
||||||
<li><a href="http://weitz.de/cl-recipes/">CL Recipes</a>, by E. Weitz, full of explanations and tips,</li>
|
<li><a href="http://weitz.de/cl-recipes/">CL Recipes</a>, by E. Weitz, full of explanations and tips,</li>
|
||||||
<li>the
|
<li>the
|
||||||
<a href="http://cberr.us/tech_writings/notes/common_lisp_standard_draft.html">CL standard</a>
|
<a href="https://franz.com/support/documentation/cl-ansi-standard-draft-w-sidebar.pdf">CL standard</a>
|
||||||
with a nice TOC, functions reference, extensive descriptions, more
|
with – in the sidebar of your PDF reader – a nice TOC, functions reference, extensive descriptions, more
|
||||||
examples and warnings (i.e: everything). <a href="https://gitlab.com/vancan1ty/clstandard_build/-/blob/master/cl-ansi-standard-draft-w-sidebar.pdf">PDF mirror</a></li>
|
examples and warnings (i.e: everything). <a href="https://gitlab.com/vancan1ty/clstandard_build/-/blob/master/cl-ansi-standard-draft-w-sidebar.pdf">PDF mirror</a></li>
|
||||||
<li>a <a href="http://clqr.boundp.org/">Common Lisp quick reference</a></li>
|
<li>a <a href="http://clqr.boundp.org/">Common Lisp quick reference</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -254,11 +259,15 @@ containing the elements of all its arguments:</p>
|
||||||
|
|
||||||
<p><code>nconc</code> is the recycling equivalent.</p>
|
<p><code>nconc</code> is the recycling equivalent.</p>
|
||||||
|
|
||||||
<h3 id="push-item-place">push (item, place)</h3>
|
<h3 id="push-pushnew-item-place">push, pushnew (item, place)</h3>
|
||||||
|
|
||||||
<p><code>push</code> prepends <em>item</em> to the list that is stored in <em>place</em>, stores
|
<p><code>push</code> prepends <em>item</em> to the list that is stored in <em>place</em>, stores
|
||||||
the resulting list in <em>place</em>, and returns the list.</p>
|
the resulting list in <em>place</em>, and returns the list.</p>
|
||||||
|
|
||||||
|
<p><code>pushnew</code> is similar, but it does nothing if the element already exists in the place.</p>
|
||||||
|
|
||||||
|
<p>See also <code>adjoin</code> below that doesn’t modify the target list.</p>
|
||||||
|
|
||||||
<pre><code class="language-lisp">(defparameter mylist '(1 2 3))
|
<pre><code class="language-lisp">(defparameter mylist '(1 2 3))
|
||||||
(push 0 mylist)
|
(push 0 mylist)
|
||||||
;; => (0 1 2 3)
|
;; => (0 1 2 3)
|
||||||
|
@ -281,6 +290,8 @@ more costly operation (have to traverse the whole list). So if you
|
||||||
need to do this: either consider using another data structure, either
|
need to do this: either consider using another data structure, either
|
||||||
just <code>reverse</code> your list when needed.</p>
|
just <code>reverse</code> your list when needed.</p>
|
||||||
|
|
||||||
|
<p><code>pushnew</code> accepts key arguments: <code>:key</code>, <code>:test</code>, <code>:test-not</code>.</p>
|
||||||
|
|
||||||
<h3 id="pop">pop</h3>
|
<h3 id="pop">pop</h3>
|
||||||
|
|
||||||
<p>a destructive operation.</p>
|
<p>a destructive operation.</p>
|
||||||
|
@ -784,6 +795,8 @@ list-a
|
||||||
;; => (0 1 2 3) ;; <-- original list unmodified.
|
;; => (0 1 2 3) ;; <-- original list unmodified.
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
|
<p>You can also use <code>pushnew</code>, that modifies the list (see above).</p>
|
||||||
|
|
||||||
<h3 id="check-if-this-is-a-subset-subsetp">Check if this is a subset (<code>subsetp</code>)</h3>
|
<h3 id="check-if-this-is-a-subset-subsetp">Check if this is a subset (<code>subsetp</code>)</h3>
|
||||||
|
|
||||||
<pre><code class="language-lisp">(subsetp '(1 2 3) list-a)
|
<pre><code class="language-lisp">(subsetp '(1 2 3) list-a)
|
||||||
|
@ -879,18 +892,36 @@ vector.</em></p>
|
||||||
;; => #(1 2 3)
|
;; => #(1 2 3)
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p><code>vector-push</code> <em>(foo vector)</em>: replace the vector element pointed to by
|
<p>The following interface is available for vectors (or vector-like arrays):</p>
|
||||||
the fill pointer by foo. Can be destructive.</p>
|
|
||||||
|
|
||||||
<p><code>vector-push-extend</code> <em>(foo vector [extension-num])</em>t</p>
|
<ul>
|
||||||
|
<li><code>vector-push</code> <em>(new-element vector)</em>: replace the vector element pointed to by the fill pointer by <code>new-element</code>, then increment the fill pointer by one. Returns the index at which the new element was placed, or NIL if there’s not enough space.</li>
|
||||||
<p><code>vector-pop</code> <em>(vector)</em>: return the element of vector its fill pointer
|
<li><code>vector-push-extend</code> <em>(new-element vector [extension])</em>: like <code>vector-push</code>, but if the fill pointer gets too large then the array is extended using <code>adjust-array</code>. <code>extension</code> is the minimum number of elements to add to the array if it must be extended.</li>
|
||||||
points to.</p>
|
<li><code>vector-pop</code> <em>(vector)</em>: decrement the fill pointer, and return the element that it now points to.</li>
|
||||||
|
<li><code>fill-pointer</code> <em>(vector)</em>. <code>setf</code>able.</li>
|
||||||
<p><code>fill-pointer</code> <em>(vector)</em>. <code>setf</code>able.</p>
|
</ul>
|
||||||
|
|
||||||
<p>and see also the <em>sequence</em> functions.</p>
|
<p>and see also the <em>sequence</em> functions.</p>
|
||||||
|
|
||||||
|
<p>The following shows how to create an array that can be pushed to and popped from arbitrarily, growing its storage capacity as needed. This is roughly equivalent to a <code>list</code> in Python, an <code>ArrayList</code> in Java, or a <code>vector<T></code> in C++ – though note that elements are not erased when they’re popped.</p>
|
||||||
|
|
||||||
|
<pre><code class="language-lisp">CL-USER> (defparameter *v* (make-array 0 :fill-pointer t :adjustable t))
|
||||||
|
*V*
|
||||||
|
CL-USER> *v*
|
||||||
|
#()
|
||||||
|
CL-USER> (vector-push-extend 42 *v*)
|
||||||
|
0
|
||||||
|
CL-USER> (vector-push-extend 43 *v*)
|
||||||
|
1
|
||||||
|
CL-USER> (vector-pop *v*)
|
||||||
|
43
|
||||||
|
CL-USER> *v*
|
||||||
|
#(42)
|
||||||
|
CL-USER> (aref *v* 1) ; beware, the element is still there!
|
||||||
|
43
|
||||||
|
CL-USER> (setf (aref *v* 1) nil) ; manually erase elements if necessary
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
<h3 id="transforming-a-vector-to-a-list">Transforming a vector to a list.</h3>
|
<h3 id="transforming-a-vector-to-a-list">Transforming a vector to a list.</h3>
|
||||||
|
|
||||||
<p>If you’re mapping over it, see the <code>map</code> function whose first parameter
|
<p>If you’re mapping over it, see the <code>map</code> function whose first parameter
|
||||||
|
@ -1974,7 +2005,7 @@ an intermediary key doesn’t exist.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Database Access and Persistence</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Database Access and Persistence</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -944,7 +949,7 @@ tables, runs the code and connects back to the original DB connection.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Dates and Times</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Dates and Times</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -561,7 +566,7 @@ local-time library:</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Debugging</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Debugging</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -281,9 +286,6 @@ traced:</p>
|
||||||
|
|
||||||
<p>The output is printed to <code>*trace-output*</code> (see the CLHS).</p>
|
<p>The output is printed to <code>*trace-output*</code> (see the CLHS).</p>
|
||||||
|
|
||||||
<p>In Slime, we also have an interactive trace dialog with <code>M-x
|
|
||||||
slime-trace-dialog</code> bound to <code>C-c T</code>.</p>
|
|
||||||
|
|
||||||
<h3 id="trace-options">Trace options</h3>
|
<h3 id="trace-options">Trace options</h3>
|
||||||
|
|
||||||
<p><code>trace</code> accepts options. For example, you can use <code>:break t</code> to invoke
|
<p><code>trace</code> accepts options. For example, you can use <code>:break t</code> to invoke
|
||||||
|
@ -437,6 +439,50 @@ your implementation’s documentation:</p>
|
||||||
|
|
||||||
<p>See the <a href="clos.html">CLOS</a> section for a tad more information.</p>
|
<p>See the <a href="clos.html">CLOS</a> section for a tad more information.</p>
|
||||||
|
|
||||||
|
<h3 id="interactive-trace-dialog">Interactive Trace Dialog</h3>
|
||||||
|
|
||||||
|
<p>Both SLIME and SLY provide an <a href="https://slime.common-lisp.dev/doc/html/SLIME-Trace-Dialog.html#SLIME-Trace-Dialog">interactive view for traces</a> that features better visualization of traces, and also access to the arguments and return values in their real form, via inspectors, not just the printed representation.</p>
|
||||||
|
|
||||||
|
<p><img src="trace-dialog.png" alt="trace-dialog" title="Trace dialog" /></p>
|
||||||
|
|
||||||
|
<p>How it works: (the following instructions are for SLIME)</p>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>Select the functions to trace using <code>M-x slime-trace-dialog-toggle-trace</code> bound to <code>C-c M-t</code>.</li>
|
||||||
|
<li>Evaluate code that calls the traced functions.</li>
|
||||||
|
<li>Open the trace dialog tool via <code>M-x slime-trace-dialog</code> bound to <code>C-c T</code>.</li>
|
||||||
|
<li>The list of traced functions appear under <code>Traced specs</code>.
|
||||||
|
Traces are fetched in batches. So use the the <code>[refresh]</code> button to update status information about tracing (number of available traces that can be fetched).</li>
|
||||||
|
<li>Then use either the <code>[fetch next batch]</code> or <code>[fetch all]</code> buttons to fetch the traces. Traces appear under <code>Traced specs</code> after that, and you can use the SLIME inspector to visualize their data (arguments and return values).</li>
|
||||||
|
<li>After more code that calls the traced functions is evaluated, repeat the process (go to step 4).</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p>But, that flow can get a bit tedious, because of the separation between updating the status of the traces and fetching them. Sometimes it is better to just fetch the traces without updating the status first. We can do that invoking the command <code>M-x slime-trace-dialog-fetch-traces</code> bound to <code>G</code>. So, instead of steps 4 and 5, just press <code>G</code> to update the user interface.</p>
|
||||||
|
|
||||||
|
<p>These are some of the Emacs commands bound to useful keys:</p>
|
||||||
|
|
||||||
|
<p><code>g</code>
|
||||||
|
<code>M-x slime-trace-dialog-fetch-status</code></p>
|
||||||
|
|
||||||
|
<pre><code>Update information on the trace collection and traced specs.
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p><code>G</code>
|
||||||
|
<code>M-x slime-trace-dialog-fetch-traces</code></p>
|
||||||
|
|
||||||
|
<pre><code>Fetch the next batch of outstanding (not fetched yet) traces. With a C-u prefix argument, repeat until no more outstanding traces.
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p><code>C-k</code>
|
||||||
|
<code>M-x slime-trace-dialog-clear-fetched-traces</code></p>
|
||||||
|
|
||||||
|
<pre><code>Prompt for confirmation, then clear all traces, both fetched and outstanding.
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Finally, the arguments and return values for each trace entry are interactive buttons. Clicking them opens the SLIME inspector on them. Invoking <code>M-RET</code> <code>M-x slime-trace-dialog-copy-down-to-repl</code> returns them to the REPL for manipulation . The number left of each entry indicates its absolute position in the calling order, which might differ from display order in case multiple threads call the same traced function.</p>
|
||||||
|
|
||||||
|
<p><code>M-x slime-trace-dialog-hide-details-mode</code> hides arguments and return values so you can concentrate on the calling logic. Additionally, <code>M-x slime-trace-dialog-autofollow-mode</code> will automatically display additional detail about an entry when the cursor moves over it.</p>
|
||||||
|
|
||||||
<h2 id="the-interactive-debugger">The interactive debugger</h2>
|
<h2 id="the-interactive-debugger">The interactive debugger</h2>
|
||||||
|
|
||||||
<p>Whenever an exceptional situation happens (see
|
<p>Whenever an exceptional situation happens (see
|
||||||
|
@ -486,7 +532,7 @@ With arguments:
|
||||||
[Condition of type SB-EXT:STEP-FORM-CONDITION]
|
[Condition of type SB-EXT:STEP-FORM-CONDITION]
|
||||||
|
|
||||||
Restarts:
|
Restarts:
|
||||||
0: [STEP-CONTINUE] Resume normal execution <---------- stepping actions
|
0: [STEP-CONTINUE] Resume normal execution <-------------------- stepping actions
|
||||||
1: [STEP-OUT] Resume stepping after returning from this function
|
1: [STEP-OUT] Resume stepping after returning from this function
|
||||||
2: [STEP-NEXT] Step over call
|
2: [STEP-NEXT] Step over call
|
||||||
3: [STEP-INTO] Step into call
|
3: [STEP-INTO] Step into call
|
||||||
|
@ -495,7 +541,7 @@ Restarts:
|
||||||
--more--
|
--more--
|
||||||
|
|
||||||
Backtrace:
|
Backtrace:
|
||||||
0: (FACTORIAL 3) <----------- press Enter to fold/unfold.
|
0: (FACTORIAL 3) <----------- press Enter to fold/unfold. Fix your code and press "r" to restart it.
|
||||||
Locals:
|
Locals:
|
||||||
N = 3 <----------- want to check? Move the point here and
|
N = 3 <----------- want to check? Move the point here and
|
||||||
press "e" to evaluate code on that frame.
|
press "e" to evaluate code on that frame.
|
||||||
|
@ -565,16 +611,25 @@ value.</li>
|
||||||
behaviour of a function a lot, it may be a sign that you need to
|
behaviour of a function a lot, it may be a sign that you need to
|
||||||
simplify it and divide it in smaller pieces.</p>
|
simplify it and divide it in smaller pieces.</p>
|
||||||
|
|
||||||
<p>And again, LispWorks has a graphical stepper.</p>
|
<p>And again, <strong>LispWorks</strong> has a <strong>graphical stepper</strong>.</p>
|
||||||
|
|
||||||
<h3 id="resume-a-program-execution-from-anywhere-in-the-stack">Resume a program execution from anywhere in the stack</h3>
|
<div class="info" style="background-color: #e7f3fe; border-left: 6px solid #2196F3; padding: 17px; margin-bottom: 1em;">
|
||||||
|
<!-- if inside a <p> then bootstrap adds 10px padding to the bottom -->
|
||||||
|
<strong>TIP:</strong> the <a href="https://github.com/mmontone/slime-breakpoints">slime-breakpoints</a> package adds stepping and breaking buttons to Slime too.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p><img src="https://raw.githubusercontent.com/mmontone/slime-star/master/screenshots/toolbars.png" alt="" /></p>
|
||||||
|
|
||||||
|
<h3 id="resume-a-program-execution-from-anywhere-in-the-stack-demo">Resume a program execution from anywhere in the stack (demo)</h3>
|
||||||
|
|
||||||
<p>In <a href="https://www.youtube.com/watch?v=jBBS4FeY7XM">this video</a> you will
|
<p>In <a href="https://www.youtube.com/watch?v=jBBS4FeY7XM">this video</a> you will
|
||||||
find a demo that shows the process explained above: how to fix a buggy
|
find a demo that shows the process explained above: how to fix a buggy
|
||||||
function and how to resume the program execution from anywhere in the
|
function and how to <strong>resume the program execution</strong> from anywhere in the
|
||||||
stack, without running everything from zero again. The video shows it
|
stack, without running everything from zero again. The video shows it
|
||||||
with Emacs and Slime, the Lem editor, both with SBCL.</p>
|
with Emacs and Slime, the Lem editor, both with SBCL.</p>
|
||||||
|
|
||||||
|
<p>They key point is to use <code>r</code> (<code>sldb-restart-frame</code>) on a stack frame to restart it.</p>
|
||||||
|
|
||||||
<!-- epub-exclude-start -->
|
<!-- epub-exclude-start -->
|
||||||
|
|
||||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/jBBS4FeY7XM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
|
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/jBBS4FeY7XM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
|
||||||
|
@ -605,7 +660,7 @@ re-compile a function at runtime and resume the program execution from
|
||||||
where it stopped (using the “step-continue” restart
|
where it stopped (using the “step-continue” restart
|
||||||
or using <code>r</code> (“restart frame”) on a given stackframe).</p>
|
or using <code>r</code> (“restart frame”) on a given stackframe).</p>
|
||||||
|
|
||||||
<p>See also the <a href="https://github.com/mmontone/slime-star">Slime-star</a> Emacs extension to set breakpoints without code annotations.</p>
|
<p>See also the <a href="https://github.com/mmontone/slime-star">Slime-star</a> Emacs extension mentioned above to set breakpoints without code annotations.</p>
|
||||||
|
|
||||||
<h2 id="advise-and-watch">Advise and watch</h2>
|
<h2 id="advise-and-watch">Advise and watch</h2>
|
||||||
|
|
||||||
|
@ -780,7 +835,7 @@ in 1999:</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="../index.html">The Common Lisp Cookbook</a> – A "defmodel" macro</h1>
|
<h1 id="title-non-xs"><a href="../index.html">The Common Lisp Cookbook</a> – A "defmodel" macro</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="../index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="../index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -133,7 +138,7 @@
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
551
lispcookbook.github.io/cl-cookbook/dynamic-libraries.html
Normal file
551
lispcookbook.github.io/cl-cookbook/dynamic-libraries.html
Normal file
|
@ -0,0 +1,551 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta name="generator" content=
|
||||||
|
"HTML Tidy for HTML5 for Linux version 5.2.0">
|
||||||
|
<title>Building Dynamic Libraries</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="description" content="A collection of examples of using Common Lisp">
|
||||||
|
<meta name="viewport" content=
|
||||||
|
"width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" href=
|
||||||
|
"assets/cl-logo-blue.png"/>
|
||||||
|
<link rel="stylesheet" href=
|
||||||
|
"assets/style.css">
|
||||||
|
<script type="text/javascript" src=
|
||||||
|
"assets/highlight-lisp.js">
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src=
|
||||||
|
"assets/jquery-3.2.1.min.js">
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src=
|
||||||
|
"assets/jquery.toc/jquery.toc.min.js">
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src=
|
||||||
|
"assets/toggle-toc.js">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href=
|
||||||
|
"assets/github.css">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 id="title-xs"><a href="index.html">The Common Lisp Cookbook</a> – Building Dynamic Libraries</h1>
|
||||||
|
<div id="logo-container">
|
||||||
|
<a href="index.html">
|
||||||
|
<img id="logo" src="assets/cl-logo-blue.png"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div id="searchform-container">
|
||||||
|
<form onsubmit="duckSearch()" action="javascript:void(0)">
|
||||||
|
<input id="searchField" type="text" value="" placeholder="Search...">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="toc-container" class="toc-close">
|
||||||
|
<div id="toc-title">Table of Contents</div>
|
||||||
|
<ul id="toc" class="list-unstyled"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content-container">
|
||||||
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Building Dynamic Libraries</h1>
|
||||||
|
|
||||||
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
|
<!-- <p class="announce"> -->
|
||||||
|
<!-- 📢 🤶 ⭐ -->
|
||||||
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
|
<!-- <strong> -->
|
||||||
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
|
<!-- </strong> -->
|
||||||
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="announce-neutral">
|
||||||
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="content"
|
||||||
|
<p>Although the vast majority of Common Lisp implementations have
|
||||||
|
some kind of <a href="ffi.html">foreign function interface</a> which allows you to
|
||||||
|
call functions from libraries which use C ABI, the other way around,
|
||||||
|
i.e. compiling your CL library as a library callable via C ABI from
|
||||||
|
other languages, might be rare.</p>
|
||||||
|
|
||||||
|
<p>Commercial implementations like LispWorks and Allegro CL usually
|
||||||
|
offer this functionality, and they are well documented <sup id="fnref:1" role="doc-noteref"><a href="dynamic-libraries.html#fn:1" class="footnote" rel="footnote">1</a></sup>.</p>
|
||||||
|
|
||||||
|
<p>This chapter describes a project called <a href="https://github.com/quil-lang/sbcl-librarian">SBCL-Librarian</a>,
|
||||||
|
an opinionated way to create libraries callable from C (anything which has C FFI) and Python using
|
||||||
|
the excellent open-source and free-to-use implementation <a href="https://www.sbcl.org">SBCL (Steel Bank Common Lisp)</a>.</p>
|
||||||
|
|
||||||
|
<p>SBCL-Librarian does support callbacks so you can integrate your Lisp library with any code,
|
||||||
|
including Python code which might use its great machine learning and statistical libraries.</p>
|
||||||
|
|
||||||
|
<p>The way SBCL-Librarian works is that it generates C source files, a C header and a Python module.</p>
|
||||||
|
|
||||||
|
<p>The C source file is compiled first into a dynamic library which is (using the provided header file)
|
||||||
|
loadable from any C project or by any project in a language which supports loading C libraries.</p>
|
||||||
|
|
||||||
|
<p>The generated Python module loads the compiled library into the Python process. This means that the C
|
||||||
|
library needs to be compiled before your Lisp library is used from Python code. This fact has two
|
||||||
|
main consequences:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>on one hand the Lisp library is all efficient native code, which is great. The Python interpreter can be quite slow and many libraries, especially the ones for machine learning
|
||||||
|
and statistics, are all compiled to native code. You can achieve the same efficiency with Common Lisp.</li>
|
||||||
|
<li>on the other hand, your library can only use the C interface to communicate with Python - primitive data
|
||||||
|
types from C, structures, functions and pointers (including pointers to functions). Some basic knowledge
|
||||||
|
of C is required.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="info" style="background-color: #e7f3fe; border-left: 6px solid #2196F3; padding: 17px;">
|
||||||
|
<!-- if inside a <p> then bootstrap adds 10px padding to the bottom -->
|
||||||
|
<strong>NOTE:</strong> The team behind SBCL-Librarian works on quantum computing in the industry. More precisely on a programming language for quantum computing called Quil, and its ecosystem.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 id="preparing-the-environment">Preparing the Environment</h2>
|
||||||
|
|
||||||
|
<h3 id="build-sbcl-with-shared-library-support">Build SBCL with Shared Library Support</h3>
|
||||||
|
|
||||||
|
<p>Binary distributions of SBCL usually do not come with SBCL built as a shared library, which is necessary for SBCL-Librarian.
|
||||||
|
You can download it either from the <a href="https://github.com/sbcl/sbcl">SBCL git repository</a>
|
||||||
|
or by <a href="getting-started.html#with-roswell">using Roswell</a> and running the command <code>ros install sbcl-source</code>.</p>
|
||||||
|
|
||||||
|
<p>SBCL also requires a working Common Lisp system to bootstrap the compilation process. An easy trick is to download a binary installation from Roswell and add it to your <code>PATH</code> variable.</p>
|
||||||
|
|
||||||
|
<p>SBCL depends on the <code>zstd</code> library. On Linux-based systems, you can obtain both the library and its header files from the package manager, where it is usually named <code>libzstd-dev</code>. On Windows, the recommended approach is to use
|
||||||
|
<a href="https://www.msys2.org">MSYS2</a> which includes Roswell, <code>zstd</code>, and its headers.</p>
|
||||||
|
|
||||||
|
<p>Navigate to the directory with the sources and run:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-bash"># Bash
|
||||||
|
|
||||||
|
# (assuming the version of your SBCL installed via Roswell is 2.4.1)
|
||||||
|
export PATH=~/.roswell/impls/x86-64/linux/sbcl-bin/2.4.1/bin/:$PATH
|
||||||
|
|
||||||
|
./make-config.sh --fancy
|
||||||
|
./make.sh --fancy
|
||||||
|
./make-shared-library.sh --fancy
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Note that the shared library has a <code>.so</code> extension even on Windows and Mac, but it seems to work just fine. If you use Roswell in MSYS2, it can use your Windows home directory rather than your MSYS2 home directory, which are different paths. Therefore, the path to Roswell might be <code>$USERPROFILE/.roswell</code> (or <code>/C/Users/<username>/.roswell</code>),
|
||||||
|
not <code>~/.roswell/</code>.</p>
|
||||||
|
|
||||||
|
<h3 id="download-and-setup-sbcl-librarian">Download and Setup SBCL-Librarian</h3>
|
||||||
|
|
||||||
|
<p>Clone the SBCL-Librarian repostiory:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-bash">git clone https://github.com/quil-lang/sbcl-librarian.git
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<h2 id="hello-world-from-lisp">Hello World from Lisp</h2>
|
||||||
|
|
||||||
|
<p>Although SBCL-Librarian comes with some documentation and a couple of examples, it doesn’t really have anything like a basic tutorial. In this chapter we’ll make a basic function which adds two numbers and we’ll call it from Python.</p>
|
||||||
|
|
||||||
|
<p>Let’s set a couple of environment variables for convenience:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-bash"># Directory with SBCL sources
|
||||||
|
export SBCL_SRC=~/.roswell/src/sbcl-2.4.1
|
||||||
|
# Directory with this project, don't forget the double slash at the end
|
||||||
|
# or it might not work
|
||||||
|
export CL_SOURCE_REGISTRY="~/prg/sbcl-librarian//"
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Libraries are usually not searched for in the current directory on more modern Linux-based systems. The paths which Python searches libraries on are usually not set to the current working directory either. Let’s set them this way for convenience.</p>
|
||||||
|
|
||||||
|
<pre><code class="language-bash">export LD_LIBRARY_PATH=.:
|
||||||
|
export PATH=.:$PATH
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Now we can create a file <code>helloworld.lisp</code> with the following content:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-lisp">(require '#:asdf)
|
||||||
|
(asdf:load-system :sbcl-librarian)
|
||||||
|
|
||||||
|
(defpackage libhelloworld
|
||||||
|
(:use :cl :sbcl-librarian))
|
||||||
|
|
||||||
|
(in-package libhelloworld)
|
||||||
|
|
||||||
|
;; will be called from Python
|
||||||
|
(defun hello-world (a b)
|
||||||
|
(+ a b))
|
||||||
|
|
||||||
|
|
||||||
|
;; error enum to be used in C/Python code for error handling
|
||||||
|
(define-enum-type error-type "err_t"
|
||||||
|
("ERR_SUCCESS" 0)
|
||||||
|
("ERR_FAIL" 1))
|
||||||
|
|
||||||
|
;; mapping Common Lisp conditions to C enums
|
||||||
|
;; in this simple example, all conditions are mapped to number 1
|
||||||
|
;; which is "ERR_FAIL" in `error-type` enum
|
||||||
|
(define-error-map error-map error-type 0
|
||||||
|
((t (lambda (condition)
|
||||||
|
(declare (ignore condition))
|
||||||
|
(return-from error-map 1)))))
|
||||||
|
|
||||||
|
;; structure of the generated C source file
|
||||||
|
(define-api libhelloworld-api (:error-map error-map ; error enum
|
||||||
|
:function-prefix "helloworld_") ; prefix for all function names (C doesn't have namespaces)
|
||||||
|
(:literal "/* types */") ; just a comment (whatever is there will be printed as-is)
|
||||||
|
(:type error-type) ; outputs the error enum
|
||||||
|
(:literal "/* functions */")
|
||||||
|
(:function ; function declaration - name, return type, argument types
|
||||||
|
(hello-world :int ((a :int) (b :int)))))
|
||||||
|
|
||||||
|
;; definition of the whole library - what is there
|
||||||
|
(define-aggregate-library libhelloworld (:function-linkage "LIBHELLOWORLD_API")
|
||||||
|
sbcl-librarian:handles sbcl-librarian:environment libhelloworld-api)
|
||||||
|
|
||||||
|
;; builds the bindings
|
||||||
|
(build-bindings libhelloworld ".")
|
||||||
|
(build-python-bindings libhelloworld ".")
|
||||||
|
|
||||||
|
;; outputs the Lisp core
|
||||||
|
(build-core-and-die libhelloworld "." :compression t)
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>The macro <code>define-enum-type</code> creates a mapping between conditions signaled by Common Lisp functions and a return type for the wrapping C functions. If a condition is signaled from Common Lisp, it is translated into a number — a C function return value — within <code>define-error-map</code>. The enumeration type adds a C <code>enum</code>, so instead of:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-C">if (1 == cl_function()) {
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>you can write:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-C">if (ERR_FAIL == cl_function()) {
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>which is more readable.</p>
|
||||||
|
|
||||||
|
<p><code>define-api</code> outlines the structure of the library code to be created, specifying the error map, types, functions, and their order (<code>:literal</code> is used for comments in this case).</p>
|
||||||
|
|
||||||
|
<p><code>define-aggregate-library</code> defines the entire library, specifying what should be included and in what order.</p>
|
||||||
|
|
||||||
|
<p>You can compile the file with the following commands:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-bash">$SBCL_SRC/run-sbcl.sh --script "helloworld.lisp"
|
||||||
|
cc -shared -fpic -o libhelloworld.so libhelloworld.c -L$SBCL_SRC/src/runtime -lsbcl
|
||||||
|
cp $SBCL_SRC/src/runtime/libsbcl.so .
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>You can run a Python console and check that the <code>helloworld</code> module was created successfully:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-python">import helloworld
|
||||||
|
|
||||||
|
dir(helloworld)
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>The function <code>helloworld_hello_world</code> should be present in the printed dictionary.</p>
|
||||||
|
|
||||||
|
<p>This function follows a C standard that the return value of the function is its error code
|
||||||
|
(0 is for success, other numbers should be defined in <code>err_t</code> class which follows the <code>error-map</code> definitions),
|
||||||
|
the last parameter of the function is its return value. Since this is a pointer to integer in this case,
|
||||||
|
an integer needs to be created using <code>ctypes</code> library and <code>helloworld_hello_world</code> has to be called with
|
||||||
|
a pointer to the result value.</p>
|
||||||
|
|
||||||
|
<p>The following program should print 11:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-python">import helloworld
|
||||||
|
import ctypes
|
||||||
|
|
||||||
|
rv = ctypes.c_int(0)
|
||||||
|
helloworld.helloworld_hello_world(5, 6, ctypes.pointer(rv))
|
||||||
|
print(rv.value)
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>There are two common problems which can occur, depending on your system.</p>
|
||||||
|
|
||||||
|
<p>First is a rather cryptic error from Python:</p>
|
||||||
|
|
||||||
|
<pre><code>>>> import helloworld
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
ImportError: dynamic module does not define module export function (PyInit_helloworld)
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>This means that Python tries to open <code>helloworld.so</code> as a Python module rather than <code>helloworld.py</code>. Since
|
||||||
|
<code>helloworld.so</code> is just an ordinary dynamic library and not a natively-compiled Python module, it
|
||||||
|
will not work.</p>
|
||||||
|
|
||||||
|
<pre><code class="language-bash">cp ./helloworld.py ./py_helloworld.py
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>and in Python <code>import py_helloworld</code>.</p>
|
||||||
|
|
||||||
|
<p>If you experience a following exception being raised:</p>
|
||||||
|
|
||||||
|
<pre><code>Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
raise Exception('Unable to locate libhelloworld') from e
|
||||||
|
Exception: Unable to locate libhelloworld
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>the first, check that all required dependencies - <code>libsbcl</code> and <code>libzstd</code> in this case - are either copied
|
||||||
|
to the output directory or are in the path which your operating system loads libraries from. If it still doesn’t
|
||||||
|
work, it might be a problem with the mechanism Python locates libraries on your particular system.</p>
|
||||||
|
|
||||||
|
<p>Open <code>helloworld.py</code> (or <code>py_helloworld.py</code> if you renamed it as suggested earlier) and change the line</p>
|
||||||
|
|
||||||
|
<pre><code class="language-Python">libpath = Path(find_library('libcallback')).resolve()
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>to a path for your operating system, e.g.</p>
|
||||||
|
|
||||||
|
<pre><code class="language-Python">libpath = Path('./libhelloworld.so').resolve()
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<h2 id="more-complex-example-callback-example">More Complex Example: Callback Example</h2>
|
||||||
|
|
||||||
|
<p>SBCL-Librarian includes several examples, one of which is a simple callback to Python code. This example comes with a <code>Makefile</code> and with a properly defined system using <code>asdf</code>.</p>
|
||||||
|
|
||||||
|
<h3 id="asdf-system-definition">ASDF system definition</h3>
|
||||||
|
|
||||||
|
<p>The system definition in <code>libcallback.asd</code> declares a dependency on SBCL-Librarian:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-lisp">(asdf:defsystem #:libcallback
|
||||||
|
:defsystem-depends-on (#:sbcl-librarian)
|
||||||
|
:depends-on (#:sbcl-librarian)
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>The ASDF system needs to know where to find the SBCL-Librarian sources. One way to specify this is by setting the <code>CL_SOURCE_REGISTRY</code> environment variable to include its directory, as seen above, or to clone the project in a location whene ASDF can find it (<code>~/common-lisp/</code>, <code>~/quicklisp/local-projects/</code>).</p>
|
||||||
|
|
||||||
|
<h3 id="bindingslisp">Bindings.lisp</h3>
|
||||||
|
|
||||||
|
<p><code>bindings.lisp</code> contains the crucial elements for generating the C bindings:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-lisp">(defun call-callback (callback outbuffer)
|
||||||
|
(sb-alien:with-alien ((str sb-alien:c-string "I guess "))
|
||||||
|
(sb-alien:alien-funcall callback str outbuffer)))
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>This function is key to the example; it is invoked from Python code and calls back a Python method (the<code>callback</code> parameter). As SBCL-Librarian generates both a C library and a Python module that wraps it, this function can be called from either C or Python. This example focuses on Python.</p>
|
||||||
|
|
||||||
|
<p>SBCL-Librarian utilizes <code>sb-alien</code>, an SBCL package for interfacing with C functions. <code>with-alien</code> creates a resource (here it is <code>str</code> of type <code>c-string</code>) that is valid within its scope and is automatically disposed of afterward, preventing memory leaks. <code>alien-funcall</code> is used to call a C function, in this case <code>callback</code>, with a newly created string and a string buffer passed in as arguments.</p>
|
||||||
|
|
||||||
|
<pre><code class="language-lisp">(sbcl-librarian::define-type :callback
|
||||||
|
:c-type "void*"
|
||||||
|
:alien-type (sb-alien:* (sb-alien:function sb-alien:void sb-alien:c-string (sb-alien:* sb-alien:char)))
|
||||||
|
:python-type "c_void_p")
|
||||||
|
|
||||||
|
(sbcl-librarian::define-type :char-buffer
|
||||||
|
:c-type "char*"
|
||||||
|
:alien-type (sb-alien:* sb-alien:char)
|
||||||
|
:python-type "c_char_p")
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>This section defines the types <code>callback</code> and <code>char-buffer</code> in C, Python, and Common Lisp. The C and Python types for both are <code>void*</code> and <code>char*</code>, respectively. The Common Lisp type for callback specifies a function prototype: a pointer to a function that returns <code>void</code> and takes two parameters, a <code>c-string</code> and a pointer to a <code>char</code>. The <code>sb-alien:*</code> indicates a pointer, so <code>:callback</code> is a pointer to a function. The <code>:char-buffer</code> type represents a <code>char*</code> in all three languages.</p>
|
||||||
|
|
||||||
|
<p>The rest of this file is similar to what was described in the <code>Hello World</code> section.</p>
|
||||||
|
|
||||||
|
<h3 id="compile-lisp-code">Compile LISP Code</h3>
|
||||||
|
|
||||||
|
<p><code>script.lisp</code> is a straightforward Lisp script for compiling the Lisp sources and outputting the wrapper code and the Lisp core.</p>
|
||||||
|
|
||||||
|
<pre><code class="language-lisp">(require '#:asdf)
|
||||||
|
|
||||||
|
(asdf:load-system '#:libcallback)
|
||||||
|
|
||||||
|
(in-package #:sbcl-librarian/example/libcallback)
|
||||||
|
|
||||||
|
(build-bindings libcallback ".")
|
||||||
|
(build-python-bindings libcallback ".")
|
||||||
|
(build-core-and-die libcallback "." :compression t)
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Now you have a couple of new files.</p>
|
||||||
|
|
||||||
|
<p><code>libcallback.c</code> is the source code for the library:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-c">#define CALLBACKING_API_BUILD
|
||||||
|
|
||||||
|
#include "libcallback.h"
|
||||||
|
|
||||||
|
void (*lisp_release_handle)(void* handle);
|
||||||
|
int (*lisp_handle_eq)(void* a, void* b);
|
||||||
|
void (*lisp_enable_debugger)();
|
||||||
|
void (*lisp_disable_debugger)();
|
||||||
|
void (*lisp_gc)();
|
||||||
|
err_t (*callback_call_callback)(void* fn, char* out_buffer);
|
||||||
|
|
||||||
|
extern int initialize_lisp(int argc, char **argv);
|
||||||
|
|
||||||
|
CALLBACKING_API int init(char* core) {
|
||||||
|
static int initialized = 0;
|
||||||
|
char *init_args[] = {"", "--core", core, "--noinform", };
|
||||||
|
if (initialized) return 1;
|
||||||
|
if (initialize_lisp(4, init_args) != 0) return -1;
|
||||||
|
initialized = 1;
|
||||||
|
return 0; }
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>At the top, you’ll find several SBCL-related functions, such as <code>lisp_gc</code>, which signals to the Lisp garbage collector that it is a good time to run. Then there is a pointer to the <code>callback_call_callback</code> function. Finally, the <code>init</code> function, which should be run before executing any Lisp code.</p>
|
||||||
|
|
||||||
|
<p>SBCL (as of version 2.4.2) didn’t support de-initialize the Lisp core so there are no functions for doing so.</p>
|
||||||
|
|
||||||
|
<p><code>libcallback.h </code> is a header file that should be included in both <code>lispcallback.c</code> and any calling C code. It contains prototypes of functions and function pointers in <code>lispcallback.c</code>, includes the error <code>enum</code>, and any comments added in <code>bindings.lisp</code>:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-C">typedef enum { ERR_SUCCESS = 0, ERR_FAIL = 1, } err_t;
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>The last file, <code>lispcallback.py</code>, is a Python wrapper around the library. The most notable part is this:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-Python">from ctypes import *
|
||||||
|
from ctypes.util import find_library
|
||||||
|
|
||||||
|
try:
|
||||||
|
libpath = Path(find_library('libcallback')).resolve()
|
||||||
|
except TypeError as e:
|
||||||
|
raise Exception('Unable to locate libcallback') from e
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>The rest of the file is similar to the C header file.</p>
|
||||||
|
|
||||||
|
<p>This setup loads a compiled C library (shared object, DLL, dylib) and informs the Python interpreter about the functions and types included in the library. It also initializes the Lisp core when loaded by the Python interpreter. The initialization needs to be called manually when the generated library is called from C.</p>
|
||||||
|
|
||||||
|
<h3 id="compile-c-code">Compile C Code</h3>
|
||||||
|
|
||||||
|
<pre><code class="language-bash">cc -shared -fpic -o libcallback.so libcallback.c -L$SBCL_SRC/src/runtime -lsbcl
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>On Mac OS the command might be a bit different:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-bash">cc -dynamiclib -o libcallback.dylib libcallback.c -L$SBCL_SRC/src/runtime -lsbcl
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>If you do not have <code>$SBCL_SRC/src/runtime</code> in your <code>$PATH</code>, you should copy the <code>$SBCL_SRC/src/runtime/libsbcl.so</code> file to the current directory.</p>
|
||||||
|
|
||||||
|
<h3 id="run">Run</h3>
|
||||||
|
|
||||||
|
<p>Now that everything is set up, you can run the example code using the following command:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-bash">$ python3 ./example.py
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>If it’s successful, you should see the output:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-bash">I guess it works!
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<h2 id="makefile">Makefile</h2>
|
||||||
|
|
||||||
|
<p>Each example comes with a Makefile designed for building on Mac. It even automatically builds the <code>libsbcl.so</code> library and copies it into the current directory. However, the command for building the project (e.g., <code>libcallback</code>) needs to be modified to work on Linux-based operating systems and on Windows (with MSYS2).</p>
|
||||||
|
|
||||||
|
<h2 id="cmake">CMake</h2>
|
||||||
|
|
||||||
|
<p>Using CMake is relatively straightforward. Unfortunately, there is currently no CMake-aware library or a <code>vcpkg</code>/<code>conan</code> package, so you’ll need to use <code>HINTS</code> with <code>find_library</code> to locate the necessary libraries.</p>
|
||||||
|
|
||||||
|
<p>Assuming you would like to compile a project named <code>my_project</code> and would like to add a LISP library, you could proceed as follows:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-CMake"># If there is a better way, let me know.
|
||||||
|
if(WIN32)
|
||||||
|
set(DIR_SEPARATOR ";")
|
||||||
|
else()
|
||||||
|
set(DIR_SEPARATOR ":")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set the ENV Vars for building the LISP part
|
||||||
|
set(SBCL_SRC "$ENV{SBCL_SRC}" CACHE PATH "Path to SBCL sources directory.")
|
||||||
|
set(SBCL_LIBRARIAN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../sbcl-librarian" CACHE PATH "Source codes of SBCL-LIBRARIAN project.")
|
||||||
|
set(CL_SOURCE_REGISTRY "${CMAKE_CURRENT_SOURCE_DIR}${DIR_SEPARATOR}${SBCL_LIBRARIAN_DIR}" CACHE PATH "ASDF registry for building of the libray.")
|
||||||
|
|
||||||
|
# Find the SBCL library
|
||||||
|
find_library(libsbcl NAMES sbcl HINTS ${SBCL_SRC}/src/runtime/)
|
||||||
|
|
||||||
|
# Link the library to the C project
|
||||||
|
target_link_libraries(my_project ${libsbcl})
|
||||||
|
|
||||||
|
# Build LISP part of the project
|
||||||
|
add_custom_command(OUTPUT my_project-lisp.core my_project-lisp.c my_project-lisp.h my_project-lisp.py
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E env CL_SOURCE_REGISTRY="${CL_SOURCE_REGISTRY}"
|
||||||
|
${SBCL_SRC}/run-sbcl.sh ARGS --script script.lisp
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different my_project-lisp.core $<TARGET_FILE_DIR:my_project>
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different my_project-lisp.c $<TARGET_FILE_DIR:my_project>
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different my_project-lisp.h $<TARGET_FILE_DIR:my_project>
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different my_project-lisp.py $<TARGET_FILE_DIR:my_project>
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E rm my_project-lisp.core my_project-lisp.c my_project-lisp.h my_project-lisp.py
|
||||||
|
|
||||||
|
# Copy SBCL library if newer
|
||||||
|
add_custom_command(TARGET my_project POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
"${libsbcl}"
|
||||||
|
$<TARGET_FILE_DIR:my_project>)
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>This concludes our tutorial on getting started with SBCL-librarian. We hope it expands your imagination in what you can build with Common Lisp and that it put you in the right tracks.</p>
|
||||||
|
|
||||||
|
<div class="footnotes" role="doc-endnotes">
|
||||||
|
<ol>
|
||||||
|
<li id="fn:1" role="doc-endnote">
|
||||||
|
<p><a href="https://www.lispworks.com/documentation/lw70/DV/html/delivery-20.htm">on LispWorks</a>, <a href="https://www.lispworks.com/documentation/lw80/lw/lw-lw-ji-88.htm">on LispWorks for Java</a>, <a href="https://franz.com/support/documentation/10.1/doc/dll.htm">on AllegroCL</a>. <a href="dynamic-libraries.html#fnref:1" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="page-source">
|
||||||
|
Page source: <a href="https://github.com/LispCookbook/cl-cookbook/blob/master/dynamic-libraries.md">dynamic-libraries.md</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
// Don't write the TOC on the index.
|
||||||
|
if (window.location.pathname != "/cl-cookbook/") {
|
||||||
|
$("#toc").toc({
|
||||||
|
content: "#content", // will ignore the first h1 with the site+page title.
|
||||||
|
headings: "h1,h2,h3,h4"});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#two-cols + ul").css({
|
||||||
|
"column-count": "2",
|
||||||
|
});
|
||||||
|
$("#contributors + ul").css({
|
||||||
|
"column-count": "4",
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<footer class="footer">
|
||||||
|
<hr/>
|
||||||
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
|
<div>
|
||||||
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="toc-btn">T<br>O<br>C</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script text="javascript">
|
||||||
|
HighlightLisp.highlight_auto({className: null});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function duckSearch() {
|
||||||
|
var searchField = document.getElementById("searchField");
|
||||||
|
if (searchField && searchField.value) {
|
||||||
|
var query = escape("site:lispcookbook.github.io/cl-cookbook/ " + searchField.value);
|
||||||
|
window.location.href = "https://duckduckgo.com/?kj=b2&kf=-1&ko=1&q=" + query;
|
||||||
|
// https://duckduckgo.com/params
|
||||||
|
// kj=b2: blue header in results page
|
||||||
|
// kf=-1: no favicons
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script async defer data-domain="lispcookbook.github.io/cl-cookbook" src="https://plausible.io/js/plausible.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Editor support</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Editor support</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -82,32 +87,6 @@ Quicklisp, SLIME and Git.</p>
|
||||||
|
|
||||||
<p><img src="assets/portacle.png" style="width: 800px" alt="Portacle with an open Slime REPL" /></p>
|
<p><img src="assets/portacle.png" style="width: 800px" alt="Portacle with an open Slime REPL" /></p>
|
||||||
|
|
||||||
<h3 id="installing-slime">Installing SLIME</h3>
|
|
||||||
|
|
||||||
<p>SLIME is in the official GNU ELPA repository of Emacs Lisp packages
|
|
||||||
(in Emacs24 and forward). Install with:</p>
|
|
||||||
|
|
||||||
<pre><code>M-x package-install RET slime RET
|
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
<p>Since SLIME is heavily modular and the defaults only do the bare minimum (not
|
|
||||||
even the SLIME REPL), you might want to enable more features with</p>
|
|
||||||
|
|
||||||
<pre><code class="language-lisp">(slime-setup '(slime-fancy slime-quicklisp slime-asdf))
|
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
<p>For more details, consult the
|
|
||||||
<a href="https://common-lisp.net/project/slime/doc/html/">documentation</a> (also available
|
|
||||||
as an Info page).</p>
|
|
||||||
|
|
||||||
<p>Now you can run SLIME with <code>M-x slime</code> and/or <code>M-x slime-connect</code>.</p>
|
|
||||||
|
|
||||||
<p>See also:</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://wikemacs.org/wiki/SLIME">https://wikemacs.org/wiki/SLIME</a> - configuration examples and extensions.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3 id="using-emacs-as-an-ide">Using Emacs as an IDE</h3>
|
<h3 id="using-emacs-as-an-ide">Using Emacs as an IDE</h3>
|
||||||
|
|
||||||
<p>See <a href="emacs-ide.html">“Using Emacs as an IDE”</a>.</p>
|
<p>See <a href="emacs-ide.html">“Using Emacs as an IDE”</a>.</p>
|
||||||
|
@ -275,6 +254,16 @@ Python, Go, Rust, JS, Nim, Scheme, HTML, CSS, plus a directory mode, a <strong>v
|
||||||
<pre><code>alias ilem='lem --eval "(lem-lisp-mode:start-lisp-repl t)"'
|
<pre><code>alias ilem='lem --eval "(lem-lisp-mode:start-lisp-repl t)"'
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
|
<p>There is more:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>🚀 <a href="https://www.youtube.com/watch?v=IMN7feOQOak">Lem on the cloud</a> (video presentation) Rooms is a product that runs Lem, a text editor created in Common Lisp, in the Cloud and can be used by multiple users.
|
||||||
|
<ul>
|
||||||
|
<li>Lem on the cloud is NEW as of April, 2024. In private beta at the time of writing.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<p><img src="assets/lem1.png" style="width: 800px" title="Lem's REPL" alt="Lem running in the terminal with the Lisp REPL full screen, showing a completion window." /></p>
|
<p><img src="assets/lem1.png" style="width: 800px" title="Lem's REPL" alt="Lem running in the terminal with the Lisp REPL full screen, showing a completion window." /></p>
|
||||||
|
|
||||||
<h2 id="sublime-text">Sublime Text</h2>
|
<h2 id="sublime-text">Sublime Text</h2>
|
||||||
|
@ -370,7 +359,7 @@ free versions of other Lisp vendors, such as Allegro CL.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Error and exception handling</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Error and exception handling</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -657,7 +662,7 @@ anything), but our message is printed afterwards anyway.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,125 +53,95 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Foreign Function Interfaces</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Foreign Function Interfaces</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<div id="content"
|
<div id="content"
|
||||||
<p>The ANSI Common Lisp standard doesn’t mention this topic. So almost everything that can be said here depends on your OS and your implementation.</p>
|
<p>The ANSI Common Lisp standard doesn’t mention this topic. So almost everything that can be said here depends on your OS and your implementation. However these days, we can use the <a href="https://github.com/cffi/cffi">CFFI</a> library, a portable and easy-to-use C foreign function interface.</p>
|
||||||
|
|
||||||
<p><a name="clisp-gethost"></a></p>
|
<blockquote>
|
||||||
|
<p>CFFI, the Common Foreign Function Interface, purports to be a portable FFI for Common Lisp. It abstracts away the differences between the API of the native FFI’s of the various Common Lisp implementations.</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
<h3 id="example-calling-gethostname-from-clisp">Example: Calling ‘gethostname’ from CLISP</h3>
|
<p>We’ll see an example right now.</p>
|
||||||
|
|
||||||
<p>Note: You should read the <a href="http://clisp.sourceforge.net/impnotes.html#dffi">relevant chapter</a> from the CLISP implementation notes before you proceed.</p>
|
<h2 id="cffi-calling-a-c-function-from-the-mathh-header-file">CFFI: calling a C function from the <code>math.h</code> header file.</h2>
|
||||||
|
|
||||||
<p><code>int gethostname(char *name, int len)</code> follows a typical pattern of C “out”-parameter convention - it expects a pointer to a buffer it’s going to fill. So you must view this parameter as either <code>:OUT</code> or <code>:IN-OUT</code>. Additionally, one must tell the function the size of the buffer. Here <code>len</code> is just an <code>:IN</code> parameter. Sometimes this will be an <code>:IN-OUT</code> parameter, returning the number of bytes actually filled in.</p>
|
<p>Let’s use <code>defcfun</code> to interface with the foreign <a href="https://en.cppreference.com/w/c/numeric/math/ceil">ceil</a> C function from <code>math.h</code>.</p>
|
||||||
|
|
||||||
<p>So <code>name</code> is actually a pointer to an array of up to <code>len</code> characters, regardless of what the poor “<code>char *</code>” C prototype says, to be used like a C string (0-termination). How many elements are in the array? Luckily, in our case, you can find it out without calculating the <code>sizeof()</code> a C structure. It’s a hostname that will be returned. The Solaris 2.x manpage says “Host names are limited to MAXHOSTNAMELEN characters, currently 256.”</p>
|
<p><a href="https://cffi.common-lisp.dev/manual/html_node/defcfun.html">defcfun</a> is a macro in the cffi library that generates a function with the name you give it.</p>
|
||||||
|
|
||||||
<p>Also, in the present example, you can use allocation <code>:ALLOCA</code>, like you’d do in C: stack-allocate a temporary. Why make things worse when using Lisp than when using C?</p>
|
<pre><code class="language-lisp">CL-USER> (cffi:defcfund ("ceil" c-ceil) :double (number :double))
|
||||||
|
|
||||||
<p>This yields the following useful signature for your foreign function:</p>
|
|
||||||
|
|
||||||
<pre><code class="language-lisp">(ffi:def-c-call-out gethostname
|
|
||||||
(:arguments (name (ffi:c-ptr (ffi:c-array-max ffi:char 256))
|
|
||||||
:out :alloca)
|
|
||||||
(len ffi:int))
|
|
||||||
;; (:return-type BOOLEAN) could have been used here
|
|
||||||
;; (Solaris says it's either 0 or -1).
|
|
||||||
(:return-type ffi:int))
|
|
||||||
|
|
||||||
(defun myhostname ()
|
|
||||||
(multiple-value-bind (success name)
|
|
||||||
;; :OUT or :IN-OUT parameters are returned via multiple values
|
|
||||||
(gethostname 256)
|
|
||||||
(if (zerop success)
|
|
||||||
(subseq name 0 (position #\null name))
|
|
||||||
(error ... ; errno may be set
|
|
||||||
...))))
|
|
||||||
(defvar hostname (myhostname))
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Possibly <code>SUBSEQ</code> and <code>POSITION</code> are superfluous, thanks to <code>C-ARRAY-MAX</code> as opposed to <code>C-ARRAY</code>:</p>
|
<p>We say that the “ceil” C function will be called “c-ceil” on our Lisp side, it takes one argument that is a double float, and it returns a number that is also a double float.</p>
|
||||||
|
|
||||||
<pre><code class="language-lisp">(defun myhostname ()
|
<p>Here is the above function macroexpanded with <code>macrostep-expand</code>:</p>
|
||||||
(multiple-value-bind (success name)
|
|
||||||
;; :out or :in-out parameters are returned via multiple values
|
<pre><code class="language-lisp">(progn
|
||||||
(gethostname 256)
|
nil
|
||||||
(if (zerop success) name
|
(defun c-ceil (number)
|
||||||
(error ... ; errno may be set
|
(let ((#:g312 number))
|
||||||
...))))
|
(cffi-sys:%foreign-funcall "ceil" (:double #:g312 :double) :convention
|
||||||
|
:cdecl :library :default))))
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p><a name="alisp-gethost"></a></p>
|
<p>The reason we called it <code>c-ceil</code> and not <code>ceil</code> is only for the example, so we know this is a wrapper around C. You can name it “ceil”, since it doesn’t designate a built-in Common Lisp function or macro.</p>
|
||||||
|
|
||||||
<h3 id="example-calling-gethostname-from-allegro-cl">Example: Calling ‘gethostname’ from Allegro CL</h3>
|
<p>Now that we have a c-ceil function from <code>math.h</code>, let’s use it! We must give it double float.</p>
|
||||||
|
|
||||||
<p>This is how the same example above would be written in Allegro Common Lisp version 6 and above. ACL doesn’t explicitly distinguish between <code>input</code> and <code>output</code> arguments. The way to declare an argument as <code>output</code> (i.e., modifiable by C) is to use an array, since arrays are passed by reference and C therefore receives a pointer to a memory location (which is what it expects). In this case things are made even easier by the fact that <code>gethostname()</code> expects an array of char, and a <code>SIMPLE-ARRAY</code> of <code>CHARACTER</code> represents essentially the same thing in Lisp. The foreign function definition is therefore the following:</p>
|
<pre><code class="language-lisp">CL-USER> (c-ceil 5.4d0)
|
||||||
|
6.0d0
|
||||||
<pre><code class="language-lisp">(def-foreign-call (c-get-hostname "gethostname")
|
|
||||||
((name (* :char) (simple-array 'character (*)))
|
|
||||||
(len :int integer))
|
|
||||||
:returning :int)
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Let’s read this line by line: this form defines a Lisp function called <code>C-GET-HOSTNAME</code> that calls the C function <code>gethostname()</code>. It takes two arguments: the first one, called <code>NAME</code>, is a pointer to a char (<code>*char</code> in C), and a <code>SIMPLE-ARRAY</code> of characters in Lisp; the second one is called <code>LEN</code>, and is an integer. The function returns an integer value.</p>
|
<p>As you can see, it works! The double gets rounded up to <code>6.0d0</code> as expected.</p>
|
||||||
|
|
||||||
<p>And now the Lisp side:</p>
|
<p>Let’s try another one! This time, we’ll use <a href="https://en.cppreference.com/w/c/numeric/math/floor">floor</a>, and we couldn’t name it “floor” because this Common Lisp function exists.</p>
|
||||||
|
|
||||||
<pre><code class="language-lisp">(defun get-hostname ()
|
<pre><code class="language-lisp">CL-USER> (cffi:defcfun ("floor" c-floor) :double (number :double))
|
||||||
(let* ((name (make-array 256 :element-type 'character))
|
C-FLOOR
|
||||||
(result (c-get-hostname name 256)))
|
CL-USER> (c-floor 5d0)
|
||||||
(if (zerop result)
|
5.0d0
|
||||||
(let ((pos (position #\null name)))
|
CL-USER> (c-floor 5.4d0)
|
||||||
(subseq name 0 pos))
|
5.0d0
|
||||||
(error "gethostname() failed."))))
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>This function creates the <code>NAME</code> array, calls <code>C-GET-HOSTNAME</code> to fill it and then checks the returned value. If the value is zero, then the call was successful, and we return the contents of <code>NAME</code> up to the first 0 character (the string terminator in C), otherwise we signal an error. Note that, unlike the previous example, we allocate the string in Lisp, and we rely on the Lisp garbage collector to get rid of it after the function terminates. Here is a usage example:</p>
|
<p>Great!</p>
|
||||||
|
|
||||||
<pre><code class="language-lisp">* (get-hostname)
|
<p>One more, let’s try <code>sqrt</code> from math.h, still with double floats:</p>
|
||||||
"terminus"
|
|
||||||
|
<pre><code class="language-lisp">CL-USER> (cffi:defcfun ("sqrt" c-sqrt) :double (number :double))
|
||||||
|
C-SQRT
|
||||||
|
CL-USER> (c-sqrt 36.50d0)
|
||||||
|
6.041522986797286d0
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Working with strings is, in general, easier than the previous example showed. Let’s say you want to call <code>getenv()</code> from Lisp to access the value of an environment variable. <code>getenv()</code> takes a string argument (the variable name) and returns another string (the variable value). To be more precise, the argument is a <em>pointer</em> to a sequence of characters that should have been allocated by the caller, and the return value is a pointer to an already-existing sequence of chars (in the environment). Here is the definition of <code>C-GETENV</code>:</p>
|
<p>We can do arithmetic with our new <code>c-sqrt</code>:</p>
|
||||||
|
|
||||||
<pre><code class="language-lisp">(def-foreign-call (c-getenv "getenv")
|
<pre><code class="language-lisp">CL-USER> (+ 2 (c-sqrt 3d0))
|
||||||
((var (* :char) string))
|
3.732050807568877d0
|
||||||
:returning :int
|
|
||||||
:strings-convert t)
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>The argument in this case is still a pointer to char in C, but we can declare it a <code>STRING</code> to Lisp. The return value is a pointer, so we declare it as integer. Finally, the <code>:STRINGS-CONVERT</code> keyword argument specifies that ACL should automatically translate the Lisp string passed as the first argument into a C string. Here is how it’s used:</p>
|
<p>We can even use our new shiny <code>c-sqrt</code> to map over a list of doubles and take the square root of all of them!</p>
|
||||||
|
|
||||||
<pre><code class="language-lisp">* (c-getenv "SHELL")
|
<pre><code class="language-lisp">CL-USER> (mapcar #'c-sqrt '(3d0 4d0 5d0 6d0 7.5d0 12.75d0))
|
||||||
-1073742215
|
(1.7320508075688772d0 2.0d0 2.23606797749979d0 2.449489742783178d0
|
||||||
</code></pre>
|
2.7386127875258306d0 3.570714214271425d0)
|
||||||
|
|
||||||
<p>If you are surprised by the return value, just remember that <code>C-GETENV</code> returns a pointer, and we must tell Lisp how to interpret the contents of the memory location pointed to by it. Since in this case we know that it will point to a C string, we can use the <code>FF:NATIVE-TO-STRING</code> function to convert it to a Lisp string:</p>
|
|
||||||
|
|
||||||
<pre><code class="language-lisp">* (native-to-string (c-getenv "SHELL"))
|
|
||||||
"/bin/tcsh"
|
|
||||||
9
|
|
||||||
9
|
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
<p>(The second and third values are the number of characters and bytes copied, respectively). One caveat: if you ask for the value of a non-existent variable, <code>C-GETENV</code> will return 0, and <code>NATIVE-TO-STRING</code> will fail. So a safer example would be:</p>
|
|
||||||
|
|
||||||
<pre><code class="language-lisp">* (let ((ptr (c-getenv "NOSUCHVAR")))
|
|
||||||
(unless (zerop ptr)
|
|
||||||
(native-to-string ptr)))
|
|
||||||
NIL
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,7 +174,7 @@
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Files and Directories</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Files and Directories</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -872,7 +877,7 @@ operations.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Functions</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Functions</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -761,7 +766,7 @@ library (in Quicklisp).</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,23 +53,28 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Getting started with Common Lisp</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Getting started with Common Lisp</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<div id="content"
|
<div id="content"
|
||||||
<p>We’ll begin with presenting easy steps to install a development environment and to start a new Common Lisp project.</p>
|
<p>We’ll begin by presenting easy steps to install a development environment and to start a new Common Lisp project.</p>
|
||||||
|
|
||||||
<p>Want a 2-clicks install? Then get
|
<p>Want a 2-click install? Then get
|
||||||
<a href="https://shinmera.github.io/portacle/">Portacle</a>, <em>a portable and
|
<a href="https://shinmera.github.io/portacle/">Portacle</a>, <em>a portable and
|
||||||
multi-platform</em> Common Lisp environment. It ships Emacs, SBCL (the
|
multi-platform</em> Common Lisp environment. It ships Emacs, SBCL (the
|
||||||
implementation), Quicklisp (package manager), SLIME (IDE) and
|
implementation), Quicklisp (package manager), SLIME (IDE) and
|
||||||
|
@ -84,9 +89,9 @@ Git. It’s the most straightforward way to get going!</p>
|
||||||
<pre><code>apt-get install sbcl
|
<pre><code>apt-get install sbcl
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Common Lisp has been standardized via an ANSI document, so it can be
|
<p>Common Lisp is an ANSI standard but implementations can vary greatly in what
|
||||||
implemented in different ways. See
|
they provide in addition to the standard. See <a href="https://en.wikipedia.org/wiki/Common_Lisp#Implementations">Wikipedia’s list of
|
||||||
<a href="https://en.wikipedia.org/wiki/Common_Lisp#Implementations">Wikipedia’s list of implementations</a>.</p>
|
implementations</a>.</p>
|
||||||
|
|
||||||
<p>The following implementations are packaged for Debian and most other popular Linux distributions:</p>
|
<p>The following implementations are packaged for Debian and most other popular Linux distributions:</p>
|
||||||
|
|
||||||
|
@ -100,7 +105,7 @@ implemented in different ways. See
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://abcl.org/">ABCL</a>, to interface with the JVM,</li>
|
<li><a href="http://abcl.org/">ABCL</a>, to interface with the JVM,</li>
|
||||||
<li><a href="https://ccl.clozure.com/">ClozureCL</a>, a good implementation with very fast build times (see this <a href="http://mr.gy/blog/clozure-cl-deb.html">Debian package for Clozure CL</a>),</li>
|
<li><a href="https://ccl.clozure.com/">ClozureCL</a>, a good implementation with very fast build times,</li>
|
||||||
<li><a href="https://github.com/drmeister/clasp">CLASP</a>, that interoperates with C++ libraries using LLVM for compilation to native code,</li>
|
<li><a href="https://github.com/drmeister/clasp">CLASP</a>, that interoperates with C++ libraries using LLVM for compilation to native code,</li>
|
||||||
<li><a href="https://franz.com/products/allegrocl/">AllegroCL</a> (proprietary)</li>
|
<li><a href="https://franz.com/products/allegrocl/">AllegroCL</a> (proprietary)</li>
|
||||||
<li><a href="http://www.lispworks.com/">LispWorks</a> (proprietary)</li>
|
<li><a href="http://www.lispworks.com/">LispWorks</a> (proprietary)</li>
|
||||||
|
@ -386,7 +391,7 @@ Debian. The package names usually begin with the cl- prefix (use
|
||||||
|
|
||||||
<h3 id="advanced-dependencies-management">Advanced dependencies management</h3>
|
<h3 id="advanced-dependencies-management">Advanced dependencies management</h3>
|
||||||
|
|
||||||
<p>You can drop Common Lisp projects into any of those folders:</p>
|
<p>You can drop Common Lisp projects into any of these folders:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>~/quicklisp/local-projects</code></li>
|
<li><code>~/quicklisp/local-projects</code></li>
|
||||||
|
@ -420,10 +425,10 @@ available right-away:</p>
|
||||||
<pre><code class="language-lisp">(ql:quickload "system")
|
<pre><code class="language-lisp">(ql:quickload "system")
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>The practical different between the two is that <code>ql:quickload</code> first tries to
|
<p>The practical difference between the two is that <code>ql:quickload</code> first tries to
|
||||||
fetch the system from the Internet if it is not already installed.</p>
|
fetch the system from the Internet if it is not already installed.</p>
|
||||||
|
|
||||||
<p>Note that symlinks in local-projects to another location of your liking works too.</p>
|
<p>Note that symlinks in local-projects to another location of your liking work too.</p>
|
||||||
|
|
||||||
<h4 id="how-to-work-with-local-versions-of-libraries">How to work with local versions of libraries</h4>
|
<h4 id="how-to-work-with-local-versions-of-libraries">How to work with local versions of libraries</h4>
|
||||||
|
|
||||||
|
@ -445,15 +450,15 @@ to help us build <em>dists</em>.</p>
|
||||||
<p>Now that we have Quicklisp and our editor ready, we can start writing
|
<p>Now that we have Quicklisp and our editor ready, we can start writing
|
||||||
Lisp code in a file and interacting with the REPL.</p>
|
Lisp code in a file and interacting with the REPL.</p>
|
||||||
|
|
||||||
<p>But what if we want to work with an existing project or create a new
|
<p>But if we want to work with an existing project or create a new
|
||||||
one, how do we proceed, what’s the right sequence of <code>defpackage</code>,
|
one, how do we proceed? What’s the right sequence of <code>defpackage</code>?
|
||||||
what to put in the <code>.asd</code> file, how to load the project into the REPL ?</p>
|
What should we put in the <code>.asd</code> file? How do we load the project into the REPL ?</p>
|
||||||
|
|
||||||
<h3 id="creating-a-new-project">Creating a new project</h3>
|
<h3 id="creating-a-new-project">Creating a new project</h3>
|
||||||
|
|
||||||
<p>Some project builders help to scaffold the project structure. We like
|
<p>Some project builders help to scaffold the project structure. We like
|
||||||
<a href="https://github.com/fukamachi/cl-project">cl-project</a> that also sets
|
<a href="https://github.com/fukamachi/cl-project">cl-project</a>, which also sets
|
||||||
up a tests skeleton.</p>
|
up a test skeleton.</p>
|
||||||
|
|
||||||
<p>In short:</p>
|
<p>In short:</p>
|
||||||
|
|
||||||
|
@ -461,7 +466,7 @@ up a tests skeleton.</p>
|
||||||
(cl-project:make-project #P"./path-to-project/root/")
|
(cl-project:make-project #P"./path-to-project/root/")
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>it will create a directory structure like this:</p>
|
<p>will create a directory structure like this:</p>
|
||||||
|
|
||||||
<pre><code>|-- my-project.asd
|
<pre><code>|-- my-project.asd
|
||||||
|-- my-project-test.asd
|
|-- my-project-test.asd
|
||||||
|
@ -473,7 +478,7 @@ up a tests skeleton.</p>
|
||||||
`-- my-project.lisp
|
`-- my-project.lisp
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Where <code>my-project.asd</code> resembles this:</p>
|
<p>where <code>my-project.asd</code> resembles this:</p>
|
||||||
|
|
||||||
<pre><code class="language-lisp">(asdf:defsystem "my-project"
|
<pre><code class="language-lisp">(asdf:defsystem "my-project"
|
||||||
:version "0.1.0"
|
:version "0.1.0"
|
||||||
|
@ -504,8 +509,8 @@ up a tests skeleton.</p>
|
||||||
<h3 id="how-to-load-an-existing-project">How to load an existing project</h3>
|
<h3 id="how-to-load-an-existing-project">How to load an existing project</h3>
|
||||||
|
|
||||||
<p>You have created a new project, or you have an existing one, and you
|
<p>You have created a new project, or you have an existing one, and you
|
||||||
want to work with it on the REPL, but Quicklisp doesn’t know it. How
|
want to work with it in the REPL, but Quicklisp doesn’t know about it. What
|
||||||
can you do ?</p>
|
do you do?</p>
|
||||||
|
|
||||||
<p>Well first, if you create it or clone it into
|
<p>Well first, if you create it or clone it into
|
||||||
one of <code>~/common-lisp</code>, <code>~/.local/share/common-lisp/source/</code> or
|
one of <code>~/common-lisp</code>, <code>~/.local/share/common-lisp/source/</code> or
|
||||||
|
@ -547,14 +552,14 @@ result in the REPL.</p>
|
||||||
|
|
||||||
<p>You can add this to your <code>~/.sbclrc</code>.</p>
|
<p>You can add this to your <code>~/.sbclrc</code>.</p>
|
||||||
|
|
||||||
<p>If you dislike the REPL to print all symbols upcase, add this:</p>
|
<p>If you dislike the REPL printing all symbols uppercase, add this:</p>
|
||||||
|
|
||||||
<pre><code>(setf *print-case* :downcase)
|
<pre><code>(setf *print-case* :downcase)
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<div class="info-box warning">
|
<div class="info-box warning">
|
||||||
<!-- if inside a <p> then bootstrap adds 10px padding to the bottom -->
|
<!-- if inside a <p> then bootstrap adds 10px padding to the bottom -->
|
||||||
<strong>Warning:</strong> This might break the behaviour of some packages like it happened with
|
<strong>Warning:</strong> This might break the behaviour of some packages like happened with
|
||||||
<a href="https://github.com/fukamachi/mito/issues/45">Mito</a>.
|
<a href="https://github.com/fukamachi/mito/issues/45">Mito</a>.
|
||||||
Avoid doing this in production.
|
Avoid doing this in production.
|
||||||
</div>
|
</div>
|
||||||
|
@ -603,7 +608,7 @@ Avoid doing this in production.
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – GUI toolkits</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – GUI toolkits</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -1165,7 +1170,7 @@ be immediately applied while the application is running!</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Home</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Home</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -149,6 +154,7 @@ a book containing recipes and other information about the preparation and cookin
|
||||||
<li><a href="os.html">Interfacing with your OS</a></li>
|
<li><a href="os.html">Interfacing with your OS</a></li>
|
||||||
<li><a href="databases.html">Databases</a></li>
|
<li><a href="databases.html">Databases</a></li>
|
||||||
<li><a href="ffi.html">Foreign Function Interfaces</a></li>
|
<li><a href="ffi.html">Foreign Function Interfaces</a></li>
|
||||||
|
<li>NEW! ⭐ <a href="dynamic-libraries.html">Building Dynamic Libraries</a></li>
|
||||||
<li><a href="gui.html">GUI programming</a></li>
|
<li><a href="gui.html">GUI programming</a></li>
|
||||||
<li><a href="sockets.html">Sockets</a></li>
|
<li><a href="sockets.html">Sockets</a></li>
|
||||||
<li><a href="websockets.html">WebSockets</a></li>
|
<li><a href="websockets.html">WebSockets</a></li>
|
||||||
|
@ -295,7 +301,7 @@ later.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Input/Output</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Input/Output</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -277,7 +282,7 @@ and
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Loop, iteration, mapping</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Loop, iteration, mapping</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -264,8 +269,10 @@ needed for the final result are actually created.</p>
|
||||||
reducers (i.e. functions like <code>+</code>) to traverse data streams in any way they
|
reducers (i.e. functions like <code>+</code>) to traverse data streams in any way they
|
||||||
wish, all while being very memory efficient.</p>
|
wish, all while being very memory efficient.</p>
|
||||||
|
|
||||||
<p>See <a href="https://git.sr.ht/~fosskers/cl-transducers">its README</a> or <a href="https://fosskers.github.io/cl-transducers/index.html">its
|
<p>See <a href="https://git.sr.ht/~fosskers/cl-transducers">its README</a>, <a href="https://fosskers.github.io/cl-transducers/index.html">its
|
||||||
API</a> for more information.</p>
|
API</a>, or the <a href="https://clojure.org/reference/transducers">original
|
||||||
|
Transducers document</a> for more
|
||||||
|
information.</p>
|
||||||
|
|
||||||
<h2 id="recipes">Recipes</h2>
|
<h2 id="recipes">Recipes</h2>
|
||||||
|
|
||||||
|
@ -347,7 +354,7 @@ infinitely. Here we show how to loop on a list forever.</p>
|
||||||
|
|
||||||
<p>We can build an infinite list by setting its last element to the list itself:</p>
|
<p>We can build an infinite list by setting its last element to the list itself:</p>
|
||||||
|
|
||||||
<pre><code class="language-lisp">(loop with list-a = '(1 2 3)
|
<pre><code class="language-lisp">(loop with list-a = (list 1 2 3)
|
||||||
with infinite-list = (setf (cdr (last list-a)) list-a)
|
with infinite-list = (setf (cdr (last list-a)) list-a)
|
||||||
for item in infinite-list
|
for item in infinite-list
|
||||||
repeat 8
|
repeat 8
|
||||||
|
@ -355,7 +362,7 @@ infinitely. Here we show how to loop on a list forever.</p>
|
||||||
;; (1 2 3 1 2 3 1 2)
|
;; (1 2 3 1 2 3 1 2)
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Illustration: <code>(last '(1 2 3))</code> is <code>(3)</code>, a list, or rather a cons cell, whose <code>car</code> is 3 and <code>cdr</code> is NIL. See the <a href="data-structures.html">data-structures chapter</a> for a reminder. This is the representation of <code>(list 3)</code>:</p>
|
<p>Illustration: <code>(last (list 1 2 3))</code> is <code>(3)</code>, a list, or rather a cons cell, whose <code>car</code> is 3 and <code>cdr</code> is NIL. See the <a href="data-structures.html">data-structures chapter</a> for a reminder. This is the representation of <code>(list 3)</code>:</p>
|
||||||
|
|
||||||
<pre><code>[o|/]
|
<pre><code>[o|/]
|
||||||
|
|
|
|
||||||
|
@ -1157,7 +1164,7 @@ NIL
|
||||||
;; (X Y Z)
|
;; (X Y Z)
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h5 id="iterating-2-by-2-over-a-list">Iterating 2 by 2 over a list</h5>
|
<h5 id="iterating-over-a-plist-or-2-by-2-over-a-list">Iterating over a plist or 2 by 2 over a list</h5>
|
||||||
|
|
||||||
<p>To iterate over a list, 2 items at a time we use a combination of <code>on</code>, <code>by</code> and destructuring.</p>
|
<p>To iterate over a list, 2 items at a time we use a combination of <code>on</code>, <code>by</code> and destructuring.</p>
|
||||||
|
|
||||||
|
@ -1536,7 +1543,7 @@ external-symbols fixnum float t nil of-type
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – License</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – License</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -124,7 +129,7 @@ documentation, even if advised of the possibility of such damage.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – LispWorks review</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – LispWorks review</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -640,6 +645,33 @@ create a so-called <code>console</code> image with multiprocessing enabled:</p>
|
||||||
|
|
||||||
<p>See LispWorks’ documentation.</p>
|
<p>See LispWorks’ documentation.</p>
|
||||||
|
|
||||||
|
<h2 id="delivering-applications">Delivering applications</h2>
|
||||||
|
|
||||||
|
<p>LispWorks’ delivery method revolves around its <code>delivery</code> function. It has good documentation: <a href="https://www.lispworks.com/documentation/lw80/deliv/deliv.htm">https://www.lispworks.com/documentation/lw80/deliv/deliv.htm</a>.</p>
|
||||||
|
|
||||||
|
<p>Unlike other open-source Lisps, LispWorks provides a tree-shaker that
|
||||||
|
can strip-off packages from the delivered application, allowing to
|
||||||
|
build small binaries, around 7MB.</p>
|
||||||
|
|
||||||
|
<h4 id="delivery-limitations">Delivery limitations</h4>
|
||||||
|
|
||||||
|
<p>LispWorks’s delivery <a href="https://www.lispworks.com/products/runtimes.html">doesn’t include</a> <code>compile-file</code> into the delivered
|
||||||
|
application (nor <code>save-image</code>, <code>deliver</code> and the IDE). As such, it isn’t possible to change code on the fly on a
|
||||||
|
delivered image. No Swank server, no possibility to use
|
||||||
|
<code>ql:quickload</code>.</p>
|
||||||
|
|
||||||
|
<p>To allow remote debugging, LW however provides its own debugger client. On the backend, do:</p>
|
||||||
|
|
||||||
|
<pre><code>(require "remote-debugger-client")
|
||||||
|
(dbg:start-client-remote-debugging-server :announce t)
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>and on the IDE, do:</p>
|
||||||
|
|
||||||
|
<pre><code>(require "remote-debugger-full")
|
||||||
|
(dbg:ide-connect-remote-debugging "host" :open-a-listener t)
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
<h2 id="see-also">See also</h2>
|
<h2 id="see-also">See also</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -647,6 +679,7 @@ create a so-called <code>console</code> image with multiprocessing enabled:</p>
|
||||||
<li><a href="https://en.wikipedia.org/wiki/LispWorks">LispWorks on Wikipedia</a></li>
|
<li><a href="https://en.wikipedia.org/wiki/LispWorks">LispWorks on Wikipedia</a></li>
|
||||||
<li>the <a href="https://github.com/fourier/awesome-lispworks">Awesome LispWorks</a> list</li>
|
<li>the <a href="https://github.com/fourier/awesome-lispworks">Awesome LispWorks</a> list</li>
|
||||||
<li><a href="https://www.youtube.com/watch?v=nsKx40ab9SY">Real Image-based approach in Common Lisp</a> - differences between SBCL and LispWorks.</li>
|
<li><a href="https://www.youtube.com/watch?v=nsKx40ab9SY">Real Image-based approach in Common Lisp</a> - differences between SBCL and LispWorks.</li>
|
||||||
|
<li>blog post: <a href="https://blog.dziban.net/posts/delivering-a-lispworks-application/">Delivering a LispWorks application</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
@ -679,7 +712,7 @@ create a so-called <code>console</code> image with multiprocessing enabled:</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Macros</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Macros</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -774,7 +779,7 @@ It also shows how to manipulate macros (and their expansion) in Emacs.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Miscellaneous</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Miscellaneous</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -189,7 +194,7 @@ T
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Numbers</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Numbers</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -699,7 +704,7 @@ or other bit-wise functions.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Interfacing with your OS</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Interfacing with your OS</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -114,6 +119,8 @@ NIL
|
||||||
|
|
||||||
<p>You should also note that some of these implementations also provide the ability to <em>set</em> these variables. These include ECL (<code>si:setenv</code>) and AllegroCL, LispWorks, and CLISP where you can use the functions from above together with <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_setf_.htm"><code>setf</code></a>. This feature might be important if you want to start subprocesses from your Lisp environment.</p>
|
<p>You should also note that some of these implementations also provide the ability to <em>set</em> these variables. These include ECL (<code>si:setenv</code>) and AllegroCL, LispWorks, and CLISP where you can use the functions from above together with <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_setf_.htm"><code>setf</code></a>. This feature might be important if you want to start subprocesses from your Lisp environment.</p>
|
||||||
|
|
||||||
|
<p>To set an envionmental variable, you can <code>setf</code> with <code>(uiop:getenv "lisp")</code> in a implementation-independent way.</p>
|
||||||
|
|
||||||
<p>Also note that the
|
<p>Also note that the
|
||||||
<a href="https://www.common-lisp.net/project/osicat/manual/osicat.html#Environment">Osicat</a>
|
<a href="https://www.common-lisp.net/project/osicat/manual/osicat.html#Environment">Osicat</a>
|
||||||
library has the method <code>(environment-variable "name")</code>, on POSIX-like
|
library has the method <code>(environment-variable "name")</code>, on POSIX-like
|
||||||
|
@ -156,7 +163,8 @@ libraries (see next section) make it portable.</p>
|
||||||
<pre><code class="language-lisp">(defun my-command-line ()
|
<pre><code class="language-lisp">(defun my-command-line ()
|
||||||
(or
|
(or
|
||||||
#+SBCL *posix-argv*
|
#+SBCL *posix-argv*
|
||||||
#+LISPWORKS system:*line-arguments-list*))
|
#+LISPWORKS system:*line-arguments-list*)
|
||||||
|
#+CLISP *args*)
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Now it would be handy to access them in a portable way and to parse
|
<p>Now it would be handy to access them in a portable way and to parse
|
||||||
|
@ -495,7 +503,7 @@ with the returned <code>exit-code</code>. 0 is success.</p>
|
||||||
(format t "error output is: ~a" error-output)))
|
(format t "error output is: ~a" error-output)))
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3 id="running-visual-commands-htop">Running visual commands (htop)</h3>
|
<h3 id="running-interactive-and-visual-commands-htop">Running interactive and visual commands (htop)</h3>
|
||||||
|
|
||||||
<p>Use <code>uiop:run-program</code> and set both <code>:input</code> and <code>:output</code> to <code>:interactive</code>:</p>
|
<p>Use <code>uiop:run-program</code> and set both <code>:input</code> and <code>:output</code> to <code>:interactive</code>:</p>
|
||||||
|
|
||||||
|
@ -506,8 +514,7 @@ with the returned <code>exit-code</code>. 0 is success.</p>
|
||||||
|
|
||||||
<p>This will spawn <code>htop</code> in full screen, as it should.</p>
|
<p>This will spawn <code>htop</code> in full screen, as it should.</p>
|
||||||
|
|
||||||
<p>It works for more commands (<code>sudo</code>, <code>vim</code>…), however not for all interactive
|
<p>It works for more commands (<code>sudo</code>, <code>vim</code>, <code>less</code>…).</p>
|
||||||
programs, such as <code>less</code> or <code>fzf</code>.</p>
|
|
||||||
|
|
||||||
<h2 id="piping">Piping</h2>
|
<h2 id="piping">Piping</h2>
|
||||||
|
|
||||||
|
@ -585,7 +592,7 @@ SB-POSIX:WAITPID (fbound)
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Packages</h1>
|
<h1 id="title-non-xs"><a href="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. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -430,7 +435,7 @@ example:</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Pattern Matching</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Pattern Matching</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -294,7 +299,7 @@ true it is matched against subpattern1.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Performance Tuning and Tips</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Performance Tuning and Tips</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -749,7 +754,7 @@ unless it is declared <code>notinline</code>.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Threads, concurrency, parallelism</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Threads, concurrency, parallelism</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -2373,7 +2378,7 @@ manual. <a href="http://www.sbcl.org/manual/">For SBCL, here is a link to the of
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Regular Expressions</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Regular Expressions</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -164,6 +169,17 @@ CL-USER> (mapcar #'parse-integer *)
|
||||||
<p>If SHAREDP is true, the substrings may share structure with TARGET-STRING.</p>
|
<p>If SHAREDP is true, the substrings may share structure with TARGET-STRING.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
<h4 id="count-matches-new-in-212-april-2024">count-matches (new in 2.1.2, April 2024)</h4>
|
||||||
|
|
||||||
|
<p><code>(count-matches regex target-string)</code> returns a count of all matches of <code>regex</code> against <code>target-string</code>:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-lisp">CL-USER> (ppcre:count-matches "a" "foo bar baz")
|
||||||
|
2
|
||||||
|
|
||||||
|
CL-USER> (ppcre:count-matches "\\w*" "foo bar baz")
|
||||||
|
6
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
<h4 id="scan-to-strings-register-groups-bind">scan-to-strings, register-groups-bind</h4>
|
<h4 id="scan-to-strings-register-groups-bind">scan-to-strings, register-groups-bind</h4>
|
||||||
|
|
||||||
<p>The <code>scan-to-strings</code> function is similar to <code>scan</code> but returns
|
<p>The <code>scan-to-strings</code> function is similar to <code>scan</code> but returns
|
||||||
|
@ -238,7 +254,7 @@ assigning the matching fragment to the variable:</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Scripting. Command line arguments. Executables.</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Scripting. Command line arguments. Executables.</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -888,7 +893,7 @@ whichever other policy.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – TCP/UDP programming with sockets</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – TCP/UDP programming with sockets</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -253,7 +258,7 @@ and <code>#(8 7 6 5 4 3 2 1)</code> on the second one.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Strings</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Strings</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -801,7 +806,7 @@ in this case.</p>
|
||||||
;; (42 41 1)
|
;; (42 41 1)
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3 id="to-any-number-read-from-string">To any number: read-from-string</h3>
|
<h3 id="to-any-number-read-from-string">To any number: <code>read-from-string</code></h3>
|
||||||
|
|
||||||
<p>Be aware that the full reader is in effect if you’re using this
|
<p>Be aware that the full reader is in effect if you’re using this
|
||||||
function. This can lead to vulnerability issues. You should use a
|
function. This can lead to vulnerability issues. You should use a
|
||||||
|
@ -834,6 +839,23 @@ SYMBOL
|
||||||
"gotcha"
|
"gotcha"
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
|
<h3 id="protecting-read-from-string">Protecting <code>read-from-string</code></h3>
|
||||||
|
|
||||||
|
<p>At the very least, if you are reading data coming from the outside, use this:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-lisp">(let ((cl:*read-eval* nil))
|
||||||
|
(read-from-string "…"))
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>This prevents code to be evaluated at read-time. That way our last example, using the <code>#.</code> reader macro, would not work. You’ll get the error “can’t read #. while *READ-EVAL* is NIL”.</p>
|
||||||
|
|
||||||
|
<p>And better yet, for more protection from a possibly custom readtable that would introduce another reader macro:</p>
|
||||||
|
|
||||||
|
<pre><code class="language-lisp">(with-standard-io-syntax
|
||||||
|
(let ((cl:*read-eval* nil))
|
||||||
|
(read-from-string "…")))
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
<h3 id="to-a-float-the-parse-float-library">To a float: the parse-float library</h3>
|
<h3 id="to-a-float-the-parse-float-library">To a float: the parse-float library</h3>
|
||||||
|
|
||||||
<p>There is no built-in function similar to <code>parse-integer</code> to parse
|
<p>There is no built-in function similar to <code>parse-integer</code> to parse
|
||||||
|
@ -1275,7 +1297,7 @@ _ - Conditional Newline
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Defining Systems</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Defining Systems</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -298,7 +303,7 @@ generate a project skeleton. It will create a default ASDF definition,
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Testing the code</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Testing the code</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -932,7 +937,7 @@ a problem.</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
BIN
lispcookbook.github.io/cl-cookbook/trace-dialog.png
Normal file
BIN
lispcookbook.github.io/cl-cookbook/trace-dialog.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Type System</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Type System</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -646,7 +651,7 @@ means “any Lisp datum”. <a href="type.html#fnref:1" class="reversefootnote"
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Using VSCode with Alive</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Using VSCode with Alive</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -649,7 +654,7 @@ on an SBCL image in a docker container.</li>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Web Scraping</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Web Scraping</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -423,7 +428,7 @@ network, parallelism and concurrency libraries to see on the
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Web development</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Web development</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -566,9 +571,7 @@ the interactive debugger (for development only, of course):</li>
|
||||||
|
|
||||||
<p>See also the generic function <code>maybe-invoke-debugger</code> if you want to
|
<p>See also the generic function <code>maybe-invoke-debugger</code> if you want to
|
||||||
fine-tune this behaviour. You might want to specialize it on specific
|
fine-tune this behaviour. You might want to specialize it on specific
|
||||||
condition classes (see below) for debugging purposes. The default method <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_invoke.htm">invokes
|
condition classes (see below) for debugging purposes.</p>
|
||||||
the debugger</a>
|
|
||||||
if <code>*catch-errors-p*</code> is <code>nil</code>.</p>
|
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>*show-lisp-errors-p*</code>: set to <code>t</code> if you want to see errors in HTML output in the browser.</li>
|
<li><code>*show-lisp-errors-p*</code>: set to <code>t</code> if you want to see errors in HTML output in the browser.</li>
|
||||||
|
@ -706,7 +709,7 @@ the most downloaded libraries of Quicklisp.</p>
|
||||||
<h4 id="djula-filters">Djula filters</h4>
|
<h4 id="djula-filters">Djula filters</h4>
|
||||||
|
|
||||||
<p>Filters allow to modify how a variable is displayed. Djula comes with
|
<p>Filters allow to modify how a variable is displayed. Djula comes with
|
||||||
a good set of built-in filters and they are <a href="https://mmontone.github.io/djula/doc/build/html/filters.html">well documented</a>. They are not to be confused with <a href="https://mmontone.github.io/djula/doc/build/html/tags.html">tags</a>.</p>
|
a good set of built-in filters and they are <a href="https://mmontone.github.io/djula/djula/Filters.html#Filters">well documented</a>. They are not to be confused with <a href="https://mmontone.github.io/djula/djula/Tags.html#Tags">tags</a>.</p>
|
||||||
|
|
||||||
<p>They look like this: ``, where <code>lower</code> is an
|
<p>They look like this: ``, where <code>lower</code> is an
|
||||||
existing filter, which renders the text into lowercase.</p>
|
existing filter, which renders the text into lowercase.</p>
|
||||||
|
@ -987,7 +990,9 @@ Listening on localhost:9003.
|
||||||
|
|
||||||
<h3 id="multi-platform-delivery-with-electron">Multi-platform delivery with Electron</h3>
|
<h3 id="multi-platform-delivery-with-electron">Multi-platform delivery with Electron</h3>
|
||||||
|
|
||||||
<p><a href="https://ceramic.github.io/">Ceramic</a> makes all the work for us.</p>
|
<p>Once you built a binary of your web application, you can point an Electron window to it.</p>
|
||||||
|
|
||||||
|
<p><a href="https://ceramic.github.io/">Ceramic</a> is a collection of tools that make all the work for us.</p>
|
||||||
|
|
||||||
<p>It is as simple as this:</p>
|
<p>It is as simple as this:</p>
|
||||||
|
|
||||||
|
@ -1206,6 +1211,8 @@ and DB migrations. Uses Qlot, Buildapp, SystemD for deployment.</li>
|
||||||
a simple project template with Hunchentoot, Easy-Routes, Djula and Bulma CSS.</li>
|
a simple project template with Hunchentoot, Easy-Routes, Djula and Bulma CSS.</li>
|
||||||
<li><a href="https://github.com/vindarel/lisp-web-live-reload-example/">lisp-web-live-reload-example</a> -
|
<li><a href="https://github.com/vindarel/lisp-web-live-reload-example/">lisp-web-live-reload-example</a> -
|
||||||
a toy project to show how to interact with a running web app.</li>
|
a toy project to show how to interact with a running web app.</li>
|
||||||
|
<li><a href="https://lisp-journey.gitlab.io/blog/common-lisp-on-the-web-enrich-your-stacktrace-with-request-and-session-data/">lisp-journey: enrich your stacktrace with session and user data</a></li>
|
||||||
|
<li><a href="https://www.youtube.com/watch?v=h_noB1sI_e8">video: how to build a web app in Lisp · part 1</a> featuring Hunchentoot, easy-routes, Djula templates, error handling, common traps.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2 id="credits">Credits</h2>
|
<h2 id="credits">Credits</h2>
|
||||||
|
@ -1245,7 +1252,7 @@ a toy project to show how to interact with a running web app.</li>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – WebSockets</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – WebSockets</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -397,7 +402,7 @@ should see your chat app!</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,19 @@
|
||||||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Using the Win32 API</h1>
|
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Using the Win32 API</h1>
|
||||||
|
|
||||||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||||||
<p class="announce">
|
<!-- <p class="announce"> -->
|
||||||
📢 🤶 ⭐
|
<!-- 📢 🤶 ⭐ -->
|
||||||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
|
||||||
<strong>
|
<!-- <strong> -->
|
||||||
Recently added: 18 videos on MACROS.
|
<!-- Recently added: 18 videos on MACROS. -->
|
||||||
</strong>
|
<!-- </strong> -->
|
||||||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
|
||||||
</p>
|
<!-- </p> -->
|
||||||
|
|
||||||
|
<p class="announce">
|
||||||
|
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="announce-neutral">
|
<p class="announce-neutral">
|
||||||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -1290,7 +1295,7 @@ handle
|
||||||
<hr/>
|
<hr/>
|
||||||
© 2002–2023 the Common Lisp Cookbook Project
|
© 2002–2023 the Common Lisp Cookbook Project
|
||||||
<div>
|
<div>
|
||||||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue