<?xml version="1.0" encoding="utf-8"?> 
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
 <title type="text">Fragments: Posts tagged 'lisp'</title>
 <link rel="self" href="https://www.tfeb.org/fragments/feeds/lisp.atom.xml" />
 <link href="https://www.tfeb.org/fragments/tags/lisp.html" />
 <id>urn:https-www-tfeb-org:-fragments-tags-lisp-html</id>
 <updated>2026-05-01T15:43:22Z</updated>
 <entry>
  <title type="text">Making CLOS slot access less slow</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2026/05/01/making-clos-slot-access-less-slow/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2026-05-01-making-clos-slot-access-less-slow</id>
  <published>2026-05-01T15:43:22Z</published>
  <updated>2026-05-01T15:43:22Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Access to slots in CLOS instances is often very slow. It&amp;rsquo;s probably not possible for it ever to be really fast, but the AMOP MOP does provide a way of making it, at least, less slow.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="how-slow-is-it"&gt;How slow is it?&lt;/h2&gt;

&lt;p&gt;Here are some benchmarks for accessing fields in objects of various kinds, using SBCL. All of these tests do something equivalent to&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defclass a ()
  ((i :initform 0 :type fixnum)))

(defclass a/no-fixnum ()
  ((i :initform 0)))

(defmethod svn ((a a) n)
  (declare (type fixnum n)
           (optimize speed (safety 0)))
  (dotimes (i n)
    (incf (the fixnum (slot-value a 'i)))))

(defmethod svn ((a a/no-fixnum) n)
  (declare (type fixnum n)
           (optimize speed (safety 0)))
  (dotimes (i n)
    (incf (the fixnum (slot-value a 'i)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;They then call &lt;code&gt;svn&lt;/code&gt; (or equivalent) with a large value of \(n\), do that a number of times \(m\) and then divide by \(2 \times n \times m\) to get an average time per access (&lt;code&gt;incf&lt;/code&gt; accesses the slot twice).&lt;/p&gt;

&lt;p&gt;For SBCL 2.6.3.178-a190d9710 on ARM64 Apple M1, seconds per access:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;raw fixnum increment \(1.58\times 10^{-10}\), ratio \(1.0\);&lt;/li&gt;
 &lt;li&gt;slot access with &lt;code&gt;slot-value&lt;/code&gt; (slot type &lt;code&gt;fixnum&lt;/code&gt;) \(1.20\times 10^{-8}\), ratio \(76\);&lt;/li&gt;
 &lt;li&gt;slot access with &lt;code&gt;slot-value&lt;/code&gt; (no slot type) \(1.22\times 10^{-8}\), ratio \(77\);&lt;/li&gt;
 &lt;li&gt;slot access with &lt;code&gt;slot-value&lt;/code&gt; (single &lt;code&gt;slot-value-using-class&lt;/code&gt; method) \(1.69\times 10^{-8}\), ratio \(107\);&lt;/li&gt;
 &lt;li&gt;slot access using &lt;code&gt;standard-instance-access&lt;/code&gt; \(1.00\times 10^{-9}\), ratio \(6.4\);&lt;/li&gt;
 &lt;li&gt;slot access, struct (slot type &lt;code&gt;fixnum&lt;/code&gt;) \(1.57\times 10^{-10}\), ratio \(1.0\);&lt;/li&gt;
 &lt;li&gt;slot access, struct (no type) \(1.58\times 10^{-10}\), ratio \(1.0\);&lt;/li&gt;
 &lt;li&gt;slot access, cons (&lt;code&gt;car&lt;/code&gt;) \(1.59\times 10^{-10}\), ratio \(1.0\).&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;These numbers vary slightly, but this gives a good picture of what is going on. In particular you can see that &lt;code&gt;slot-value&lt;/code&gt; within a method specialised on the class is more than 70 times slower than access for a structure slot, but if you can use &lt;code&gt;standard-instance-access&lt;/code&gt; it is only about 6 times slower: &lt;code&gt;standard-instance-access&lt;/code&gt; speeds things up by a factor of about 10, which changes CLOS slot access performance from laughably slow to merely pretty slow.&lt;/p&gt;

&lt;h2 id="a-macro"&gt;A macro&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;ve written a macro, called &lt;code&gt;with-sia-slots&lt;/code&gt; which is like &lt;code&gt;with-slots&lt;/code&gt; but uses &lt;code&gt;standard-instance-access&lt;/code&gt;. It therefore has all the constraints imposed by that, but it is significantly faster than &lt;code&gt;with-slots&lt;/code&gt; or &lt;code&gt;slot-value&lt;/code&gt;. It has some overhead, as it has to dynamically compute the slot locations: this is better done outside any inner loop. This means that, for instance, you probably want to write code that looks like&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(with-sia-slots (x) o
  (dotimes (i many)
    (setf x (... x ...))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which will mean you only pay the overhead once.&lt;/p&gt;

&lt;p&gt;The above tests don&amp;rsquo;t use &lt;code&gt;with-sia-slots&lt;/code&gt;, as I wrote them partly to see if something like this was worth writing. However on a current (at the time of writing) SBCL &lt;code&gt;with-sia-slots&lt;/code&gt; is asymptotically about 10 times faster than &lt;code&gt;with-slots&lt;/code&gt; as demonstrated by these tests.&lt;/p&gt;

&lt;p&gt;Up to package names it should be portable to any CL with an AMOP-compatible MOP. It can be found in my implementation-specific hacks, linked from &lt;a href="https://tfeb.org/fragments/documentation/" title="Documentation"&gt;here&lt;/a&gt;.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Structures of arrays</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2026/04/16/structures-of-arrays/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2026-04-16-structures-of-arrays</id>
  <published>2026-04-16T11:01:13Z</published>
  <updated>2026-04-16T11:01:13Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Or, second system.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;A while ago, I decided that I&amp;rsquo;d like to test my intuition that Lisp (specifically implementations of Common Lisp) was not, in fact, bad at floating-point code and that the ease of designing languages in Lisp could make traditional Fortran-style array-bashing numerical code pretty pleasant to write.&lt;/p&gt;

&lt;p&gt;I used an intentionally naïve numerical solution to a gravitating many-body system as a benchmark, so I could easily compare Lisp &amp;amp; C versions. The brief result is that the Lisp code is a little slower than C, but not much: Lisp is not, in fact, slow. Who knew?&lt;/p&gt;

&lt;p&gt;The point here though, is that I wanted to dress up the array-bashing code so it looked a lot more structured. To do this I wrote a macro which hid what was in fact an array of (for instance) double floats behind a bunch of syntax which made it look like an array of structures. That macro took a couple of hours.&lt;/p&gt;

&lt;p&gt;This was fine and pretty simple, but it only dealt with a single type for each conceptual array of objects, there was no inheritance and it was restricted in various other ways. In particular it really was syntactic sugar on a vector: there was no distinct implementational type at all. So I thought well, I could make it more general and nicer.&lt;/p&gt;

&lt;p&gt;Big mistake.&lt;/p&gt;

&lt;h2 id="the-second-system"&gt;The second system&lt;/h2&gt;

&lt;p&gt;Here is an example of what I wanted to be able to do (this is in fact the current syntax):&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(define-soa-class example ()
  ((x :array t :type double-float)
   (y :array t :type double-float)
   (p :array t :type double-float :group pq)
   (q :array t :type double-float :group pq)
   (r :array t :type fixnum)
   (s)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This defines a class, instances of which have five array slots and one scalar slot. Of the array slots:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; share an array and will be neighbouring elements;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;p&lt;/code&gt; and &lt;code&gt;q&lt;/code&gt; share a different array, because the group option says they must not share with &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;r&lt;/code&gt; will be in its own array, unless the upgraded element type of &lt;code&gt;fixnum&lt;/code&gt; is the same as that of &lt;code&gt;double-float&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;s&lt;/code&gt; is just a slot.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The implementation will tell you this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (describe (make-instance 'example :dimensions '(2 2)))
#&amp;lt;example 8010059EEB&amp;gt; is an example
[...]
dimensions      (2 2)
total-size      4
rank            2
tick            1
its class example has a valid layout
it has 3 arrays:
 index 0, element type double-float, 2 slots
 index 1, element type (signed-byte 64), 1 slot
 index 2, element type double-float, 2 slots
it has 5 array slots:
 name x, index 0 offset 0
 name y, index 0 offset 1
 name r, index 1 offset 0
 name p, index 2 offset 0
 name q, index 2 offset 1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is already too complicated: the ability to control sharing via groups is almost certainly never going to be useful: it&amp;rsquo;s only even there because I thought of it quite early on and never removed it.&lt;/p&gt;

&lt;p&gt;The class definition macro then needs to arrange life so that enough information is available so that a macro can be written which turns indexed slot access into indexed array access of the underlying arrays which are secretly stored in instances, inserting declarations to make this as fast as possible: anything slower than explicit array access is not acceptable. This might (and does) look like this, for example:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(with-array-slots (x y) (thing example)
  (for* ((i ...) (j ...))
    (setf (x i j) (- (y i j) (y j i)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see from this, the resulting objects should be allowed to have rank other than 1. Inheritance should also work, including for array slots. Redefinition should be supported and obsolete macro expansions and instances at least detected.&lt;/p&gt;

&lt;p&gt;In other words there are &lt;em&gt;exactly two things&lt;/em&gt; I should have aimed at achieving: the ability to define fields of various types and have them grouped into (generally fewer) underlying arrays, and an implementational type to hold these things. Everything else was just unnecessary baggage which made the implementation much more complicated than it needed to be.&lt;/p&gt;

&lt;p&gt;I had not finished making mistakes. The system needs to store some metadata about how slots map onto the underlying arrays, element types and so on, so the macro can use this to compile efficient code. There are two obvious ways to do this: use the property list of the class name, or subclass &lt;code&gt;standard-class&lt;/code&gt; and store the metadata in the class. The first approach is simple, portable, has clear semantics, but it&amp;rsquo;s &amp;lsquo;hacky&amp;rsquo;; the second is more complicated, not portable, has unclear semantics&lt;sup&gt;&lt;a href="#2026-04-16-structures-of-arrays-footnote-1-definition" name="2026-04-16-structures-of-arrays-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;, but it&amp;rsquo;s The Right Thing&lt;sup&gt;&lt;a href="#2026-04-16-structures-of-arrays-footnote-2-definition" name="2026-04-16-structures-of-arrays-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;. Another wrong decision I made without even trying.&lt;/p&gt;

&lt;p&gt;The only thing that saved me was that the nature of software is that you can only make a finite number of bad decisions in a finite time.&lt;/p&gt;

&lt;h2 id="more-bad-decisions"&gt;More bad decisions&lt;/h2&gt;

&lt;p&gt;I was not done. Early on, I thought that, well, I could make this whole thing be a shim around &lt;code&gt;defstruct&lt;/code&gt;: single inheritance was more than enough, and obviously I could store metadata on the property list of the type name as described above. And there&amp;rsquo;s no nausea with multiple accessors or any of that nonsense.&lt;/p&gt;

&lt;p&gt;But, somehow, I found writing a thing which would process the &lt;code&gt;(structure-name ...)&lt;/code&gt; case of &lt;code&gt;defstruct&lt;/code&gt; too painful, so I decided to go for the shim-around-&lt;code&gt;defclass&lt;/code&gt; version instead. I even have a partly-complete version of the &lt;code&gt;defstruct&lt;/code&gt;y code which I abandoned. Another mistake.&lt;/p&gt;

&lt;p&gt;I also decided that The Right Thing was to have the system support objects of rank 0. That constrains the underlying array representation (it needs to use rank \(n+1\) arrays for an object of rank \(n\)) in a way which I thought for a long time might limit performance.&lt;/p&gt;

&lt;h2 id="things-i-already-knew"&gt;Things I already knew&lt;/h2&gt;

&lt;p&gt;At any point during the implementation of this I could have told you that it was too general and the implementation was going to be too complicated for no real gain. I don&amp;rsquo;t know why I made so many bad choices.&lt;/p&gt;

&lt;p&gt;The whole process took weeks and I nearly just gave up several times.&lt;/p&gt;

&lt;h2 id="the-light-at-the-end-of-the-tunnel"&gt;The light at the end of the tunnel&lt;/h2&gt;

&lt;p&gt;Or: all-up testing.&lt;/p&gt;

&lt;p&gt;Eventually, I had a thing I thought might work. The macro syntax was a bit ugly (that macro still exists, with a different name) but it seemed to work. But since the whole purpose of the thing was performance, that needed to be checked. I wasn&amp;rsquo;t optimistic.&lt;/p&gt;

&lt;p&gt;What I did was to write a version of my naïve gravitational many-body system using the new code, based closely on the previous one. The function that updates the state of the particles looks like this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun/quickly step-pvs (source destination from below dt G &amp;amp;aux
                                (n (particle-vector-length source)))
  ;; Step a source particle vector into a destination one.
  ;;
  ;; Operation count:
  ;;  3
  ;;  + (below - from) * (n - 1) * (3 + 8 + 9)
  ;;  + (below - from) * (12 + 6)
  ;;  = (below - from) * (20 * (n - 1) + 18) + 3
  (declare (type particle-vector source destination)
           (type vector-index from)
           (type vector-dimension below)
           (type fpv dt G)
           (type vector-dimension n))
  (when (eq source destination)
    (error "botch"))
  (let*/fpv ((Gdt (* G dt))
             (Gdt^2/2 (/ (* Gdt dt) (fpv 2.0))))
    (binding-array-slots (((source particle-vector :check nil :rank 1 :suffix _s)
                           m x y z vx vy vz)
                          ((destination particle-vector :check nil :rank 1 :suffix _d)
                           m x y z vx vy vz))
      (for ((i1 (in-naturals :initially from :bound below :fixnum t)))
        (let/fpv ((ax/G zero.fpv)
                  (ay/G zero.fpv)
                  (az/G zero.fpv)
                  (x1 (x_s i1))
                  (y1 (y_s i1))
                  (z1 (z_s i1))
                  (vx1 (vx_s i1))
                  (vy1 (vy_s i1))
                  (vz1 (vz_s i1)))
          (for ((i2 (in-naturals n t)))
            (when (= i1 i2) (next))
            (let/fpv ((m2 (m_s i2))
                      (x2 (x_s i2))
                      (y2 (y_s i2))
                      (z2 (z_s i2)))
              (let/fpv ((rx (- x2 x1))
                        (ry (- y2 y1))
                        (rz (- z2 z1)))
                (let/fpv ((r^3 (let* ((r^2 (+ (* rx rx) (* ry ry) (* rz rz)))
                                      (r (sqrt r^2)))
                                 (declare (type nonnegative-fpv r^2 r))
                                 (* r r r))))
                  (incf ax/G (/ (* rx m2) r^3))
                  (incf ay/G (/ (* ry m2) r^3))
                  (incf az/G (/ (* rz m2) r^3))))))
          (setf (x_d i1) (+ x1 (* vx1 dt) (* ax/G Gdt^2/2))
                (y_d i1) (+ y1 (* vy1 dt) (* ay/G Gdt^2/2))
                (z_d i1) (+ z1 (* vz1 dt) (* az/G Gdt^2/2)))
          (setf (vx_d i1) (+ vx1 (* ax/G Gdt))
                (vy_d i1) (+ vy1 (* ay/G Gdt))
                (vz_d i1) (+ vz1 (* az/G Gdt)))))))
  destination)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And it not only worked, the performance was very close to the previous version, straight out of the gate. The syntax is not as nice as that of the initial, quick-and-dirty version, but it is much more general, so I think that&amp;rsquo;s worth it on the whole.&lt;/p&gt;

&lt;p&gt;There have been problems since then: in particular the dependency on when classes get defined. It will never be as portable as I&amp;rsquo;d like because of the unnecessary MOP dependencies&lt;sup&gt;&lt;a href="#2026-04-16-structures-of-arrays-footnote-3-definition" name="2026-04-16-structures-of-arrays-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt;, but it is usable and quick&lt;sup&gt;&lt;a href="#2026-04-16-structures-of-arrays-footnote-4-definition" name="2026-04-16-structures-of-arrays-footnote-4-return"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Was it worth it? May be, but it should have been simpler.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2026-04-16-structures-of-arrays-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;When exactly do classes get defined? Right.&amp;nbsp;&lt;a href="#2026-04-16-structures-of-arrays-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2026-04-16-structures-of-arrays-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;Nothing that uses the AMOP MOP is ever The Right Thing, because the whole thing was designed by people who were extremely smart, but still not as smart as they needed to be and thought they were. It&amp;rsquo;s unclear if any MOP for CLOS can ever be satisfactory, in part because CLOS itself suffers from the same smart-but-not-smart-enough problem to a large extent not helped by bring dropped wholesale into CL at the last minute: by the time CL was standardised people had written large systems in it, but almost nobody had written anything significant using CLOS, let alone the AMOP MOP.&amp;nbsp;&lt;a href="#2026-04-16-structures-of-arrays-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2026-04-16-structures-of-arrays-footnote-3-definition" class="footnote-definition"&gt;
   &lt;p&gt;A mistake I somehow managed to avoid was using the whole slot-definition mechanism the MOP wants you to use.&amp;nbsp;&lt;a href="#2026-04-16-structures-of-arrays-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2026-04-16-structures-of-arrays-footnote-4-definition" class="footnote-definition"&gt;
   &lt;p&gt;I will make it available at some point.&amp;nbsp;&lt;a href="#2026-04-16-structures-of-arrays-footnote-4-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Rules for Lisp programs</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2026/04/08/rules-for-lisp-programs/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2026-04-08-rules-for-lisp-programs</id>
  <published>2026-04-08T10:48:26Z</published>
  <updated>2026-04-08T10:48:26Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Some very serious rules. Very serious.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;&lt;strong&gt;The essential rule.&lt;/strong&gt; If you are not building languages in Lisp why are you even here?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The lesser rules.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;If you write a program which uses &lt;code&gt;defclass&lt;/code&gt; you are probably making a mistake.&lt;/li&gt;
 &lt;li&gt;If you write a program which uses the CLOS MOP you are making a mistake.&lt;/li&gt;
 &lt;li&gt;If you write a program which uses LOOP for any purpose other than creating a better iteration construct you are making a mistake.&lt;/li&gt;
 &lt;li&gt;If you write a program which uses LOOP only to create a better iteration construct you are probably making a mistake.&lt;/li&gt;
 &lt;li&gt;If you write a program which uses explicit package-qualified names more than very infrequently you will be cast into the outer darkness along with your program.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;I will not be taking questions.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Literals and constants in Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2025/12/04/literals-and-constants-in-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2025-12-04-literals-and-constants-in-common-lisp</id>
  <published>2025-12-04T16:23:45Z</published>
  <updated>2025-12-04T16:23:45Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Or, &lt;code&gt;constantp&lt;/code&gt; is not enough.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Because I do a lot of things with &lt;a href="https://www.tfeb.org/fragments/documentation/star.html" title="Štar"&gt;Štar&lt;/a&gt;, and for other reasons, I spend a fair amount of time writing various compile-time optimizers for things which have the semantics of function calls. You can think of iterator optimizers in Štar as being a bit like compiler macros: the aim is to take a function call form and to turn it, in good cases, into something quicker&lt;sup&gt;&lt;a href="#2025-12-04-literals-and-constants-in-common-lisp-footnote-1-definition" name="2025-12-04-literals-and-constants-in-common-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;. One important way of doing this is to be able to detect things which are known at compile-time: constants and literals, for instance.&lt;/p&gt;

&lt;p&gt;One of the things this has made clear to me is that, like John Peel, &lt;code&gt;constantp&lt;/code&gt; is not enough. Here&amp;rsquo;s an example.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(in-row-major-array a :simple t :element-type 'fixnum)&lt;/code&gt; is a function call whose values Štar can use to tell it how to iterate (via &lt;code&gt;row-major-aref&lt;/code&gt;) over an array. When used in a &lt;code&gt;for&lt;/code&gt; form, its optimizer would like to be able to expand into something involving &lt;code&gt;(declare (type (simple-array fixnum *) ...)&lt;/code&gt;, so that the details of the array are known to the compiler, which can then generate fast code for &lt;code&gt;row-major-aref&lt;/code&gt;. This makes a great deal of difference to performance: array access to simple arrays of known element types is usually much faster than to general arrays.&lt;/p&gt;

&lt;p&gt;In order to do this it needs to know two things:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;that the values of the &lt;code&gt;simple&lt;/code&gt; and &lt;code&gt;element-type&lt;/code&gt; keyword arguments are compile-time constants;&lt;/li&gt;
 &lt;li&gt;&lt;em&gt;what their values are&lt;/em&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;You might say, well, that&amp;rsquo;s what &lt;code&gt;constantp&lt;/code&gt; is for&lt;sup&gt;&lt;a href="#2025-12-04-literals-and-constants-in-common-lisp-footnote-2-definition" name="2025-12-04-literals-and-constants-in-common-lisp-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;. It&amp;rsquo;s not: &lt;code&gt;constantp&lt;/code&gt; tells you only the &lt;em&gt;first&lt;/em&gt; of these, and you need both.&lt;/p&gt;

&lt;p&gt;Consider this code, in a file to be compiled:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defconstant et 'fixnum)

(defun ... ...
  (for ((e (in-array a :element-type et)))
    ...)
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, &lt;code&gt;constantp&lt;/code&gt;will tell you that &lt;code&gt;et&lt;/code&gt; is indeed a compile-time constant. &lt;em&gt;But it won&amp;rsquo;t tell you its value&lt;/em&gt;, and in particular nothing says it needs to be bound at compile-time at all: &lt;code&gt;(symbol-value 'et)&lt;/code&gt; may well be an error at compile-time.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;constantp&lt;/code&gt; is not enough&lt;sup&gt;&lt;a href="#2025-12-04-literals-and-constants-in-common-lisp-footnote-3-definition" name="2025-12-04-literals-and-constants-in-common-lisp-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt;! instead you need a function that tells you &amp;lsquo;yes, this thing is a compile-time constant, and its value is &amp;hellip;&amp;rsquo;. This is what &lt;code&gt;literal&lt;/code&gt; does&lt;sup&gt;&lt;a href="#2025-12-04-literals-and-constants-in-common-lisp-footnote-4-definition" name="2025-12-04-literals-and-constants-in-common-lisp-footnote-4-return"&gt;4&lt;/a&gt;&lt;/sup&gt;: it conservatively answers the question, and tells you the value if so. In particular, an expression like &lt;code&gt;(literal '(quote fixnum))&lt;/code&gt; will return &lt;code&gt;fixnum&lt;/code&gt;, the value, and &lt;code&gt;t&lt;/code&gt; to say yes, it is a compile-time constant. It can&amp;rsquo;t do this for things defined with &lt;code&gt;defconstant&lt;/code&gt;, and it may miss other cases, but when it says something is a compile-time constant, it is. In particular it works for actual literals (hence its name), and for forms whose macroexpansion is a literal.&lt;/p&gt;

&lt;p&gt;That is enough in practice.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2025-12-04-literals-and-constants-in-common-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;Śtar&amp;rsquo;s iterator optimizers are not compiler macros, because the code they write is inserted in various places in the iteration construct, but they&amp;rsquo;re doing a similar job: turning a construct involving many function calls into one requiring fewer or no function calls.&amp;nbsp;&lt;a href="#2025-12-04-literals-and-constants-in-common-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-12-04-literals-and-constants-in-common-lisp-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;And you may ask yourself, &amp;ldquo;How do I work this?&amp;rdquo; / And you may ask yourself, &amp;ldquo;Where is that large automobile?&amp;rdquo; / And you may tell yourself, &amp;ldquo;This is not my beautiful house&amp;rdquo; / And you may tell yourself, &amp;ldquo;This is not my beautiful wife&amp;rdquo;&amp;nbsp;&lt;a href="#2025-12-04-literals-and-constants-in-common-lisp-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-12-04-literals-and-constants-in-common-lisp-footnote-3-definition" class="footnote-definition"&gt;
   &lt;p&gt;Here&amp;rsquo;s something that staryed as a mail message which tries to explain this in some more detail. In the case of variables &lt;code&gt;defconstant&lt;/code&gt; is required to tell &lt;code&gt;constantp&lt;/code&gt; that a variable is a constant at compile-time but is not required (and should not be required) to evaluate the initform, let alone actually establish a binding at that time. In SBCL it does both (SBCL doesn&amp;rsquo;t really have a compilation environment). In LW, say, it at least does not establish a binding, because LW does have a compilation environment. That means that in LW compiling a file has fewer compile-time side-effects than it does in SBCL. Outside of variables, it&amp;rsquo;s easily possible that a compiler might be smart enough to know that, given &lt;code&gt;(defun c (n) (+ n 15))&lt;/code&gt;, then &lt;code&gt;(constantp '(c 1) &amp;lt;compilation environment&amp;gt;)&lt;/code&gt; is true. But you can&amp;rsquo;t evaluate &lt;code&gt;(c 1)&lt;/code&gt; at compile-time at all. &lt;code&gt;constantp&lt;/code&gt; tells you that you don&amp;rsquo;t need to bind variables to prevent multiple evaluation, it doesn&amp;rsquo;t, and can&amp;rsquo;t, tell you what their values will be.&amp;nbsp;&lt;a href="#2025-12-04-literals-and-constants-in-common-lisp-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-12-04-literals-and-constants-in-common-lisp-footnote-4-definition" class="footnote-definition"&gt;
   &lt;p&gt;Part of the &lt;code&gt;org.tfeb.star/utilities&lt;/code&gt; package.&amp;nbsp;&lt;a href="#2025-12-04-literals-and-constants-in-common-lisp-footnote-4-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">A timing macro for Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2025/11/27/a-timing-macro-for-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2025-11-27-a-timing-macro-for-common-lisp</id>
  <published>2025-11-27T11:50:16Z</published>
  <updated>2025-11-27T11:50:16Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;For a long time I&amp;rsquo;ve used a little macro to time chunks of code to avoid an endless succession of boilerplate functions to do this. I&amp;rsquo;ve finally published the wretched thing.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;If you&amp;rsquo;re writing programs where you care about performance, you often want to be able to make programatic comparisons of performance. &lt;code&gt;time&lt;/code&gt; doesn&amp;rsquo;t do this, since it just reports things. Instead you want something that runs a bit of code a bunch of times and then returns the average time, with &amp;lsquo;a bunch of times&amp;rsquo; being controllable. &lt;code&gt;timing&lt;/code&gt; is that macro. Here is a simple example:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun dotimes/in-naturals-ratio (&amp;amp;key (iters 10000000) (tries 1000))
  (declare (type fixnum iters)
           (optimize speed))
  (/
   (timing (:n tries)
     (let ((s 0))                       ;avoid optimizing loop away
       (declare (type fixnum s))
       (dotimes (i iters s)
         (incf s))))
   (timing (:n tries)
     (let ((s 0))
       (declare (type fixnum s))
       (for ((_ (in-naturals iters t)))
         (incf s))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and then, for instance&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (dotimes/in-naturals-ratio)
1.0073159&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All &lt;code&gt;timing&lt;/code&gt; does is to wrap up its body into a function and then call a function which calls this function the number of times you specify and averages the time, returning that average as a float.&lt;/p&gt;

&lt;p&gt;There are some options which let it print a progress note every given number of calls, wrap a call to &lt;code&gt;time&lt;/code&gt; around things so you get, for instance, GC reporting, and subtract away the same number of calls to an empty function to try and account for overhead (in practice this is not very useful).&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s all it is. It&amp;rsquo;s available in version 10 of my Lisp tools:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;documentation &lt;a href="https://tfeb.org/fragments/documentation/tfeb-lisp-tools.html"&gt;here&lt;/a&gt;;&lt;/li&gt;
 &lt;li&gt;git repo &lt;a href="https://tfeb.org/computer/repos/tfeb-lisp-tools.git"&gt;here&lt;/a&gt;;&lt;/li&gt;
 &lt;li&gt;tarball &lt;a href="https://tfeb.org/computer/tarballs/tfeb-lisp-tools.tar.gz"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;</content></entry>
 <entry>
  <title type="text">The lost cause of the Lisp machines</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2025/11/18/the-lost-cause-of-the-lisp-machines/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2025-11-18-the-lost-cause-of-the-lisp-machines</id>
  <published>2025-11-18T08:52:44Z</published>
  <updated>2025-11-18T08:52:44Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;I am just really bored by Lisp Machine romantics at this point: they should go away. I expect they never will.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="history"&gt;History&lt;/h2&gt;

&lt;p&gt;Symbolics &lt;a href="https://www.latimes.com/archives/la-xpm-1993-02-02-fi-1060-story.html" title="Symbolics Inc. Seeks Chapter 11 Protection"&gt;went bankrupt in early 1993&lt;/a&gt;. In the way of these things various remnants of the company lingered on for, in this case, decades. But 1983 was when the Lisp Machines died.&lt;/p&gt;

&lt;p&gt;The death was not unexpected: by the time I started using mainstream Lisps in 1989&lt;sup&gt;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-1-definition" name="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt; everyone knew that special hardware for Lisp was a dead idea. The common idea was that the arrival of RISC machines had killed it, but in fact machines like the Sun 3/260 in its &amp;lsquo;AI&amp;rsquo; configuration&lt;sup&gt;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-2-definition" name="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt; were already hammering nails in its coffin. In 1987 I read a report showing the Lisp performance of an early RISC machine, using &lt;a href="https://en.wikipedia.org/wiki/Kyoto_Common_Lisp" title="Kyoto Common Lisp"&gt;Kyoto Common Lisp&lt;/a&gt;, not a famously fast implementation of CL, beating a Symbolics on &lt;a href="https://www.dreamsongs.com/Files/Timrep.pdf" title="Performance and evaluation of Lisp systems"&gt;the Gabriel benchmarks&lt;/a&gt; [PDF link].&lt;/p&gt;

&lt;p&gt;1993 is 32 years ago. The Symbolics 3600, probably the first Lisp machine that sold in more than tiny numbers, was introduced in 1983, ten years earlier. People who used Lisp machines other than as historical artefacts are old today&lt;sup&gt;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-3-definition" name="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Lisp machines were both widely available and offered the best performance for Lisp for a period of about five years which ended nearly forty years ago. They were probably never competitive in terms of performance for the money.&lt;/p&gt;

&lt;p&gt;It is time, and long past time, to let them go.&lt;/p&gt;

&lt;p&gt;But still the romantics &amp;mdash; some of them even old enough to remember the Lisp machines &amp;mdash; repeat their myths.&lt;/p&gt;

&lt;h2 id="it-was-the-development-environment"&gt;&amp;lsquo;It was the development environment&amp;rsquo;&lt;/h2&gt;

&lt;p&gt;No, it wasn&amp;rsquo;t.&lt;/p&gt;

&lt;p&gt;The development environments offered by both families of Lisp machines were seriously cool, at least for the 1980s. I mean, they really were very cool indeed. Some of the ways they were cool matter today, but some don&amp;rsquo;t. For instance in the 1980s and early 1990s Lisp images were very large compared to available memory, and machines were also extremely slow in general. So good Lisp development environents did a lot of work to hide this slowness, and in general making sure you only very seldom had to restart everthing, which took significant fractions of an hour, if not more. None of that matters today, because machines are so quick and Lisps so relatively small.&lt;/p&gt;

&lt;p&gt;But that&amp;rsquo;s not the only way they were cool. They really were just lovely things to use in many ways. But, despite what people might believe: &lt;em&gt;this did not depend on the hardware&lt;/em&gt;: there is no reason at all why a development environent that cool could not be built on stock hardware. Perhaps, (perhaps) that was not true in 1990: it is certainly true today.&lt;/p&gt;

&lt;p&gt;So if a really cool Lisp development environment doesn&amp;rsquo;t exist today, it is nothing to do with Lisp machines not existing. In fact, as someone who used Lisp machines, I find the LispWorks development environment at least as comfortable and productive as they were. But, oh no, the full-fat version is not free, and no version is open source. Neither, I remind you, were they.&lt;/p&gt;

&lt;h2 id="they-were-much-faster-than-anything-else"&gt;&amp;lsquo;They were much faster than anything else&amp;rsquo;&lt;/h2&gt;

&lt;p&gt;No, &lt;a href="#history" title="History"&gt;they weren&amp;rsquo;t&lt;/a&gt;. Please, stop with that.&lt;/p&gt;

&lt;h2 id="the-hardware-was-user-microcodable-you-see"&gt;&amp;lsquo;The hardware was user-microcodable, you see&amp;rsquo;&lt;/h2&gt;

&lt;p&gt;Please, stop telling me things about &lt;em&gt;machines I used&lt;/em&gt;: believe it or not, I know those things.&lt;/p&gt;

&lt;p&gt;Many machines were user-microcodable before about 1990. That meant that, technically, a user of the machine could implement their own instruction set. I am sure there are cases where people even did that, and a much smaller number of cases where doing that was not just a waste of time.&lt;/p&gt;

&lt;p&gt;But in almost all cases the only people who wrote microcode were the people who built the machine. And the reason they wrote microcode was because it is the easiest way of implementing a very complex instruction set, especially when you can&amp;rsquo;t use vast numbers of transistors. For instance if you&amp;rsquo;re going to provide an &amp;lsquo;add&amp;rsquo; instruction which will add numbers of any type, trapping back into user code for some cases, then by far the easiest way of doing that is going to be by writing code, not building hardware. And that&amp;rsquo;s what the Lisp machines did.&lt;/p&gt;

&lt;p&gt;Of course, the compiler could have generated that code for hardware without that instruction. But with the special instruction the compiler&amp;rsquo;s job is much easier, and code is smaller. A small, quick compiler and small compiled code were very important with slow machines which had tiny amounts of memory. Of course a compiler not made of wet string could have used type information to &lt;em&gt;avoid&lt;/em&gt; generating the full dispatch case, but wet string was all that was available.&lt;/p&gt;

&lt;p&gt;What microcodable machines almost never meant was that users of the machines would write microcode.&lt;/p&gt;

&lt;p&gt;At the time, the tradeoffs made by Lisp machines might even have been reasonable. CISC machines in general were probably good compromises given the expense of memory and how rudimentary compilers were: I can remember being horrified at the size of compiled code for RISC machines. But I was horrified because I wasn&amp;rsquo;t thinking about it properly. Moore&amp;rsquo;s law was very much in effect in about 1990 and, among other things, it meant that the amount of memory you could afford was rising exponentially with time: the RISC people understood that.&lt;/p&gt;

&lt;h2 id="they-were-lisp-all-the-way-down"&gt;&amp;lsquo;They were Lisp all the way down&amp;rsquo;&lt;/h2&gt;

&lt;p&gt;This, finally, maybe, is a good point. They were, and you could dig around and change things on the fly, and this was pretty cool. Sometimes you could even replicate the things you&amp;rsquo;d done later. I remember playing with sound on a 3645 which was really only possible because you could get low-level access to the disk from Lisp, as the disk could just marginally provide data fast enough to stream sound.&lt;/p&gt;

&lt;p&gt;On the other hand they had no isolation and thus no security at all: people didn&amp;rsquo;t care about that in 1985, but if I was using a Lisp-based machine today I would certainly be unhappy if my web browser could modify my device drivers on the fly, or poke and peek at network buffers. A machine that was Lisp all the way down today would need to ensure that things like that couldn&amp;rsquo;t happen.&lt;/p&gt;

&lt;p&gt;So may be it would be Lisp all the way down, but you absolutely would not have the kind of ability to poke around in and redefine parts of the guts you had on Lisp machines. Maybe that&amp;rsquo;s still worth it.&lt;/p&gt;

&lt;p&gt;Not to mention that I&amp;rsquo;m just not very interested in spending a huge amount of time grovelling around in the guts of something like an SSL implementation: those things exist already, and I&amp;rsquo;d rather do something new and cool. I&amp;rsquo;d rather do something that Lisp is uniquely suited for, not reinvent wheels. Well, may be that&amp;rsquo;s just me.&lt;/p&gt;

&lt;p&gt;Machines which were Lisp all the way down might, indeed, be interesting, although they could not look like 1980s Lisp machines if they were to be safe. But that does not mean they would need special hardware for Lisp: they wouldn&amp;rsquo;t. If you want something like this, hardware is not holding you back: there&amp;rsquo;s no need to endlessly mourn the lost age of Lisp machines, you can start making one now. Shut up and code.&lt;/p&gt;

&lt;p&gt;And now we come to the really strange arguments, the arguments that we need special Lisp machines either for reasons which turn out to be straightforwardly false, or because we need something that Lisp machines &lt;em&gt;never were&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id="good-lisp-compilers-are-too-hard-to-write-for-stock-hardware"&gt;&amp;lsquo;Good Lisp compilers are too hard to write for stock hardware&amp;rsquo;&lt;/h2&gt;

&lt;p&gt;This mantra is getting old.&lt;/p&gt;

&lt;p&gt;The most important thing is that &lt;em&gt;we have good stock-hardware Lisp compilers today&lt;/em&gt;. As an example, today&amp;rsquo;s CL compilers are not far from CLANG/LLVM for floating-point code. I tested SBCL and LispWorks: it would be interesting to know how many times more work has gone into LLVM than them for such a relatively small improvement. I can&amp;rsquo;t imagine a world where these two CL compilers would not be at least comparable to LLVM if similar effort was spent on them&lt;sup&gt;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-4-definition" name="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-4-return"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;These things are so much better than the wet-cardboard-and-string compilers that the LispMs had it&amp;rsquo;s not funny. In particular, if some mythical &amp;lsquo;dedicated Lisp hardware&amp;rsquo; made it possible to write a Lisp compiler which generated significantly faster code, then &lt;em&gt;code from Lisp compilers would comprehensively outperform C and Fortran compilers&lt;/em&gt;: does that seem plausible? I thought not.&lt;/p&gt;

&lt;p&gt;A large amount of work is also going into compilation for other dynamically-typed, interactive languages which aim at high performance. That means on-the-fly compilation and recompilation of code where both the compilation and the resulting code must be quick. Example: &lt;a href="https://julialang.org/" title="Julia"&gt;Julia&lt;/a&gt;. Any of that development could be reused by Lisp compiler writers if they needed to or wanted to (I don&amp;rsquo;t know if they do, or should).&lt;/p&gt;

&lt;p&gt;Ah, but then it turns out that that&amp;rsquo;s not what is meant by a &amp;lsquo;good compiler&amp;rsquo; after all. It turns out that &amp;lsquo;good&amp;rsquo; means &amp;lsquo;compillation is fast&amp;rsquo;.&lt;/p&gt;

&lt;p&gt;All these compilers are pretty quick: the computational resources used by even a pretty hairy compiler have not scaled anything like as fast as those needed for the problems we want to solve (that&amp;rsquo;s why Julia can use LLVM on the fly). Compilation is also not an Amdahl bottleneck as it can happen on the node that needs the compiled code.&lt;/p&gt;

&lt;p&gt;Compilers are so quick that a widely-used CL implementation exists where EVAL uses the compiler, unless you ask it not to.&lt;/p&gt;

&lt;p&gt;Compilation options are also a thing: you can ask compilers to be quick, fussy, sloppy, safe, produce fast code and so on. Some radically modern languages also allow this to be done in a standardised (but extensible) way at the language level, so you can say &amp;lsquo;make this inner loop really quick, and I have checked all the bounds so don&amp;rsquo;t bother with that&amp;rsquo;.&lt;/p&gt;

&lt;p&gt;The tradeoff between a fast Lisp compiler and a really good Lisp compiler is imaginary, at this point.&lt;/p&gt;

&lt;h2 id="they-had-wonderful-keyboards"&gt;&amp;lsquo;They had wonderful keyboards&amp;rsquo;&lt;/h2&gt;

&lt;p&gt;Well, if you didn&amp;rsquo;t mind the weird layouts: yes, they did&lt;sup&gt;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-5-definition" name="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-5-return"&gt;5&lt;/a&gt;&lt;/sup&gt;. And has &lt;em&gt;exactly nothing&lt;/em&gt; to do with Lisp.&lt;/p&gt;

&lt;p&gt;And so it goes on.&lt;/p&gt;

&lt;h2 id="bored-now"&gt;Bored now&lt;/h2&gt;

&lt;p&gt;There&amp;rsquo;s a well-known syndrome amongst photographers and musicians called GAS: gear acquisition syndrome. Sufferers from this&lt;sup&gt;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-6-definition" name="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-6-return"&gt;6&lt;/a&gt;&lt;/sup&gt; pursue an endless stream of purchases of gear &amp;mdash; cameras, guitars, FX pedals, the last long-expired batch of a legendary printing paper &amp;mdash; in the strange hope that the next camera, the next pedal, that paper, will bring out the Don McCullin, Jimmy Page or Chris Killip in them. Because, of course, Don McCullin &amp;amp; Chris Killip only took the pictures they did because he had the right cameras: it was nothing to do with talent, practice or courage, no.&lt;/p&gt;

&lt;p&gt;GAS is a lie we tell ourselves to avoid the awkward reality that what we actually need to do is &lt;em&gt;practice&lt;/em&gt;, a lot, and that even if we did that we might not actually be very talented.&lt;/p&gt;

&lt;p&gt;Lisp machine romanticism is the same thing: a wall we build ourself so that, somehow unable to climb over it or knock it down, we never have to face the fact that the only thing stopping us is us.&lt;/p&gt;

&lt;p&gt;There is no purpose to arguing with Lisp machine romantics because they will never accept that the person building the endless barriers in their way is the same person they see in the mirror every morning. They&amp;rsquo;re too busy building the walls.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;As a footnote, I went to a talk by an HPC person in the early 90s (so: after the end of the cold war&lt;sup&gt;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-7-definition" name="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-7-return"&gt;7&lt;/a&gt;&lt;/sup&gt; and when the HPC money had gone) where they said that HPC people needed to be aiming at machines based on what big commercial systems looked like as nobody was going to fund dedicated HPC designs any more. At the time that meant big cache-coherent SMP systems. Those hit their limits and have really died out now: the bank I worked for had dozens of fully-populated big SMP systems in 2007, it perhaps still has one or two they can&amp;rsquo;t get rid of because of some legacy application. So HPC people now run on enormous shared-nothing farms of close-to-commodity processors with very fat interconnect and are wondering about / using GPUs. That&amp;rsquo;s similar to what happened to Lisp systems, of course: perhaps, in the HPC world, there are romantics who mourn the lost glories of the Cray&amp;ndash;3. Well, if I was giving a talk to people interested in the possibilities of hardware today I&amp;rsquo;d be saying that in a few years there are going to be a &lt;em&gt;lot&lt;/em&gt; of huge farms of GPUs going very cheap if you can afford the power. People could be looking at whether those can be used for anything more interesting than the huge neural networks they were designed for. I don&amp;rsquo;t know if they can.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;Before that I had read about Common Lisp but actually written programs in Cambridge Lisp and Standard Lisp.&amp;nbsp;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;This had a lot of memory and a higher-resolution screen, I think, and probably was bundled with a rebadged Lucid Common Lisp.&amp;nbsp;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-3-definition" class="footnote-definition"&gt;
   &lt;p&gt;I am at the younger end of people who used these machines in anger: I was not there for the early part of the history described here, and I was also not in the right part of the world at a time when that mattered more. But I wrote Lisp from about 1985 and used Lisp machines of both families from 1989 until the mid to late 1990s. I know from first-hand experience what these machines were like.&amp;nbsp;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-4-definition" class="footnote-definition"&gt;
   &lt;p&gt;If anyone has good knowledge of Arm64 (specifically Apple M1) assembler and performance, and the patience to pore over a couple of assembler listings and work out performance differences, please get in touch. I have written most of a document exploring the difference in performance, but I lost the will to live at the point where it came down to understanding just what details made the LLVM code faster. All the compilers seem to do a good job of the actual float code, but perhaps things like array access or loop overhead are a little slower in Lisp. The difference between SBCL &amp;amp; LLVM is a factor of under 1.2.&amp;nbsp;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-4-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-5-definition" class="footnote-definition"&gt;
   &lt;p&gt;The Sun type 3 keyboard was both wonderful and did not have a weird layout, so there&amp;rsquo;s that.&amp;nbsp;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-5-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-6-definition" class="footnote-definition"&gt;
   &lt;p&gt;I am one: I know what I&amp;rsquo;m talking about here.&amp;nbsp;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-6-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-7-definition" class="footnote-definition"&gt;
   &lt;p&gt;The cold war did not end in 1991. America did not win.&amp;nbsp;&lt;a href="#2025-11-18-the-lost-cause-of-the-lisp-machines-footnote-7-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Disentangling iteration from value accumulation</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2025/10/31/disentangling-iteration-from-value-accumulation/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2025-10-31-disentangling-iteration-from-value-accumulation</id>
  <published>2025-10-31T12:40:33Z</published>
  <updated>2025-10-31T12:40:33Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Iteration forms and forms which accumulate values don&amp;rsquo;t have to be the same thing. I think that it turns out that separating them works rather well.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;There&amp;rsquo;s no one true way to write programs, especially in Lisp&lt;sup&gt;&lt;a href="#2025-10-31-disentangling-iteration-from-value-accumulation-footnote-1-definition" name="2025-10-31-disentangling-iteration-from-value-accumulation-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;: a language whose defining feature is that it supports and encourages the seamless construction of new programming languages&lt;sup&gt;&lt;a href="#2025-10-31-disentangling-iteration-from-value-accumulation-footnote-2-definition" name="2025-10-31-disentangling-iteration-from-value-accumulation-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;. In particular there are plenty of different approaches to iteration, and to accumulating values during iteration. In CL there are at least three approaches in the base language:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;constructs which map a function over some &amp;lsquo;iterable&amp;rsquo; object, often a list or a sequence of some other kind, to build another object with the results, as by &lt;code&gt;mapcar&lt;/code&gt; for instance;&lt;/li&gt;
 &lt;li&gt;constructs which just iterate, as by &lt;code&gt;dotimes&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;iteration constructs which combine iteration with possible value accumulation, such as &lt;code&gt;do&lt;/code&gt; and of course &lt;code&gt;loop&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;What CL &lt;em&gt;doesn&amp;rsquo;t&lt;/em&gt; have is any constructs which simply accumulate values. So, for instance, if you wanted to acquire the even numbers from a list with &lt;code&gt;dolist&lt;/code&gt; you might write&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((evens '()))
  (dolist (e l (nreverse evens))
    (when (and (realp e) (evenp e))
      (push e evens))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of course you could do this with &lt;code&gt;loop&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(loop for e in l
      when (and (realp e) (evenp e)) collect e)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;but &lt;code&gt;loop&lt;/code&gt; is a construct which combines iteration and value collection.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s tempting to say that, well, can&amp;rsquo;t you turn &lt;em&gt;all&lt;/em&gt; iteration into mapping? Python sort of does this: objects can be &amp;lsquo;iterable&amp;rsquo;, and you can iterate over anything iterable, and then comprehensions let you accumulate values. But in general this doesn&amp;rsquo;t work very well: consider a file which you want to iterate over. But &lt;em&gt;how&lt;/em&gt;? Do you want to iterate over its characters, its bytes, its lines, its words, over some other construct in the file? You can&amp;rsquo;t just say &amp;lsquo;a file is iterable&amp;rsquo;: it is, but you have to specify the intent before iterating over it&lt;sup&gt;&lt;a href="#2025-10-31-disentangling-iteration-from-value-accumulation-footnote-3-definition" name="2025-10-31-disentangling-iteration-from-value-accumulation-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt;. You also have the problem that you very often only want to return &lt;em&gt;some&lt;/em&gt; values, so the notion of &amp;lsquo;mapping&amp;rsquo; is not very helpful. If you try and make everything be mapping you end up with ugly things like &lt;code&gt;mapcan&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You do need general iteration constructs, I think: constructs which say &amp;lsquo;is there more? if there is give me the next thing&amp;rsquo;. In CL both the standard general iteration constructs combine, or can combine, iteration with accumulation: there is no pure general iteration construct. And there are no pure value accumulation constructs at all.&lt;/p&gt;

&lt;h2 id="from-maclisp-to-cl"&gt;From Maclisp to CL&lt;/h2&gt;

&lt;p&gt;An interesting thing happened in the transition from Maclisp to CL.&lt;/p&gt;

&lt;p&gt;Maclisp had &lt;a href="https://www.maclisp.info/pitmanual/contro.html#5.9.1"&gt;&lt;code&gt;prog&lt;/code&gt;&lt;/a&gt;, which was a special operator (it would have called it a special form), and which combined the ability to use &lt;code&gt;go&lt;/code&gt; and to say &lt;code&gt;return&lt;/code&gt;. This is a construct which dates back to the very early days of Lisp.&lt;/p&gt;

&lt;p&gt;Common Lisp also has &lt;a href="https://www.lispworks.com/documentation/HyperSpec/Body/m_prog_.htm" title="prog"&gt;&lt;code&gt;prog&lt;/code&gt;&lt;/a&gt;, but now it&amp;rsquo;s a macro, not a special operator. The reason its a macro is that CL has split the functionality of &lt;code&gt;prog&lt;/code&gt; into three parts (four parts if you include variable binding):&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://www.lispworks.com/documentation/HyperSpec/Body/s_progn.htm" title="progn"&gt;&lt;code&gt;progn&lt;/code&gt;&lt;/a&gt; is a special operator which evaluates the forms in its body in order;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://www.lispworks.com/documentation/HyperSpec/Body/s_tagbod.htm" title="tagbody"&gt;&lt;code&gt;tagbody&lt;/code&gt;&lt;/a&gt; is a special operator whch allows tags and &lt;code&gt;go&lt;/code&gt; in its body;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://www.lispworks.com/documentation/HyperSpec/Body/s_block.htm" title="block"&gt;&lt;code&gt;block&lt;/code&gt;&lt;/a&gt; is a special operator which supports &lt;code&gt;return&lt;/code&gt; and &lt;code&gt;return-from&lt;/code&gt;&lt;/li&gt;
 &lt;li&gt;and of course &lt;a href="https://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm" title="let"&gt;&lt;code&gt;let&lt;/code&gt;&lt;/a&gt; provides binding of variables.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Maclisp had &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;progn&lt;/code&gt;: what it &lt;em&gt;didn&amp;rsquo;t&lt;/em&gt; have was &lt;code&gt;tagbody&lt;/code&gt; and &lt;code&gt;block&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These can be combined (you don&amp;rsquo;t in fact need &lt;code&gt;progn&lt;/code&gt; in this case) to form &lt;code&gt;prog&lt;/code&gt;, which is something like&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro prog ((&amp;amp;rest bindings)
                &amp;amp;body tags/forms)
  `(block nil
     (let ,@bindings
       (tagbody
        ,@tags/forms)
       nil)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So what CL has done is to divide &lt;code&gt;prog&lt;/code&gt; into its component parts, which then can be used individually in other ways: it has provided the components of &lt;code&gt;prog&lt;/code&gt; as individual constructs. You can build &lt;code&gt;prog&lt;/code&gt; from these, but you can build other things as well (&lt;code&gt;defun&lt;/code&gt; expands to something involving &lt;code&gt;block&lt;/code&gt;, for instance), including things which don&amp;rsquo;t exist in base CL.&lt;/p&gt;

&lt;h2 id="a-linguistic-separation-of-concerns"&gt;A linguistic separation of concerns&lt;/h2&gt;

&lt;p&gt;What CL has achieved is a &lt;em&gt;separation of concerns&lt;/em&gt; at the language level: it has reduced the number of concerns addressed by each construct. It hasn&amp;rsquo;t done this completely: &lt;code&gt;progn&lt;/code&gt; is not the only special operator which sequences the forms in its body, for instance, and &lt;code&gt;let&lt;/code&gt; is not a macro defined in terms of &lt;code&gt;lambda&lt;/code&gt;. But it&amp;rsquo;s taken steps in this direction compared to Maclisp.&lt;/p&gt;

&lt;p&gt;This approach is really only viable for languages which have powerful macro systems where macros are not syntactically distinguished. Without a macro system then separating concerns at the language level would make almost all programs more verbose since constructs which combine lower-level ones can&amp;rsquo;t be created. With a macro system where macros are syntactically distinguished, such as Julia&amp;rsquo;s, then such constructs are always second-class citizens. With a macro system like CL&amp;rsquo;s this is no longer a problem: CL has &lt;code&gt;prog&lt;/code&gt;, for instance, but it&amp;rsquo;s now a macro.&lt;/p&gt;

&lt;p&gt;It seems to me that the only reason &lt;em&gt;not&lt;/em&gt; to take this process as far as it can go in Lisps is if it makes the compiler&amp;rsquo;s job unduly hard. It makes no difference to users of the language, so long as it provides, as CL does the old, unseparated, convenient constructs.&lt;/p&gt;

&lt;h2 id="from-cl-to-here-knows-when"&gt;From CL to here knows when&lt;/h2&gt;

&lt;p&gt;I can&amp;rsquo;t redesign CL and don&amp;rsquo;t want to do that. But I can experiment with building a language I&amp;rsquo;d like to use on top of it.&lt;/p&gt;

&lt;p&gt;In particular CL has already provided the separated constructs you need to build your own iteration constructs, and no CL iteration constructs are special operators. Just as &lt;code&gt;do&lt;/code&gt; is constructed from (perhaps) &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;block&lt;/code&gt; and &lt;code&gt;tagbody&lt;/code&gt;, and &lt;code&gt;loop&lt;/code&gt; is constructed from some horrid soup if the same things, you can build your own iteration constructs this way. And the same is true for value accumulation constructs. And you can reasonably expect these to perform as well as the ones in the base language.&lt;/p&gt;

&lt;p&gt;This is what I&amp;rsquo;ve done, several times in fact.&lt;/p&gt;

&lt;p&gt;The first thing I built, long ago, was a list accumulation construct called &lt;code&gt;collecting&lt;/code&gt;: within its body there is a local function, &lt;code&gt;collect&lt;/code&gt;, which will accumulate a value onto the list returned from &lt;code&gt;collecting&lt;/code&gt;. It secretly maintains a tail-pointer to the list so accumulation is constant-time. This was originally built to make it simpler to accumulate values when traversing tree or graph structures, to avoid the horrid and, in those days, slow explicit &lt;code&gt;push&lt;/code&gt; &amp;hellip; &lt;code&gt;nreverse&lt;/code&gt; idiom.&lt;/p&gt;

&lt;p&gt;So, for instance&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(collecting
  (labels ((walk (node)
             ...
             (when ... (collect thing))
             ...
             (dolist (...) (walk ...))))
    (walk ...)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;might walk over some structure, collecting interesting things, and returning a list of them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tfeb.org/fragments/documentation/tfeb-lisp-hax.html#collecting-lists-forwards-and-accumulating-collecting" title="Collecting"&gt;&lt;code&gt;collecting&lt;/code&gt;&lt;/a&gt; was originally based on some ideas in Interlisp-D, and has since metastasized into a, well, collection of related constructs: multiple named collectors (&lt;code&gt;collecting&lt;/code&gt; itself is now defined in terms of this construct), explicit collector objects, general accumulators and most recently a construct which accumulates values into vectors. It works pretty well.&lt;/p&gt;

&lt;p&gt;The second part of the story is high-performance iteration constructs which just iterate, which are general, which are pleasant to use and have semantics which are easy to understand. Both &lt;code&gt;loop&lt;/code&gt;and &lt;code&gt;do&lt;/code&gt; fail the first three of these conditions for me, and &lt;code&gt;loop&lt;/code&gt; fails the fourth as well.&lt;/p&gt;

&lt;p&gt;Well, I&amp;rsquo;ve written a number of iteration constructs and constructs related to iteration. Finally, last year, my friend Zyni &amp;amp; I (the ideas are largely hers, I wrote most of the code I think) came up with &lt;a href="https://tfeb.org/fragments/documentation/star.html" title="Štar"&gt;Štar&lt;/a&gt; which we&amp;rsquo;ve described as &amp;lsquo;a simple and extensible iteration construct&amp;rsquo;. Lots of other people have written iteration constructs for CL: Štar occupies a position which tries to be as extreme as possible while remaining pleasant to use. There are no special keywords, the syntax is pretty much that of &lt;code class="brush: ^4"&gt;let&lt;/code&gt; and there is no value accumulation: all it does is iterate. The core of Štar exports six names, of which the three that support nested iteration are arguably unneeded in the same way that &lt;code&gt;let*&lt;/code&gt; is. Teaching it how to iterate over things is simple, teaching it how to optimize such iterations is usually simple enough to do when it&amp;rsquo;s worth it. And it&amp;rsquo;s within $\varepsilon$ of anything in terms of performance.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s simple (at least in interface) and quick because it hardly does anything, of course: it relies entirely on iterators to do anything at all and iterator optimizers to do anything quickly. Even then all it does is, well, iterate.&lt;/p&gt;

&lt;p&gt;These two components are thus attempts at separating the two parts of something like &lt;code&gt;loop&lt;/code&gt;, &lt;a href="https://iterate.common-lisp.dev" title="Iterate"&gt;Iterate&lt;/a&gt; or &lt;a href="https://github.com/Shinmera/for" title="For"&gt;For&lt;/a&gt;, or other constructs which combine iteration and value accumulation: they are to these constructs what &lt;code&gt;tagbody&lt;/code&gt; and &lt;code&gt;block&lt;/code&gt; are to &lt;code&gt;prog&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="reinventing-the-wheel"&gt;Reinventing the wheel&lt;/h2&gt;

&lt;p&gt;I used to ride bicycles a lot. And I got interested in the surprisingly non-obvious way that bicycle wheels work. After reading &lt;a href="https://en.wikipedia.org/wiki/The_Bicycle_Wheel" title="The bicycle wheel"&gt;&lt;em&gt;The bicycle wheel&lt;/em&gt;&lt;/a&gt; I decided that I could make wheels, and I did do that.&lt;/p&gt;

&lt;p&gt;And a strange thing happened: although I rationally understood that the wheels I had made were as good or better than any other wheel, for the first little while after building them I was terrified that they would bend or, worse, collapse. There was no rational reason for this: it was just that for some reason I trusted my own workmanship less than I trusted whoever had made the off-the-shelf wheels they&amp;rsquo;d replaced (and, indeed, some of whose parts I had cannibalised to make them).&lt;/p&gt;

&lt;p&gt;Of course they didn&amp;rsquo;t bend or collapse, and I still rode on one of them until quite recently.&lt;/p&gt;

&lt;p&gt;The same thing happened with Štar: for quite a while after finishing it I had to work hard to force myself to use it: even though I knew it was fast and robust. It wasn&amp;rsquo;t helped that one of the basic early iterators was overcomplex and had somewhat fragile performance. It wasn&amp;rsquo;t until I gave up on it and replaced it by a much simpler and more limited one, while also making a much more general iterator fast enough to use for the complicated cases that it felt comfortable.&lt;/p&gt;

&lt;p&gt;This didn&amp;rsquo;t happen with &lt;code&gt;collecting&lt;/code&gt;: I think that&amp;rsquo;s because it did something CL didn&amp;rsquo;t already have versions of, while it&amp;rsquo;s very often possible to replace a construct using Štar with some nasty thing involving &lt;code&gt;do&lt;/code&gt; or some other iteration construct. Also Štar is much bigger than &lt;code&gt;collecting&lt;/code&gt; and it&amp;rsquo;s hard to remember that I&amp;rsquo;m not using a machine with a few MB of memory any more. Perhaps it&amp;rsquo;s also because I first wrote &lt;code&gt;collecting&lt;/code&gt; a very long time ago.&lt;/p&gt;

&lt;p&gt;But I got over this, and now almost the only times I&amp;rsquo;d use any other iteration construct are either when &lt;code&gt;mapcar&lt;/code&gt; &amp;amp;c are obviously right, or when I&amp;rsquo;m writing code for someone else to look at.&lt;/p&gt;

&lt;p&gt;And writing iterators is easy, especially given that you very often do not need optimizers for them: if you&amp;rsquo;re iterating over the lines in a file two function calls per line is not hurting much. Iterators, of course, can also iterate over recursively-defined structures such as trees or DAGs: it&amp;rsquo;s easy to say &lt;code&gt;(for ((leaf (in-graph ... :only-leaves t))) ...)&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="would-it-help"&gt;Would it help?&lt;/h2&gt;

&lt;p&gt;In my biased experience, yes, quite a lot. I now much prefer writing and reading code that uses &lt;code&gt;for&lt;/code&gt; to code that uses almost any of the standard iteration constructs, and &lt;code&gt;collecting&lt;/code&gt;, together with its friends, simply does not have a standard equivalent at all: if you don&amp;rsquo;t have it, you need either to write it, or implement it explicitly each time.&lt;/p&gt;

&lt;p&gt;But my experience is very biased: I have hated &lt;code&gt;loop&lt;/code&gt; almost since it arrived in CL, and I find using &lt;code&gt;do&lt;/code&gt; for anything non-trivial clumsy enough that I&amp;rsquo;ve previously written &lt;a href="https://tfeb.org/fragments/documentation/tfeb-lisp-hax.html#decomposing-iteration-simple-loops" title="Simple loops"&gt;versions of it which require less repetition&lt;/a&gt;. And of course I was quite involved in the design and implementation of Štar, so it&amp;rsquo;s not surprising that I like it.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m also &lt;a href="https://tfeb.org/fragments/2022/10/03/bradshaw-s-laws/" title="Bradshaw's laws"&gt;very comfortable&lt;/a&gt; with the idea that Lisp is about language design &amp;mdash; in 2025 I don&amp;rsquo;t see any compelling advantage of Lisp &lt;em&gt;other&lt;/em&gt; than constructing languages &amp;mdash; and that people who write Lisp end up writing in their own idiolects. The argument against doing this seems to be that every Lisp project ends up being its own language and this means that it is hard to recruit people. I can only assume that the people who say that have never worked on any large system written in languages other than Lisp&lt;sup&gt;&lt;a href="#2025-10-31-disentangling-iteration-from-value-accumulation-footnote-4-definition" name="2025-10-31-disentangling-iteration-from-value-accumulation-footnote-4-return"&gt;4&lt;/a&gt;&lt;/sup&gt;: &lt;a href="https://en.wikipedia.org/wiki/Greenspun's_tenth_rule" title="Greenspun's tenth rule"&gt;Greenspun&amp;rsquo;s tenth rule&lt;/a&gt; very much applies to these systems.&lt;/p&gt;

&lt;p&gt;In summary: yes, it would help.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id="an-example"&gt;An example&lt;/h2&gt;

&lt;p&gt;In the examples directory for Štar there is an iterator called &lt;code&gt;in-graph&lt;/code&gt; which can iterate over any graph, if it knows how to find the neighbours of a node. For instance:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (for ((n (in-graph (list '(a b (c b) d))
                     (lambda (n)
                       (if (atom n) '() (cdr n))))))
    (print n))

(a b (c b) d) 
b 
(c b) 
b 
d 
nil

&amp;gt; (for ((n (in-graph (list '(a b (c b) d))
                     (lambda (n)
                       (if (atom n) '() (cdr n)))
                     :unique t)))
    (print n))

(a b (c b) d) 
b 
(c b) 
d 
nil

&amp;gt; (for ((n (in-graph (list '(a b (c b) d))
                     (lambda (n)
                       (if (atom n) '() (cdr n)))
                     :order :breadth-first)))
    (print n))

(a b (c b) d) 
b 
(c b) 
d 
b 
nil

&amp;gt; (collecting (for ((n (in-graph (list '(a b (c b) d))
                                 (lambda (n)
                                   (if (atom n) '() (cdr n)))
                                 :unique t
                                 :only-leaves t)))
                (collect n)))
(b d)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (setf *print-circle* t)
t

&amp;gt; (for ((n (in-graph (list '#1=(a #2=(b c #1#) d #2#))
                     (lambda (n)
                       (if (atom n) '() (cdr n)))
                     :unique t)))
    (print n))

#1=(a #2=(b c #1#) d #2#) 
#1=(b c (a #1# d #1#)) 
c 
d 
nil&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (for ((p (in-graph (list *package*) #'package-use-list
                     :unique t :order :breadth-first)))
    (format t "~&amp;amp;~A~%" (package-name p)))
COMMON-LISP-USER
ORG.TFEB.DSM
ORG.TFEB.HAX.ITERATE
ORG.TFEB.HAX.COLLECTING
ORG.TFEB.STAR
ORG.TFEB.TOOLS.REQUIRE-MODULE
COMMON-LISP
HARLEQUIN-COMMON-LISP
LISPWORKS
ORG.TFEB.HAX.UTILITIES
ORG.TFEB.HAX.SIMPLE-LOOPS
ORG.TFEB.HAX.SPAM
ORG.TFEB.DSM/IMPL
nil&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;in-graph&lt;/code&gt; is fairly simple, and uses both collectors and Štar in its own implementation:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun in-graph (roots node-neighbours &amp;amp;key
                       (only-leaves nil)
                       (order ':depth-first)
                       (unique nil)
                       (test #'eql)
                       (key #'identity))
  ;; Preorder / postorder would be nice to have
  "Iterate over a graph

- ROOTS are the nodes to start from.
- NODE-NEIGHBOURS is a function which, given a node, returns its
  neighbours if any.
- ORDER may be :DEPTH-FIRST (default) or :BREADTH-FIRST.
- UNIQUE, if given, will iterate nodes uniquely.
- TEST is the comparison test for nodes: it must be something
  acceptable to MAKE-HASH-TABLE.  Default is #'EQL.
- KEY, if given, extracts a key from a node for comparison in the
  usual way.

There is no optimizer.

If the graph is cyclic an iteration using this will not terminate
unless UNIQUE is true, unless some other clause stops it.  If the
graph is not directed you also need to use UNIQUE."
  (check-type order (member :depth-first :breadth-first))
  (let ((agenda (make-collector :initial-contents roots))
        (duplicate-table (if unique (make-hash-table :test test) nil))
        (this nil))
    (values
     (thunk                             ;predicate does all the work
       (if (collector-empty-p agenda)
           nil
         (for ((it (stepping (it :as (pop-collector agenda)))))
           (let ((neighbours (funcall node-neighbours it))
                 (k (and unique (funcall key it))))
             (cond
              ((and unique (gethash k duplicate-table))
               ;; It's a duplicate: skip
               (if (collector-empty-p agenda)
                   (final nil)
                 (next)))
              ((null neighbours)
               ;; Leaf, add it to the duplicate table if need be and say we found something
               (when unique
                 (setf (gethash k duplicate-table) t))
               (setf this it)
               (final t))
              (t
               ;; Not a leaf: update the agenda ...
               (setf agenda
                     (case order
                       (:depth-first
                        (nconc-collectors (make-collector :initial-contents neighbours) agenda))
                       (:breadth-first
                        (nconc-collectors agenda (make-collector :initial-contents neighbours)))))
               ;; .. add it to the duplicate table if need be so it's
               ;; skipped next time ...
               (when unique               
                 (setf (gethash k duplicate-table) t))
               ;; ... and decide if we found something
               (cond
                (only-leaves
                 (if (collector-empty-p agenda)
                     (final nil)
                   (next)))
                 (t
                  (setf this it)
                  (final t)))))))))
     (thunk this))))&lt;/code&gt;&lt;/pre&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2025-10-31-disentangling-iteration-from-value-accumulation-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;&amp;lsquo;Lisp&amp;rsquo; here will usually mean &amp;lsquo;Common Lisp&amp;rsquo;.&amp;nbsp;&lt;a href="#2025-10-31-disentangling-iteration-from-value-accumulation-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-10-31-disentangling-iteration-from-value-accumulation-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;Although if you use &lt;code&gt;loop&lt;/code&gt; you must accept that you will certainly suffer eternal damnation. Perhaps that&amp;rsquo;s worth it: Robert Johnson thought so, anyway.&amp;nbsp;&lt;a href="#2025-10-31-disentangling-iteration-from-value-accumulation-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-10-31-disentangling-iteration-from-value-accumulation-footnote-3-definition" class="footnote-definition"&gt;
   &lt;p&gt;This is the same argument that explains why a universal equality predicate is nonsensical: equality of objects depends on what they are equal &lt;em&gt;as&lt;/em&gt; and that is often not implicit in the objects.&amp;nbsp;&lt;a href="#2025-10-31-disentangling-iteration-from-value-accumulation-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-10-31-disentangling-iteration-from-value-accumulation-footnote-4-definition" class="footnote-definition"&gt;
   &lt;p&gt;Or in Lisp, more than likely.&amp;nbsp;&lt;a href="#2025-10-31-disentangling-iteration-from-value-accumulation-footnote-4-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Tracing the expansion of external macros</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2025/10/10/tracing-the-expansion-of-external-macros/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2025-10-10-tracing-the-expansion-of-external-macros</id>
  <published>2025-10-10T10:39:18Z</published>
  <updated>2025-10-10T10:39:18Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;I have improved my &lt;code&gt;trace-macroexpand&lt;/code&gt; system so you can say, in effect &amp;lsquo;trace the expansion of only the macros in the interface to a given package&amp;rsquo;. This is a fairly useful thing.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Tracing macroexpansion in Common Lisp is a pretty useful thing to be able to do, in my experience. It is completely possible to do this in portable CL via &lt;a href="https://www.lispworks.com/documentation/HyperSpec/Body/v_mexp_h.htm"&gt;&lt;code&gt;*macroexpand-hook*&lt;/code&gt;&lt;/a&gt;: you simply put your tracing function on this hook, making sure it actually does expand the macro. &lt;a href="https://tfeb.org/fragments/documentation/tfeb-lisp-hax.html#tracing-macroexpansion-trace-macroexpand"&gt;&lt;code&gt;trace-macroexpand&lt;/code&gt;&lt;/a&gt; does just this, and lets you specify which macros you want to be traced.&lt;/p&gt;

&lt;p&gt;It has always allowed you to say &amp;lsquo;trace all macros whose home package is this package&amp;rsquo;. That&amp;rsquo;s less useful than you might think:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;it means that not only macros whose names are exported from the packqge are traced, but any macros in its guts are also traced, which generally a user of the package should not be interested in;&lt;/li&gt;
 &lt;li&gt;it &lt;em&gt;doesn&amp;rsquo;t&lt;/em&gt; trace macros which are exported from a package but whose home package is not that package.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Very often the second thing is exactly what you want: you want to be able to say &amp;lsquo;let me see the expansion of macros in the public interface to this package, but I don&amp;rsquo;t care about the internal details of it&amp;rsquo;.&lt;/p&gt;

&lt;p&gt;It can now do exactly that.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;trace-macro-package&lt;/code&gt; now takes a list of &lt;em&gt;package specifiers&lt;/em&gt;. If a package specifier is a list of one or more other package specifiers, then it changes their meaning to be &amp;lsquo;trace the exports of these packages only&amp;rsquo;.&lt;/p&gt;

&lt;p&gt;Here is an example:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (find-symbol "FOR" :org.tfeb.star)
for
:external

&amp;gt; (symbol-package *)
#&amp;lt;The ORG.TFEB.STAR/IMPL package, 188/512 internal, 6/16 external&amp;gt;

&amp;gt; (trace-macroexpand t)
nil

&amp;gt; (setf *trace-macroexpand-per-line-prefix* "| ")
"| "

&amp;gt; (trace-macro-package :org.tfeb.star)
("ORG.TFEB.STAR")

&amp;gt; (for ((_ (in-naturals 10))))
nil

&amp;gt; (untrace-macro-package :org.tfeb.star)
nil

&amp;gt; (trace-macro-package '(:org.tfeb.star))
(("ORG.TFEB.STAR"))

&amp;gt; (for ((_ (in-naturals 10))))
| (for (#))
|  -&amp;gt; (multiple-value-bind (#:&amp;lt;v&amp;gt;) 0 ...)
nil&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As well as this, both &lt;code&gt;trace-macro-package&lt;/code&gt; and &lt;code&gt;untrace-macro-package&lt;/code&gt; now &lt;em&gt;canonicalise&lt;/em&gt; the specifiers they are given, which means, for instance that &lt;code&gt;(trace-macro-package '("FOO" "BAR"))&lt;/code&gt; is exactly the same as &lt;code&gt;(trace-macro-package '("FOO") '("BAR"))&lt;/code&gt;: this means that things like&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (trace-macro-package '("FOO" "BAR"))

[...]

&amp;gt; (untrace-macro-package '("FOO"))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will work properly.&lt;/p&gt;

&lt;p&gt;This change is in version 10.9.0 of the &lt;a href="https://tfeb.org/fragments/documentation/tfeb-lisp-hax.html"&gt;TFEB.ORG Lisp hax&lt;/a&gt;, &lt;a href="https://tfeb.org/computer/repos/tfeb-lisp-hax.git"&gt;git repo&lt;/a&gt;.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Optional per-line prefix for trace-macroexpand</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2025/10/08/optional-per-line-prefix-for-trace-macroexpand/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2025-10-08-optional-per-line-prefix-for-trace-macroexpand</id>
  <published>2025-10-08T16:52:23Z</published>
  <updated>2025-10-08T16:52:23Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;My &lt;a href="https://tfeb.org/fragments/documentation/tfeb-lisp-hax.html#tracing-macroexpansion-trace-macroexpand"&gt;macroexpansion tracer&lt;/a&gt; can now print per-line prefixes when tracing, which can make things more readable.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;I find &lt;code&gt;trace-macroexpand&lt;/code&gt; pretty useful: if you write Lisp with lots of nontrivial macros&lt;sup&gt;&lt;a href="#2025-10-08-optional-per-line-prefix-for-trace-macroexpand-footnote-1-definition" name="2025-10-08-optional-per-line-prefix-for-trace-macroexpand-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt; then it can be fairly hard to understand what&amp;rsquo;s going on when something is not working properly. &lt;code&gt;trace-macroexpand&lt;/code&gt; lets you see this either for individual macros or many of them. It can, portably, trace any macro including ones defined by CL, which is even nicer.&lt;/p&gt;

&lt;p&gt;However it&amp;rsquo;s not always easy to distinguish its output from other output. So, I realised I could add a per-line prefix which can help distinguish its output. Here is an example.&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (defvar *a* (cons nil nil))
*a*

&amp;gt; (trace-macroexpand t)
nil

&amp;gt; (trace-macro setf)
(setf)

&amp;gt; (setf (car *a*) 10)
(setf (car *a*) 10)
 -&amp;gt; (system::%rplaca *a* 10)
10

&amp;gt; (setf *trace-macroexpand-per-line-prefix* "| ")
(setf *trace-macroexpand-per-line-prefix* "| ")
 -&amp;gt; (let* (#) (setq *trace-macroexpand-per-line-prefix* #:|Store-Var-1692|))
"| "

&amp;gt; (setf (car *a*) 11)
| (setf (car *a*) 11)
|  -&amp;gt; (system::%rplaca *a* 11)
11&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is in version 10.8.1&lt;sup&gt;&lt;a href="#2025-10-08-optional-per-line-prefix-for-trace-macroexpand-footnote-2-definition" name="2025-10-08-optional-per-line-prefix-for-trace-macroexpand-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt; of the &lt;a href="https://tfeb.org/fragments/documentation/tfeb-lisp-hax.html"&gt;TFEB.ORG Lisp hax&lt;/a&gt;, &lt;a href="https://tfeb.org/computer/repos/tfeb-lisp-hax.git"&gt;git repo&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2025-10-08-optional-per-line-prefix-for-trace-macroexpand-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;If you aren&amp;rsquo;t doing that, why are you writing Lisp at all?&amp;nbsp;&lt;a href="#2025-10-08-optional-per-line-prefix-for-trace-macroexpand-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-10-08-optional-per-line-prefix-for-trace-macroexpand-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;10.8.0 had a stupid bug.&amp;nbsp;&lt;a href="#2025-10-08-optional-per-line-prefix-for-trace-macroexpand-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Defaulting places in Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2025/10/07/defaulting-places-in-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2025-10-07-defaulting-places-in-common-lisp</id>
  <published>2025-10-07T11:50:22Z</published>
  <updated>2025-10-07T11:50:22Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Or: less boilerplate.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Common Lisp (CL) has a general notion of a &lt;a href="https://www.lispworks.com/documentation/HyperSpec/Body/05_a.htm" title="Generalized reference"&gt;&lt;em&gt;place&lt;/em&gt;&lt;/a&gt;, which is a form which has a value or values and into which a value or values can be stored. Variables are places, but so are forms like &lt;code&gt;(car c)&lt;/code&gt;: &lt;code&gt;(setf (car c) 2)&lt;/code&gt; will store 2 into the car of the cons bound to &lt;code&gt;c&lt;/code&gt;. Places can even store multiple values:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((a 1) (b 3))
  (setf (values a b) (values 3 4))
  (values a b))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;for instance. Here the place is &lt;code&gt;(values a b)&lt;/code&gt; which is a place composed of two other places.&lt;/p&gt;

&lt;p&gt;This is a really useful notion, not only because places mean the language no longer needs all sorts of special-purpose mutation functions &amp;mdash; &lt;code&gt;rplaca&lt;/code&gt; still exists for compatibility but there is no &lt;code&gt;sethash&lt;/code&gt; or &lt;code&gt;aset&lt;/code&gt; &amp;mdash; but because you can implement your own places which behave just like the ones the language provides.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s an example of a place called a &amp;lsquo;wrapped alist&amp;rsquo;: it&amp;rsquo;s just a cons whose cdr is an alist. It&amp;rsquo;s done like this so storing works in general (think about empty alists).&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun make-wrapped-alist (&amp;amp;optional (for-alist '()))
  (cons nil for-alist))

(defun wrapped-alist-alist (wa)
  (cdr wa))

(defun wav (item wrapped-alist &amp;amp;key (test nil testp) (default nil))
  (let ((found (if testp
                   (assoc item (cdr wrapped-alist) :test test)
                 (assoc item (cdr wrapped-alist)))))
    (if found
        (values (cdr found) t)
      (values default nil))))

(defun (setf wav) (new item wrapped-alist &amp;amp;key (test nil testp) default)
  (declare (ignore default))
  (let ((found (if testp
                   (assoc item (cdr wrapped-alist) :test test)
                 (assoc item (cdr wrapped-alist)))))
    (if found
        (setf (cdr found) new)
      (progn
        (push (cons item new) (cdr wrapped-alist))
        new))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I will use these wrapped alist places in the examples below.&lt;/p&gt;

&lt;h2 id="defaulting-places"&gt;Defaulting places&lt;/h2&gt;

&lt;p&gt;Quite often, a place has a default value or a way of indicating that there is no value in it, and you want to be able to say &amp;lsquo;if this place has not been stored into, then store this into it&amp;rsquo;. In the case of hash tables, the indicator is that &lt;code&gt;gethash&lt;/code&gt; returns a second value of &lt;code&gt;nil&lt;/code&gt;, and that is the same for &lt;code&gt;av&lt;/code&gt; and my wrapped alists.&lt;/p&gt;

&lt;p&gt;Sometimes this is not a problem, especially when the accessor for a place lets you provide a default:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun symbol-counts (l)
  (let ((table (make-hash-table)))
    (dolist (e l)
      (when (symbolp e)
        (incf (gethash e table 0))))
    (collecting
      (maphash (lambda (k v)
                 (collect (cons k v)))
               table))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun symbol-counts/probably-slower (l)
  (let ((wa (make-wrapped-alist)))
    (dolist (e l)
      (when (symbolp e)
        (incf (av e wa :default 0))))
    (wrapped-alist-alist wa)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But sometimes it is a problem. Consider the case where the fallback thing you want to store is expensive, or has side-effects. Now you need to write some boilerplate code:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(unless (nth-value 1 (wav item wa)
    (setf (wav item wa) (compute-complicated-thing))))&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="the-wrong-way"&gt;The wrong way&lt;/h2&gt;

&lt;p&gt;Well, boilerplate is bad. So you might want to replace this by a macro:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro defaulting/wrong (place-form value-form)
  ;; This just assumes that PLACE-FORM returns NIL if it has no value:
  ;; in real life you need to be cleverer.
  `(or ,place-form
       (setf ,place-form ,value-form)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is not only limited, but incorrect. It&amp;rsquo;s incorrect because it multiply evaluates subforms to &lt;code&gt;place-form&lt;/code&gt;. Consider this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((i 0) (table (make-hash-table)))
  (defaulting/wrong (gethash (incf i) table) 3))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, using wrapped alists it&amp;rsquo;s easy to see what this is doing wrong:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((i 0) (wa (make-wrapped-alist)))
    (defaulting/wrong (wav (incf i) wa) 3)
    (wrapped-alist-alist wa))
((2 . 3))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, not great. The boilerplate you&amp;rsquo;d need to write is:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((i 0) (wa (make-wrapped-alist)))
    (let ((k (incf i)))
      (unless (wav k wa)
        (setf (wav k wa) 3)))
    (wrapped-alist-alist wa))
((1 . 3))&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="the-right-way"&gt;The right way&lt;/h2&gt;

&lt;p&gt;The problem is that any such &lt;code&gt;defaulting&lt;/code&gt; macro doesn&amp;rsquo;t know anything about the place it&amp;rsquo;s defaulting. So it can&amp;rsquo;t know which subforms of the place it needs to stash values for.&lt;/p&gt;

&lt;p&gt;Well, it turns out that the designers of CL thought of this, and they provided the tool you need, which is &lt;a href="https://www.lispworks.com/documentation/HyperSpec/Body/f_get_se.htm" title="get-setf-expansion"&gt;&lt;code&gt;get-setf-expansion&lt;/code&gt;&lt;/a&gt;. Given a place and optionally an environment, this will tell you exactly what you need to know to both read from that place and write to it, and to do so multiple times if need be.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;get-setf-expansion&lt;/code&gt; is what you need to be able to write your own &lt;code&gt;setf&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro assign (&amp;amp;rest pairs &amp;amp;environment e)
  ;; This should be SETF give or take
  `(progn
     ,@(collecting
         (for ((tail (on-list pairs :by #'cddr)))
           (destructuring-bind (place-form value-form . _) tail
             (declare (ignore _))
             (multiple-value-bind (vars vals store-vars writer-form reader-form)
                 (get-setf-expansion place-form e)
               (declare (ignore reader-form))
               (collect
                `(let* ,(mapcar #'list vars vals)
                   (multiple-value-bind ,store-vars ,value-form
                     ,writer-form)))))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But you can also use it to write &lt;code&gt;defaulting&lt;/code&gt; properly. Here is a much fancier version of it, which is now correct (I hope):&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro defaulting (place value-form
                            &amp;amp;body options
                            &amp;amp;key test default-value nth-value &amp;amp;environment e)
  (declare (ignore options))            ;just for indent
  (multiple-value-bind (tvars tforms store-variables storing-form accessing-form)
      (get-setf-expansion place e)
    `(let* ,(mapcar #'list tvars tforms)
         (when ,(cond
                 ((and test nth-value)
                  `(not (funcall ,test ,default-value (nth-value ,nth-value ,accessing-form))))
                 (test
                  `(not (multiple-value-call ,test ,default-value ,accessing-form)))
                 ((and default-value nth-value)
                  `(eql ,default-value (nth-value ,nth-value ,accessing-form)))
                 (default-value
                  `(eql ,default-value ,accessing-form))
                 (nth-value
                  `(not (nth-value ,nth-value ,accessing-form)))
                 (t
                  `(not ,accessing-form)))
           (multiple-value-bind ,store-variables ,value-form
             ,storing-form))
         ,accessing-form)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So now:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((i 0) (wa (make-wrapped-alist)))
    (defaulting (wav (incf i) wa) 3)
    (wrapped-alist-alist wa))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or, using options to this &lt;code&gt;defaulting&lt;/code&gt; to tell it the value to be checked:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((i 0) (wa (make-wrapped-alist)))
    (defaulting (wav (incf i) wa) 3 :nth-value 1)
    (wrapped-alist-alist wa))
((1 . 3))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, you can see the expansion using &lt;a href="https://tfeb.org/fragments/documentation/tfeb-lisp-hax.html#tracing-macroexpansion-trace-macroexpand"&gt;&lt;code&gt;trace-macroexpand&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((a (make-wrapped-alist)))
    (defaulting (wav 'k a) 3 :nth-value 1))
(defaulting (wav 'k a)
    3
  :nth-value 1)
 -&amp;gt; (let* ((#:a1 a))
      (when (not (nth-value 1 (wav 'k #:a1)))
        (multiple-value-bind (#:new0) 3 (funcall #'(setf wav) #:new0 'k #:a1)))
      (wav 'k #:a1))
3
t&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and this is obviously correct.&lt;/p&gt;

&lt;p&gt;This macro exists in &lt;a href="https://tfeb.org/fragments/documentation/tfeb-lisp-hax.html#small-utilities-utilities" title="Small utilities"&gt;&lt;code&gt;org.tfeb.hax.utilities&lt;/code&gt;&lt;/a&gt;, the git repo for which is &lt;a href="https://tfeb.org/computer/repos/tfeb-lisp-hax.git" title="TFEB Lisp hax"&gt;&lt;code&gt;tfeb.org/computer/repos/tfeb-lisp-hax.git&lt;/code&gt;&lt;/a&gt;. Note it is &lt;em&gt;not&lt;/em&gt; in the archived GitHub repo.&lt;/p&gt;

&lt;p&gt;This is version 10.7.0 of the TFEB.ORG Lisp hax.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Minimum clown</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2025/08/26/minimum-clown/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2025-08-26-minimum-clown</id>
  <published>2025-08-26T14:29:31Z</published>
  <updated>2025-08-26T14:29:31Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Hosting code on GitHub now seems like an invitation to have it turned into AI slop. Here&amp;rsquo;s what I did to move.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;blockquote&gt;
 &lt;p&gt;Isn&amp;rsquo;t it rich?
  &lt;br /&gt;Are we a pair?
  &lt;br /&gt;Me here at last on the ground,
  &lt;br /&gt;You in mid-air.
  &lt;br /&gt;Send in the clowns.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I think the number of people who care about, let alone rely on, my Lisp code who I don&amp;rsquo;t personally know is somewhere between few and none by now. Nevertheless, it makes me feel honest to publish some of what I write, in the hope someone might find it useful.&lt;/p&gt;

&lt;p&gt;Long ago, I did that by simply putting files on my vanity site (in the days when people had vanity sites). At some point it became clear that this was not the right answer, and the thing to do was to keep things on one of the newfangled source-hosting sites. I have never been and will never be comfortable with the idea of the canonical version of anything I make not sitting on storage that I control &amp;mdash; people who do that are not thinking hard enough in my opinion &amp;mdash; which means that no source-hosting site based on a centralised source control system was at all interesting.&lt;/p&gt;

&lt;h2 id="send-in-the-clowns"&gt;Send in the clowns&lt;/h2&gt;

&lt;p&gt;And then git arrived, and sometime after it, GitHub. Git meant that I could both keep the canonical versions of things somewhere safe while making them publicly available. At about the same time I was realising that vanity sites were, well, vanity, and the antique documentation written in raw HTML with its origins in the mid 1990s really needed to be turned into something better, anyway.&lt;/p&gt;

&lt;p&gt;Well, it was more complicated, of course. I have a source tree which contains history that&amp;rsquo;s not public and some of which is very old&lt;sup&gt;&lt;a href="#2025-08-26-minimum-clown-footnote-1-definition" name="2025-08-26-minimum-clown-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;. So after initially pushing a frozen version of what used to be on my vanity site, I organised things into various &amp;lsquo;publication repos&amp;rsquo; which get populated (by &lt;code&gt;make&lt;/code&gt;) from the source tree. These have simplified histories, often really only being a series of release versions. And this worked fine.&lt;/p&gt;

&lt;p&gt;I never really used much of the mechanism provided by GitHub: I didn&amp;rsquo;t need it, and doing so would have broken my rule of not depending on things I don&amp;rsquo;t have control over.&lt;/p&gt;

&lt;p&gt;In 2018 Microsoft bought GitHub, and&lt;/p&gt;

&lt;blockquote&gt;
 &lt;p&gt;THIS IS WHAT HAPPENS WHEN YOU STORE YOUR DATA IN THE CLOWN.&lt;/p&gt;
 &lt;p&gt;The Clown is just &lt;em&gt;someone else&amp;rsquo;s computer&lt;/em&gt; and they can and will &lt;em&gt;fuck&lt;/em&gt; you. If it&amp;rsquo;s not on your computer, it&amp;rsquo;s not under your control. Why do you all keep doing this to yourselves??&lt;/p&gt;
 &lt;p&gt;Stop hitting yourself. Seriously, stop it.
  &lt;br /&gt;&amp;mdash; &lt;a href="https://www.jwz.org/blog/2018/06/lol-github/" title="LOL Github"&gt;jwz&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;But I wasn&amp;rsquo;t worried, because I was not storing my data in the clown: I was just publishing copies of it there. I felt kind of smug about that. I hadn&amp;rsquo;t worked out, in 2018, how bad things could get and how fast. I had worked out that if you were not paying the clown, then the clown was feeding on your soul, but I didn&amp;rsquo;t think it would get any useful nutrition from the parts of my soul it could reach. And other things were going on which distracted me.&lt;/p&gt;

&lt;p&gt;Fast forward to mid&amp;ndash;2025, and GitHub is a subsidiary of Microsoft&amp;rsquo;s &amp;lsquo;weaponized bullshit&amp;rsquo; division: it is time, and past time, to go.&lt;/p&gt;

&lt;p&gt;Where? Well there are other clowns. But no: they may be good clowns, for now, but they&amp;rsquo;re still clowns. Clowns are, well, clowns: you don&amp;rsquo;t want to be trusting them. You want a &lt;em&gt;minimum clown&lt;/em&gt; policy.&lt;/p&gt;

&lt;h2 id="where-are-the-clowns"&gt;Where are the clowns?&lt;/h2&gt;

&lt;p&gt;So here&amp;rsquo;s what I am doing.&lt;/p&gt;

&lt;p&gt;If you can live with git&amp;rsquo;s &lt;a href="https://git-scm.com/docs/http-protocol" title="HTTP protocol"&gt;dumb HTTP protocol&lt;/a&gt; then any web server which can host static files can host read-only git repos. To push to them you need some smarter protocol, and you need to have a hook which does &lt;code&gt;git update-server-info&lt;/code&gt; after any change: this should be in the &lt;code&gt;post-update&lt;/code&gt; hook, really. All these repos will be read-only and public, so I don&amp;rsquo;t need access control or authentication.&lt;/p&gt;

&lt;p&gt;To actually make them exist you need more. Fortunately the people who host my vanity domain provide SSH access and &lt;code&gt;git&lt;/code&gt; exists on the server. So that&amp;rsquo;s enough to create a repo, add the hook and then push everything to it as and when I need to.&lt;/p&gt;

&lt;p&gt;For documentation: I am already using &lt;a href="https://docs.racket-lang.org/frog/index.html" title="Frog"&gt;Frog&lt;/a&gt; for, for instance, this post. And Frog has the nice feature that you can just add Markdown files in a directory (or any subdirectory) it knows about and it will turn them into HTML. So I wrote a makefile to copy &lt;code&gt;README.md&lt;/code&gt; files from publication repos and suitably munged the original GitHub Pages index page.&lt;/p&gt;

&lt;p&gt;Then there were a bunch of small changes such as telling &lt;code&gt;rsync&lt;/code&gt; not to clobber the repos when updating things, gluing makefiles together so suitable things happen in subdirectories and &lt;code&gt;make publish&lt;/code&gt; does everything needed.&lt;/p&gt;

&lt;p&gt;What this needs is a web server that can host static files with enough storage (which is not a great deal), and a way of syncing local content to it. SSH access, git on the server and &lt;code&gt;rsync&lt;/code&gt; make things quite a bit easier but I could maintain the public repos locally and sync them to the web server however it allowed that.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m pretty confident that any other hosting provider I might one day switch to&lt;sup&gt;&lt;a href="#2025-08-26-minimum-clown-footnote-2-definition" name="2025-08-26-minimum-clown-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt; will provide that.&lt;/p&gt;

&lt;h2 id="well-maybe-next-year"&gt;Well, maybe next year&lt;/h2&gt;

&lt;p&gt;If I was a big player I think I would simply delete my GitHub repos and put up a message saying where people could now find things. I&amp;rsquo;m not a big player, so what I did is to make the repos read-only (GitHub calls this &amp;lsquo;archiving&amp;rsquo;) and add suitable links. I&amp;rsquo;ve done this for all my main Lisp repos: I have some more to do. Archiving means people may never notice: so be it. I plan to tell, for instance, Quicklisp in due course. I also have some non-public (clones of) repos on GitHub which I will just host outside the web server tree, accessing them only via SSH.&lt;/p&gt;

&lt;p&gt;There are, inevitably, some changes to the Markdown parsing, which I need to chase down and fix in the source. There already were incompatibilities amongst GitHub&amp;rsquo;s various parsers.&lt;/p&gt;

&lt;p&gt;When I&amp;rsquo;ve finished all this, I probably will replace my GitHub Pages site by something which just points at the canonical place.&lt;/p&gt;

&lt;p&gt;There will be no releases: I&amp;rsquo;ll just post things announcing changes with tag names. There is no big tracking: just mail me.&lt;/p&gt;

&lt;p&gt;Where things are&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://tfeb.org/computer/" title="tfeb.org/computer/"&gt;tfeb.org/computer/&lt;/a&gt; is the list of things;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://tfeb.org/computer/repos/" title="tfeb.org/computer/repos/"&gt;tfeb.org/computer/repos/&lt;/a&gt; is where the repos are;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://tfeb.org/fragments/documentation/" title="tfeb.org/fragments/documentation/"&gt;tfeb.org/fragments/documentation/&lt;/a&gt; is the list of documentation.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;And that is all.&lt;/p&gt;

&lt;blockquote&gt;
 &lt;p&gt;Isn&amp;rsquo;t it rich?
  &lt;br /&gt;Isn&amp;rsquo;t it queer,
  &lt;br /&gt;Losing my timing this late
  &lt;br /&gt;In my career?
  &lt;br /&gt;And where are the clowns?
  &lt;br /&gt;There ought to be clowns.
  &lt;br /&gt;Well, maybe next year.&lt;/p&gt;&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2025-08-26-minimum-clown-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;It turns out I never did import all the CVS versions of things, although I meant to.&amp;nbsp;&lt;a href="#2025-08-26-minimum-clown-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2025-08-26-minimum-clown-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;Pair, my current provider, are fine. But they are also American, and I&amp;rsquo;d rather use a provider based in a democracy.&amp;nbsp;&lt;a href="#2025-08-26-minimum-clown-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">The modern real programmer</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2025/01/31/the-modern-real-programmer/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2025-01-31-the-modern-real-programmer</id>
  <published>2025-01-31T19:17:18Z</published>
  <updated>2025-01-31T19:17:18Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;This is adapted from an email from my friend Zyni, used with her permission. Don&amp;rsquo;t take it too seriously.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Real programmers do not write programs like this. If a real programmer has to deal with a collection of particles, they do not have some silly object which represents a particle, perhaps made up of other objects representing physical vectors, and then some array of pointers to these particle objects. That is a bourgeois fantasy and the people who do that will not long survive the revolution. They will die due to excessive pointer-chasing; many of them have already died of quiche.&lt;/p&gt;

&lt;p&gt;Real programmers do today as they have always done: if they have some particles to simulate a galaxy they make an array of floating point numbers, in which the particles live.&lt;/p&gt;

&lt;p&gt;This is how it has always been done, and how it always will be done, by people who care about performance.&lt;/p&gt;

&lt;p&gt;And this is why Lisp is so superb. Because you can write this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(for* ((i1 (in-particle-vector-indices pv))
       (i2 (in-particle-vector-indices pv i1)))
  (declare (type particle-vector-index i1 i2))
  (with-particle-at (i1 pv :name p1)
    (with-particle-at (i2 pv :name p2)
      (let/fpv ((rx (- p2-x p1-x))
                (ry ...)
                ...)
        ... compute interactions ...))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this is:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;very fast&lt;sup&gt;&lt;a href="#2025-01-31-the-modern-real-programmer-footnote-1-definition" name="2025-01-31-the-modern-real-programmer-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;, because it all turns into optimized loops over suitable &lt;code&gt;(simple-array double-float (*))&lt;/code&gt; with no silly objects or consing;&lt;/li&gt;
 &lt;li&gt;relatively easy for a human to read, since you can see, for instance what &lt;code&gt;(for ((i (in-particle-vector-indices v))) ...)&lt;/code&gt; is doing and do not have to second-guess some idiot &lt;code&gt;loop&lt;/code&gt; form which will be full of obscure bugs;&lt;/li&gt;
 &lt;li&gt;quiche-compatible: you can easily write a function &lt;code&gt;particle-at&lt;/code&gt; which will construct a &lt;code&gt;particle&lt;/code&gt; object from a particle vector entry (such a function will later be excised as it has no callers, of course);&lt;/li&gt;
 &lt;li&gt;perhaps most important it is possible for a &lt;em&gt;program&lt;/em&gt; to take this code and to look at it and to say, &amp;lsquo;OK, this is an iteration over a particle vector – it is not some stupid hard-to-parse &lt;code&gt;(loop for ... oh I have no idea what this is ...)&lt;/code&gt; as used by the quiche people, it is &lt;code&gt;(for ((i (in-particle-vector-indices v))) ...)&lt;/code&gt; and it is very easy to see what this is – and there are things I can do with that&amp;rsquo; and generate Fortran which can be easily (or, less difficultly &amp;mdash; is &amp;lsquo;difficultly&amp;rsquo; a word? English is so hard) be made to run well on proper machines with sensible numbers of processors.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;And this is the thing they still do not see. You write your program which uses the only useful data structure, but you also write your program in a language you have built designed so that both a human and another program can understand it, and do useful things with it, because your program says what it means. Every construct in your program should be designed so that this other program can get &lt;em&gt;semantic&lt;/em&gt; information from that construct to turn it into something else.&lt;/p&gt;

&lt;p&gt;And this is why Lisp is so uniquely useful for real orogrammers. Lisp has only one interesting feature today: it is a language not for writing programs, but for writing &lt;em&gt;languages&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That is what real programmers do: they build languages to solve their problems. The real programmer understands only two things:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;the only data structure worth knowing about is the array;&lt;/li&gt;
 &lt;li&gt;her job as a programmer is to &lt;em&gt;write languages&lt;/em&gt; which will make writing programs to manipulate arrays easy for a human to understand;&lt;/li&gt;
 &lt;li&gt;and her other job is to write other programs which will take these programs and turn them into Fortran;&lt;/li&gt;
 &lt;li&gt;and when that is done she can go and ride her lovely cob to the fair.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Real programmers also can count only to two.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2025-01-31-the-modern-real-programmer-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;I (Tim, not Zyni, who would use a cleverer integrator) wrote a mindless program to integrate systems of gravitating particles to test some of the things we&amp;rsquo;ve written that are mentioned in this email. On an Apple M1 it sustains well over 1 double precision GFLOP. Without using the GPU I think this is about what the processor can do.&amp;nbsp;&lt;a href="#2025-01-31-the-modern-real-programmer-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Wild pathnames in Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2024/08/18/wild-pathnames-in-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2024-08-18-wild-pathnames-in-common-lisp</id>
  <published>2024-08-18T17:00:02Z</published>
  <updated>2024-08-18T17:00:02Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Common Lisp&amp;rsquo;s pathname system has many problems. Here is proposal to make the situation a little better in one respect. This is not a general fix: it&amp;rsquo;s just trying to solve one problem.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="the-problem"&gt;The problem&lt;/h2&gt;

&lt;p&gt;The underlying problem is that on many platforms pathnames which &amp;lsquo;look like&amp;rsquo; they contain wildcards are perfectly legal pathnames to the filesystem. So, on Unix &amp;amp; related systems &lt;code&gt;[foo].*&lt;/code&gt; is a legal filename. On these platforms wildcard handling is generally implemented in a library, or often in multiple semi-compatible libraries&lt;sup&gt;&lt;a href="#2024-08-18-wild-pathnames-in-common-lisp-footnote-1-definition" name="2024-08-18-wild-pathnames-in-common-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;CL then has two problems:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;there is no portable way to construct pathnames which look wild but are not;&lt;/li&gt;
 &lt;li&gt;there is no portable way to parse a string which looks like a wild pathname but in fact should not be interpreted as one, for instance a string coming from some other application or library, or a filename stored in some file, such as an archive.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;(1) happens because &lt;a href="https://www.lispworks.com/documentation/HyperSpec/Body/19_bbc.htm" title=" Restrictions on Wildcard Pathnames"&gt;19.2.2.3&lt;/a&gt; says, in part&lt;/p&gt;

&lt;blockquote&gt;
 &lt;p&gt;When examining wildcard components of a wildcard pathname, conforming programs must be prepared to encounter any of the following additional values in any component or any element of a list that is the directory component: [&amp;hellip;] A string containing implementation-dependent special wildcard characters. [&amp;hellip;]&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;That means that implementations are allowed to represent wildcard components of pathnames as strings, and that means that you can&amp;rsquo;t portably construct a non-wildcard pathname.&lt;/p&gt;

&lt;p&gt;(2) happens because there&amp;rsquo;s no way to tell &lt;code&gt;parse-namestring&lt;/code&gt; or &lt;code&gt;pathname&lt;/code&gt; that the string you&amp;rsquo;ve handed to them is not wild, even though it looks like it is. That in turn means that to deal with this case you need to either write or find a pathname-parsing library which doesn&amp;rsquo;t have this problem.&lt;/p&gt;

&lt;p&gt;These problems arise in practice: for instance some programs create filenames which look like &lt;code&gt;[foo].xml&lt;/code&gt;: SBCL at least parses strings like this as wild, as it is allowed to do. This then breaks programs which want to, for instance, process zip files, tar files or other archive formats.&lt;/p&gt;

&lt;h2 id="a-proposed-solution"&gt;A proposed solution&lt;/h2&gt;

&lt;p&gt;For (1) change 19.2.2.3 to say that wildcard components are never strings. Change the description of &lt;code&gt;make-pathname&lt;/code&gt; to say that if the corresponding components to it are strings (or suitably-constrained lists for the directory component) then the pathname is not wild, except if the default provides a component which is wild.&lt;/p&gt;

&lt;p&gt;For (2) add an extra argument to both &lt;code&gt;parse-namestring&lt;/code&gt; and &lt;code&gt;pathname&lt;/code&gt; named &lt;code&gt;wild&lt;/code&gt; with a default of true. If given as &lt;code&gt;nil&lt;/code&gt; this will force string parsing to construct a non-wild pathname. If that is not possible, such as when &lt;code&gt;pathname&lt;/code&gt; is handed a pathname which is already wild, then an error will be signalled.&lt;/p&gt;

&lt;h2 id="notes"&gt;Notes&lt;/h2&gt;

&lt;p&gt;This is the smallest change I can think of which will solve the problem. Some implementations, SBCL for instance, already solve (1) in the suggested way. None, I think, solve (2).&lt;/p&gt;

&lt;p&gt;For added value, it might be useful to specify that wildcard components can be given either as symbols or as lists whose first element is a symbol, and encourage implementations to return them as such if possible. So, for instance &lt;code&gt;(:sequence "foo-" (:alternation "bar" "zap"))&lt;/code&gt; might represent a wild name which matches &lt;code&gt;"foo-bar"&lt;/code&gt; and &lt;code&gt;"foo-zap"&lt;/code&gt;. I am not suggesting this particular notation however.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2024-08-18-wild-pathnames-in-common-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;Let me introduce you to the joys of Unix.&amp;nbsp;&lt;a href="#2024-08-18-wild-pathnames-in-common-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">The abominable shadow</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2024/08/01/the-abominable-shadow/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2024-08-01-the-abominable-shadow</id>
  <published>2024-08-01T10:55:11Z</published>
  <updated>2024-08-01T10:55:11Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Most uses of &lt;code&gt;shadow&lt;/code&gt; and &lt;code&gt;shadowing-import&lt;/code&gt; in Common Lisp packages point to design problems.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Let&amp;rsquo;s assume you are designing a language which is going to be a variant CL: most of it will be just CL, but perhaps some things will be different. For example, let&amp;rsquo;s imagine that you want &lt;code&gt;if&lt;/code&gt; to have a mandatory else clause. You might start by designing your package like this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defpackage :my-language
  (:use :cl)
  (:shadow #:if)
  (:export #:if))

(in-package :my-language)

...

(defmacro if (test then else)
  `(cl:if ,test ,then ,else))

...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That all seems fine, right? Well, not so much. Consider for a minute people who want to &lt;em&gt;use&lt;/em&gt; your language. They need to write something like this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defpackage :my-language-user-package
  (:use :cl :my-language)
  (:shadowing-import-from :my-language #:if))

(in-package :my-language-user-package)

...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;lsquo;Oh well&amp;rsquo;, you say, &amp;lsquo;that&amp;rsquo;s not so bad&amp;rsquo;. Well, now let&amp;rsquo;s say you want to add a version of &lt;code&gt;cond&lt;/code&gt; to your language which understands &lt;code&gt;else&lt;/code&gt; and &lt;code&gt;otherwise&lt;/code&gt;. So:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defpackage :my-language
  (:use :cl)
  (:shadow #:if #:cond)
  (:export #:if #:cond #:else))

(in-package :my-language)

...

(defmacro if (test then else)
  `(cl:if test then else))

(defmacro cond (&amp;amp;body clauses)
  `(cl:cond
    ,@(mapcar (lambda (clause)
                (if (and (consp clause)
                         (member (first clause) '(else otherwise)))
                    `(t ,@(rest clause))
                  clause))
              clauses)))

...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now every user of your language has to modify their package definitions:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defpackage :my-language-user-package
  (:use :cl :my-language)
  (:shadowing-import-from :my-language #:if #:cond))

(in-package :my-language-user-package)

...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&amp;rsquo;ll say that again: &lt;strong&gt;every user of your language has to modify their package definitions every time you enhance it in a way which is not compatible with CL&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That &amp;hellip; sucks. It&amp;rsquo;s an &lt;em&gt;absolutely terrible&lt;/em&gt; design. Wouldn&amp;rsquo;t it be nice if it could be avoided?&lt;/p&gt;

&lt;p&gt;It can. Rather than shadowing symbols, you can instead construct the packages you actually would like to exist. In the example above what you probably want people to be able to do is to say&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defpackage :my-language-user-package
  (:use :my-language))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and have that work, even when your language changes. So, you need the &lt;code&gt;MY-LANGUAGE&lt;/code&gt; package to export most of the symbols from &lt;code&gt;CL&lt;/code&gt; as well as a few of its own. You can do this by hand:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defpackage :my-language
  (:use)
  (:export #:if #:cond #:else)
  (:import-from :cl
   cl:&amp;amp;allow-other-keys ...)
  (:export
   cl:&amp;amp;allow-other-keys ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where the &lt;code&gt;:import-from&lt;/code&gt; and the second &lt;code&gt;:export&lt;/code&gt; clause specify all the symbols from &lt;code&gt;CL&lt;/code&gt; except those which are replaced by ones defined by your language.&lt;/p&gt;

&lt;p&gt;Note the empty &lt;code&gt;:use&lt;/code&gt; clause: this avoids symbol clashes and therefore the need to shadow things.&lt;/p&gt;

&lt;p&gt;You can then either define your language in this package or in an implementation package which uses it: the package has imported all of the external symbols from &lt;code&gt;CL&lt;/code&gt; other than the ones it overrides, so it doesn&amp;rsquo;t need to use the &lt;code&gt;CL&lt;/code&gt; package at all.&lt;/p&gt;

&lt;p&gt;The benefit of doing things this way is that it means that every user of this system doesn&amp;rsquo;t have to care about the details of it and isn&amp;rsquo;t forced to change their code because of implementation changes. That&amp;rsquo;s worth it, even though writing the &lt;code&gt;defpackage&lt;/code&gt; forms is laborious: you should do the work, not every user of your systm.&lt;/p&gt;

&lt;p&gt;Of course, in real life you would not have to remember the names of all the symbols you are reexporting: you&amp;rsquo;d write a program to do it for you. You&amp;rsquo;d write, in fact, a macro.&lt;/p&gt;

&lt;p&gt;Well other people have already done that for you, in particular I did this in 1998 when I decided that this idea was interesting. Other people have since done similar things I think and may have done so before me, but I will describe my version: &lt;a href="https://github.com/tfeb/conduit-packages" title="Conduit packages"&gt;conduit packages&lt;/a&gt;. In particular I&amp;rsquo;ll mostly describe the functionality exported from the &lt;code&gt;ORG.TFEB.CONDUIT-PACKAGES/DEFINE-PACKAGE&lt;/code&gt; package, which doesn&amp;rsquo;t replace macros like &lt;code&gt;defpackage&lt;/code&gt; and functions like &lt;code&gt;export&lt;/code&gt;, but rather provides functionality under different names.&lt;/p&gt;

&lt;p&gt;The basic notion is that packages can be &lt;em&gt;conduits&lt;/em&gt; for one or more other packages: they serve to gather together and reexport subsets of the exported names from the packages for which they are conduits. &lt;code&gt;define-package&lt;/code&gt; lets you define conduit packages easily, and &lt;code&gt;define-conduit-package&lt;/code&gt; is even more specialised to the task.&lt;/p&gt;

&lt;p&gt;Here is how you would define the package above&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(define-package :my-language
  (:use)
  (:export #:if #:cond #:else)
  (:extends/excluding :cl
   #:if #:cond))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or with &lt;code&gt;define-conduit-package&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(define-conduit-package :my-language
  (:export #:if #:cond #:else)
  (:extends/excluding :cl
   #:if #:cond))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can quite happily define your language as before.&lt;/p&gt;

&lt;p&gt;This works, of course, even if your package wants to extend other packages whose exports might change in a way that &lt;code&gt;CL&lt;/code&gt;&amp;rsquo;s are unlikely to do any time soon: the symbols to import &amp;amp; reexport are computed based on the state of the package system at the time the form is evaluated. In some cases &amp;mdash; if the package you are extending is itself known to the system &amp;mdash; the packages will be dynamically recomputed:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (define-package :foo
    (:export #:one))
#&amp;lt;The FOO package, 0/16 internal, 1/16 external&amp;gt;

&amp;gt; (define-conduit-package :bar
    (:extends :foo))
#&amp;lt;The BAR package, 0/16 internal, 1/16 external&amp;gt;

&amp;gt; (do-external-symbols (s :bar (values)) (print (symbol-name s)))

"ONE"

&amp;gt; (define-package :foo
    (:export #:one #:foo))
Warning: Using DEFPACKAGE to modify #&amp;lt;The FOO package, 0/16 internal, 1/16 external&amp;gt;.
#&amp;lt;The FOO package, 0/16 internal, 2/16 external&amp;gt;

&amp;gt; (do-external-symbols (s :bar (values)) (print (symbol-name s)))

"FOO"
"ONE"&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And thus was the abominable shadow cast into the outer darkness.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;A remaining question is: are there good uses for shadowing? Well, conduit packages itself uses them in its implementation package, mostly because I was too lazy to write the code which would explicitly map over &lt;code&gt;CL&lt;/code&gt;. And there must, I suppose, be other good uses, but it&amp;rsquo;s very hard to think of them. The other common case, where you want to use two packages which export the same names, is dealt with by simply using a conduit of course.&lt;/p&gt;

&lt;p&gt;I think it&amp;rsquo;s worth remembering that when the CL package system was initially defined, people didn&amp;rsquo;t really understand how such a thing should work. MACLISP didn&amp;rsquo;t have a package system, Lisp Machine Lisp probably did (certainly Zetalisp did), but there was no great experience with what a package system should be like. Indeed the first CL version didn&amp;rsquo;t have &lt;code&gt;defpackage&lt;/code&gt;: instead you had to construct packages by hand, and there were all sorts of weirdnesses in the way the compiler handled &lt;code&gt;make-package&lt;/code&gt; and other package functions (or you had to use &lt;code&gt;eval-when&lt;/code&gt; all over the place).&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Finally, when I wrote conduit packages I was still thinking that packages were big expensive objects, because in the late 1980s they were, and I hadn&amp;rsquo;t yet realised that this was no longer true. In the late 1980s a big workstation on which you ran CL might have had 16MB of memory. Today laptops have perhaps a thousand times as much memory: data structures which ate a lot of precious memory in 1990 don&amp;rsquo;t any more. So I think, today, it&amp;rsquo;s appropriate to use packages in a fairly fine-grained way: having a few extra packages really is not hurting you very much.&lt;/p&gt;

&lt;p&gt;So here is another way to define the little language above.&lt;/p&gt;

&lt;p&gt;First, define a conduit for &lt;code&gt;CL&lt;/code&gt; which exports just the symbols you want:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(define-conduit-package :my-language/cl
  (:extends/excluding :cl
   #:if #:cond))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now define the implementation package for the language: this exports the new symbols:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(define-package :my-language/impl
  (:use :my-language/cl)
  (:export
   #:if #:cond #:else))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, finally, define the public package, which is a conduit for both &lt;code&gt;MY-LANGUAGE/CL&lt;/code&gt; and &lt;code&gt;MY-LANGUAGE/IMPL&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(define-conduit-package :my-language
  (:extends :my-language/cl :my-language/impl))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is absurd overkill in this tiny example, but for real examples, where there might be several implementation packages, it lets you split things up in a nice way, while not burdening your users with lots of tiny packages.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Monochrome</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2024/05/20/monochrome/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2024-05-20-monochrome</id>
  <published>2024-05-20T08:58:05Z</published>
  <updated>2024-05-20T08:58:05Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Or, why limitations matter.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;After we released Štar, my friend Zyni had a rather distressing and inconclusive exchange with someone on reddit. Apart from making me feel even better about walking away from reddit a decade and more ago, I realised an interesting thing when talking to her about her experience.&lt;/p&gt;

&lt;h2 id="limitations"&gt;Limitations&lt;/h2&gt;

&lt;p&gt;Here are some curious things that people do.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Why, in 2024, would anyone use a digital camera which can only make monochrome pictures?&lt;/li&gt;
 &lt;li&gt;Why, in 2024, would anyone use a film camera?&lt;/li&gt;
 &lt;li&gt;Why, in 2024, would anyone record music in a studio which uses tape?&lt;/li&gt;
 &lt;li&gt;Why, in 2024, would any guitarist use a collection of flaky old FX pedals connected by noisy and unreliable cables, and a valve amplifier which occasionally catches fire&lt;sup&gt;&lt;a href="#2024-05-20-monochrome-footnote-1-definition" name="2024-05-20-monochrome-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;?&lt;/li&gt;
 &lt;li&gt;Why, in 2024, would anyone shoot a movie on film?&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Yet people do all these things: there are at least two manufacturers of dedicated monochrome cameras, and you can pay to have your colour digital camera converted to monochrome by removing the filter array; many people use film; studios which use tape still exist and probably are becoming more common; too many guitarists to count use elderly FX pedals, a nest of cables and a valve amplifier; many very famous recent movies have been made on film.&lt;/p&gt;

&lt;p&gt;There is, of course, a lot of myth and lore about the special magic properties of these things: people go on endlessly about how monochrome digital sensors have more effective resolution than Bayer sensors, as if anyone needs more resolution today, or how the effective sensitivity is higher, as if anyone needs more sensitivity today. The same for film (no, it&amp;rsquo;s not magic, no, it&amp;rsquo;s not somehow better than digital in any objective way), analogue recording, old FX pedals and amplifiers, and movies made on film. If you really think movies made on film are somehow better or &amp;lsquo;more natural&amp;rsquo;, watch &lt;em&gt;The Holdovers&lt;/em&gt;, which was shot digitally but is a really beautiful simulacrum of what movies looked like in about 1972.&lt;/p&gt;

&lt;p&gt;The awful truth is that none of these technologies get you anything objectively better, &lt;em&gt;even if what you want to do is reproduce what people did when those technologies were all there was&lt;/em&gt;. You can simulate film so well it is impossible to tell the difference, you can simulate analogue tape just as well. Modern digital FX/amplification systems for guitar are a wonder. You can produce really beautiful monochrome images from colour files.&lt;/p&gt;

&lt;p&gt;So why, really, do people do these things?&lt;/p&gt;

&lt;p&gt;The clue, for me, is in the first one: why would anyone use a dedicated monochrome digital camera? Why would I use one if I could afford to? The answer, for me and others, is &lt;em&gt;because it restricts what you can do&lt;/em&gt;. If your camera will only do monochrome, then &lt;em&gt;that&amp;rsquo;s all you can do&lt;/em&gt;, and somehow that matters. I can&amp;rsquo;t afford a monochrome-only digital camera, but I do use a digital camera which has a monochrome-only workflow (this is why I bought it, in fact): the camera sets a &amp;lsquo;monochrome&amp;rsquo; flag in its files which the raw-conversion tool understands, and unless you work hard you never see a colour version of the photographs you&amp;rsquo;ve taken. And this matters to me: it needs to be difficult to overcome the limitation, so I can think in monochrome&lt;sup&gt;&lt;a href="#2024-05-20-monochrome-footnote-2-definition" name="2024-05-20-monochrome-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;And of course I use film as well, and mostly black and white film with some recent excursions into colour reversal (slide) film. Partly I do this because I enjoy working in the darkroom and the tactile quality of film cameras from the 1980s and before, but more important, I think, is how limiting film is. Once you&amp;rsquo;ve taken a picture, it&amp;rsquo;s there: you can&amp;rsquo;t chimp and decide to do it again. You have 36 (or 10, or 1) exposures before you have to change film: every frame matters. Film can&amp;rsquo;t see in the dark. Mostly it can&amp;rsquo;t even see in colour (reversal film is now absurdly expensive). 35mm film is always going to have grain. Making photographs using film is a festival of limitations.&lt;/p&gt;

&lt;p&gt;It turns out that, for many people, &lt;em&gt;limitations matter&lt;/em&gt;. If you take them away, then suddenly you can do anything. So you spend your time fiddling with the parameters of what you &lt;em&gt;can&lt;/em&gt; do, and doing nothing as a result, rather than being forced to pull your finger out and do &lt;em&gt;something&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s why many people make photographs with monochrome cameras, or on film. That&amp;rsquo;s why people still make movies on film. That&amp;rsquo;s why people paint or draw, rather than using some vast digital image-creation system. That&amp;rsquo;s why people write books on typewriters, or with a pen. That&amp;rsquo;s why Colin Chapman designed cars the way he did, and why more than 160 companies have made (and still do make) replicas of one of his designs.&lt;/p&gt;

&lt;p&gt;Not everyone: not even most people. But some people. Enough people.&lt;/p&gt;

&lt;p&gt;And it&amp;rsquo;s not enough to simply say &amp;lsquo;I won&amp;rsquo;t use all the features I do not want&amp;rsquo;: those features need &lt;em&gt;not to be there&lt;/em&gt;. Using a camera which can only make monochrome images is &lt;em&gt;not like&lt;/em&gt; using a camera which can make colour images but choosing not to. Choosing not to chimp is &lt;em&gt;not like&lt;/em&gt; being unable to chimp. Using a film camera is &lt;em&gt;not like&lt;/em&gt; using a digital camera and film simulation. Drawing with a pencil on paper is &lt;em&gt;not like&lt;/em&gt; using a drawing program but choosing only to use the pencil tool, however good that tool is. Limitations have to be, well, limitations. I don&amp;rsquo;t know why this is, but they do.&lt;/p&gt;

&lt;h2 id="štar"&gt;Štar&lt;/h2&gt;

&lt;p&gt;And that&amp;rsquo;s why Štar exists: because it&amp;rsquo;s limited, because it does &lt;em&gt;one thing&lt;/em&gt;. Because there is as little syntax as we could make there be. In Štar &lt;em&gt;everything&lt;/em&gt; is an iterator&lt;sup&gt;&lt;a href="#2024-05-20-monochrome-footnote-3-definition" name="2024-05-20-monochrome-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt; so any expression like&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(for ((&amp;lt;var/s&amp;gt; &amp;lt;iterator&amp;gt;))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;can be turned into&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(multiple-value-bind (v c) &amp;lt;iterator&amp;gt;
  (for ((&amp;lt;var/s&amp;gt; (values v c)))
    ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And it will mean exactly the same thing, although often it will be slower&lt;sup&gt;&lt;a href="#2024-05-20-monochrome-footnote-4-definition" name="2024-05-20-monochrome-footnote-4-return"&gt;4&lt;/a&gt;&lt;/sup&gt;. And &lt;em&gt;all&lt;/em&gt; clauses are like that. There is &lt;em&gt;only one case&lt;/em&gt;: the form on the right-hand side of a clause is a perfectly general expression evaluated, once, in the way you think it will be. There is no magic syntax, at all. And because Štar does only one thing &amp;mdash; iterate &amp;mdash; it &lt;em&gt;forces&lt;/em&gt; you to use other tools to do other things, and to make sure all these tools compose well with each other. There was once a famous operating system whose designers played the same trick.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.dreamsongs.com/WorseIsBetter.html" title="Worse is better"&gt;Richard Gabriel&amp;rsquo;s famous essay&lt;/a&gt;, usually known as &lt;a href="https://www.dreamsongs.com/RiseOfWorseIsBetter.html" title="The rise of worse is better"&gt;&lt;em&gt;Worse is better&lt;/em&gt;&lt;/a&gt;, is celebrated for describing the difference between &lt;em&gt;right thing&lt;/em&gt; systems and &lt;em&gt;worse is better&lt;/em&gt; systems&lt;sup&gt;&lt;a href="#2024-05-20-monochrome-footnote-5-definition" name="2024-05-20-monochrome-footnote-5-return"&gt;5&lt;/a&gt;&lt;/sup&gt;. It is less celebrated for another distinction it made amongst the right thing systems. That distinction is between &lt;em&gt;big complex systems&lt;/em&gt; and &lt;em&gt;diamond-like jewel&lt;/em&gt; systems:&lt;/p&gt;

&lt;blockquote&gt;
 &lt;p&gt;The &lt;em&gt;big complex system&lt;/em&gt; scenario goes like this:&lt;/p&gt;
 &lt;p&gt;First, the right thing needs to be designed. Then its implementation needs to be designed. Finally it is implemented. Because it is the right thing, it has nearly 100% of desired functionality, and implementation simplicity was never a concern so it takes a long time to implement. It is large and complex. It requires complex tools to use properly. The last 20% takes 80% of the effort, and so the right thing takes a long time to get out, and it only runs satisfactorily on the most sophisticated hardware.&lt;/p&gt;
 &lt;p&gt;The &lt;em&gt;diamond-like jewel&lt;/em&gt; scenario goes like this:&lt;/p&gt;
 &lt;p&gt;The right thing takes forever to design, but it is quite small at every point along the way. To implement it to run fast is either impossible or beyond the capabilities of most implementors.&lt;/p&gt;
 &lt;p&gt;The two scenarios correspond to Common Lisp and Scheme.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Štar aspires to be the diamond-like jewel of iteration frameworks. Its interface is tiny: &lt;code&gt;org.tfeb.*&lt;/code&gt; exports six symbols, four of which could be removed with no loss of functionality&lt;sup&gt;&lt;a href="#2024-05-20-monochrome-footnote-6-definition" name="2024-05-20-monochrome-footnote-6-return"&gt;6&lt;/a&gt;&lt;/sup&gt;. But it aims to be general and to be able to turn this clean, minimal syntax into fast code: apart from the catalogue of built-in iterators, almost all the rest of the interface is to the tools that let you do this for your own iterators.&lt;/p&gt;

&lt;p&gt;It may seem odd that Štar is written in Common Lisp, not Scheme, but CL is what we actually use and so producing tools which turn CL into the system we&amp;rsquo;d like to have is what we care about. In my case, I also remember the movement to reexpress CL as a small core language combined with libraries.&lt;/p&gt;

&lt;p&gt;Štar is not for everybody. If you like &lt;code&gt;loop&lt;/code&gt; you probably will hate it (but you have no taste, so we don&amp;rsquo;t care). If you are an adherent of the big complex system school you probably won&amp;rsquo;t like it either (and we respect your opinion). That&amp;rsquo;s not who Štar is for: Štar is for the people who appreciate the diamond-like jewel, who believe that limitations matter, in a deep way.&lt;/p&gt;

&lt;p&gt;If that&amp;rsquo;s not for you, that is completely fine: not everybody is the same: not everyone wants a monochrome camera, and not everyone knew, or liked if they did know, that famous operating system&lt;sup&gt;&lt;a href="#2024-05-20-monochrome-footnote-7-definition" name="2024-05-20-monochrome-footnote-7-return"&gt;7&lt;/a&gt;&lt;/sup&gt;. Some people even like &lt;code&gt;loop&lt;/code&gt;, apparently. But understand that it &lt;em&gt;is&lt;/em&gt; for some people, and try to avoid sneering at them, if you can.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2024-05-20-monochrome-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;Well-maintained valve amplifiers hardly ever catch fire. Often they are also electrically safe.&amp;nbsp;&lt;a href="#2024-05-20-monochrome-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2024-05-20-monochrome-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;Why a photographer or a movie maker would &lt;em&gt;want&lt;/em&gt; to work in monochrome is another, related question: why, in 2024, intentionally throw away all the colour information in a scene?&amp;nbsp;&lt;a href="#2024-05-20-monochrome-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2024-05-20-monochrome-footnote-3-definition" class="footnote-definition"&gt;
   &lt;p&gt;In this way, Štar is like some Scheme compilers which turn everything into \(\lambda\) expressions and then try to make those expressions quick.&amp;nbsp;&lt;a href="#2024-05-20-monochrome-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2024-05-20-monochrome-footnote-4-definition" class="footnote-definition"&gt;
   &lt;p&gt;One of the things Štar&amp;rsquo;s tests do is exactly this transformation as a way of testing that iterator optimizers do not change the semantics of the program.&amp;nbsp;&lt;a href="#2024-05-20-monochrome-footnote-4-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2024-05-20-monochrome-footnote-5-definition" class="footnote-definition"&gt;
   &lt;p&gt;Entertainingly, that famous operating system is often disparaged as an example of worse is better. In terms of its implementation that may be justified: its ideas are certainly &lt;em&gt;not&lt;/em&gt; examples of worse is better.&amp;nbsp;&lt;a href="#2024-05-20-monochrome-footnote-5-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2024-05-20-monochrome-footnote-6-definition" class="footnote-definition"&gt;
   &lt;p&gt;We have argued, at length, about this. We decided that, just as Scheme includes &lt;code&gt;let&lt;/code&gt; and, even more extravagantly, &lt;code&gt;let*&lt;/code&gt;, Štar should include &lt;code&gt;final&lt;/code&gt;, &lt;code&gt;for*&lt;/code&gt; and &lt;code&gt;final*&lt;/code&gt;. In the language of the Scheme reports, they are library syntax (&lt;code&gt;for*&lt;/code&gt;) and library procedures (&lt;code&gt;final&lt;/code&gt;, &lt;code&gt;final*&lt;/code&gt;, &lt;code&gt;next*&lt;/code&gt; which serves no purpose without &lt;code&gt;for*&lt;/code&gt;).&amp;nbsp;&lt;a href="#2024-05-20-monochrome-footnote-6-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2024-05-20-monochrome-footnote-7-definition" class="footnote-definition"&gt;
   &lt;p&gt;There&amp;rsquo;s a book about that.&amp;nbsp;&lt;a href="#2024-05-20-monochrome-footnote-7-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Štar: an iteration construct for Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2024/05/15/an-iteration-construct-for-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2024-05-15-an-iteration-construct-for-common-lisp</id>
  <published>2024-05-15T06:37:18Z</published>
  <updated>2024-05-15T06:37:18Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Štar is a concise and extensible iteration construct for Common Lisp which aims to be pleasant to use, easy to understand, fast if needed, general, and not to look like Fortran.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Common Lisp has multiple iteration constructs: mapping functions such as &lt;code&gt;mapcar&lt;/code&gt;, special-purpose constructs such as &lt;code&gt;dotimes&lt;/code&gt; and &lt;code&gt;dolist&lt;/code&gt;, the general but somewhat clumsy construct which is &lt;code&gt;do&lt;/code&gt; and &lt;code&gt;do*&lt;/code&gt;, and finally the extended &lt;code&gt;loop&lt;/code&gt; macro which aims to embed a &amp;lsquo;more friendly&amp;rsquo; iteration language into CL and succeeds in being so complex that it is often hard to know whether a given form is legal or not without poring over &lt;code&gt;loop&lt;/code&gt;&amp;rsquo;s grammar.&lt;/p&gt;

&lt;p&gt;None of these constructs manage to be all three of pleasant to use, easy to understand and general. &lt;code&gt;loop&lt;/code&gt; somehow fails to be any of these things in many cases. None are extensible&lt;sup&gt;&lt;a href="#2024-05-15-an-iteration-construct-for-common-lisp-footnote-1-definition" name="2024-05-15-an-iteration-construct-for-common-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;But Common Lisp is a Lisp, and Lisp&amp;rsquo;s huge advantage is that it is a programming language in which it is easy to write programming languages, or parts of them, like iteration constructs. That is, after all, how most or all of the existing constructs started life.&lt;/p&gt;

&lt;p&gt;Lots of these have been written, of course. Štar tries to distinguish itself by being as simple as possible: it has as little special syntax as I could work out how to give it – there is no special little language you need to learn. It also has no inherent knowledge about how to iterate over any particular structure: it doesn&amp;rsquo;t know how to iterate over lists, or ranges of numbers. Rather it knows that iterating has to answer two questions:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;is there more?&lt;/li&gt;
 &lt;li&gt;what is the next thing?&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;In addition it knows how to ask another question:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;is there any information I can use to make asking the first two questions faster?&lt;/li&gt;&lt;/ul&gt;

&lt;h2 id="what-it-looks-like"&gt;What it looks like&lt;/h2&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(for ((e (in-list l)))
  (print e))

(for (((k v) (in-hash-table h)))
  ...)

(for* ((entry (in-list entries))
       (element (in-list entry)))
  ...)

(defun in-alist (alist)
  (values
    (lambda () (not (null alist)))
    (lambda ()
      (destructuring-bind ((k . v) . more) alist
        (setf alist more)
        (values k v)))))

(for (((k v) (in-alist ...)))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These are some simple examples: the last shows how easy it is to teach Štar to iterate over new things, or over existing things in new ways. Not shown here is that it&amp;rsquo;s also pretty easy to teach it how to optimize new iterators and to make various declarations about things.&lt;/p&gt;

&lt;h2 id="what-štar-is-not"&gt;What Štar is not&lt;/h2&gt;

&lt;p&gt;Štar is an &lt;em&gt;iteration construct&lt;/em&gt;: what it does is to iterate. It has nothing to do with collecting values. For Štar, iteration and value accumulation are orthogonal problems which should be solved by orthogonal constructs. In particular if you wanted to make a list of the even numbers from a list, you might to this by using Štar together with a value-collection macro:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(collecting
  (for ((e (in-list ...)))
    (when (evenp e)
      (collect e))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is yet another way in which Štar differs from &lt;code&gt;loop&lt;/code&gt; and many other constructs. In particular Štar&amp;rsquo;s point of view is that mixing together iteration and value accumulation results in a system that is not very good at either.&lt;/p&gt;

&lt;p&gt;Similarly, Štar doesn&amp;rsquo;t contain a mass of syntax letting you select only certain values, or allowing you to terminate iteration early: you don&amp;rsquo;t write&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(loop for x in l while (numberp x) do ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Instead you write&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(for ((x (in-list l)))
  (unless (numberp x) (final))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The body of an iteration is exactly like the body of &lt;code&gt;defun&lt;/code&gt;, except there are some local functions which you can call to skip to the next iteration or finish the iteration.&lt;/p&gt;

&lt;p&gt;Štar, of course, doesn&amp;rsquo;t bundle some destructuring system which will inevitably be subtly incompatible with other destructuring systems while also not being usable independently. If you want destructuring, use a full-fat system of your choice.&lt;/p&gt;

&lt;p&gt;You probably get the idea: Štar is a tool whose job is to iterate: not some leaking bag of broken abstractions.&lt;/p&gt;

&lt;h2 id="multiple-values"&gt;Multiple values&lt;/h2&gt;

&lt;p&gt;One thing that Štar &lt;em&gt;does&lt;/em&gt; do is to take multiple values seriously. A clause which specifies a list of variables will bind them to the multiple values returned by the iterator. Multiple values, unlike destructuring, are something you really have to have in the iteration construct itself.&lt;/p&gt;

&lt;h2 id="the-thing-that-doesnt-really-matter-but-everyone-cares-about"&gt;The thing that doesn&amp;rsquo;t really matter but everyone cares about&lt;/h2&gt;

&lt;p&gt;So, OK, Štar is an extensible, general, iteration construct. Obviously it will have traded performance for all this. I mean, it&amp;rsquo;s the old Lisp story, &lt;a href="https://www.dreamsongs.com/WorseIsBetter.html" title="Worse is better"&gt;the one Gabriel told us&lt;/a&gt; long ago. Right?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;* Running benchmarks
** lists of length 2000, nesting 3
what                                                  seconds      ratio
star                                                   30.312      1.000
loop                                                   30.071      0.992
dolist                                                 21.594      0.712
** range 100000, nesting 2
what                                                  seconds      ratio
star/with-step                                          9.414      1.000
star/no-step                                            9.406      0.999
loop                                                   18.412      1.956
dotimes                                                 9.469      1.006&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="a-sketch-of-štar"&gt;A sketch of Štar&lt;/h2&gt;

&lt;p&gt;Štar has three parts, four if you count the iterators:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;the iteration constructs themselves and bindings they make;&lt;/li&gt;
 &lt;li&gt;a protocol for defining new iterators;&lt;/li&gt;
 &lt;li&gt;a protocol for defining optimizers for iterators;&lt;/li&gt;
 &lt;li&gt;a collection of predefined iterators and optimizers for them.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The first three parts are much more finished than the fourth: most of the existing iterators were written as proofs of concept and may well change, get better, or go away.&lt;/p&gt;

&lt;h3 id="iterators"&gt;Iterators&lt;/h3&gt;

&lt;p&gt;These are forms (usually, named function calls) which return two values, both functions of no arguments:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;the first value is called and should return true if there is more to do;&lt;/li&gt;
 &lt;li&gt;the second value is called to return the next value or values of the iterator.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;These functions answer the first two questions Štar needs to ask: is there more, and if there is, what is it? These two functions obviously share state in general.&lt;/p&gt;

&lt;p&gt;To answer the third question – how do I make things faster? – named iterator functions can have &lt;em&gt;optimizers&lt;/em&gt;: these are functions called by Štar at macroexpansion time which tell it how to make things faster. It&amp;rsquo;s up to an optimizer to ensure the semantics are the same for the optimized and unoptimized versions. Optimizers can specify a set of bindings to make, declarations for them, how to iterate, and some other things.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s possible to install and remove optimizers, and to dynamically bind sets of them. This might be useful, for instance, to compile a file where some particular assumptions (&amp;lsquo;all vectors are vectors of floats&amp;rsquo;) are true.&lt;/p&gt;

&lt;h3 id="iteration-constructs"&gt;Iteration constructs&lt;/h3&gt;

&lt;p&gt;There are two:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;for&lt;/code&gt; iterates in parallel;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;for*&lt;/code&gt; defines nested loops: &lt;code&gt;(for* ((...) (...)) ...)&lt;/code&gt; is like &lt;code&gt;(for ((...)) (for ((...)) ...))&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Note that because of the way iterators work, sequential binding within one loop makes no sense.&lt;/p&gt;

&lt;p&gt;The first argument of &lt;code&gt;for&lt;/code&gt; or &lt;code&gt;for*&lt;/code&gt; specifies a number of clauses: each clause is of the form &lt;code&gt;&amp;lt;var/s&amp;gt; &amp;lt;iterator&amp;gt;)&lt;/code&gt;. Multiple values are supported, and it is possible to make various declarations about variables: this matters for &lt;code&gt;for*&lt;/code&gt;, where there is no room for declarations for other than the last (innermost) clause. Variables whose name is &lt;code&gt;"_"&lt;/code&gt; are ignored by default.&lt;/p&gt;

&lt;p&gt;Within the body of an iteration there are four local functions:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;next&lt;/code&gt; skips to the next iteration;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;next*&lt;/code&gt; skips to the next outer-level iteration for &lt;code&gt;for*&lt;/code&gt; and is the same as &lt;code&gt;next&lt;/code&gt; for &lt;code&gt;for&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;final&lt;/code&gt; returns zero or more values from the current iteration&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;final*&lt;/code&gt; returns zero or more values for the outer-level iteration for &lt;code&gt;for*&lt;/code&gt; and is the same as &lt;code&gt;final&lt;/code&gt; for &lt;code&gt;for&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;h3 id="provided-iterators"&gt;Provided iterators&lt;/h3&gt;

&lt;p&gt;There are iterators which work for lists, vectors, general sequences, hash tables, ranges of reals, as well as some more interesting ones. Not all iterators currently have optimizers. You only need to care about writing optimizers if you need to make iterators very fast: they can be significantly fiddly to write.&lt;/p&gt;

&lt;p&gt;The iterator over ranges of reals has an optimizer which tries hard to make things pretty fast.&lt;/p&gt;

&lt;p&gt;As well as this there are some more interesting iterators. An example is &lt;code&gt;sequentially&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(for ((a (sequentially 1 2)))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will bind &lt;code&gt;a&lt;/code&gt; sequentually to &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt;. But this iterator is a macro which has the behaviour of a FEXPR, so it evaluates its arguments only when needed (and as many times as needed). A variant of &lt;code&gt;sequentially&lt;/code&gt; is &lt;code&gt;sequentially*&lt;/code&gt; which &amp;lsquo;sticks&amp;rsquo; on its last argument. So for instance:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((v 0))
    (for ((a (sequentially* (incf v)))
          (_ (in-range 3)))
      (print a)))

1 
2 
3 &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Another way to write this is:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (for ((a (let ((v 0)) (sequentially* (incf v))))
        (_ (in-range 4)))
    (print a))

1 
2 
3 
4 &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And of course there is a meta-iterator (also implemented as a macro), &lt;code&gt;in-iterators&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (for ((a (in-iterators
            (in-list '(1 2))
            (in-list '(3 4)))))
    (print a))

1 
2 
3 
4 &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&amp;rsquo;s possible to construct very general iterators with tools like this.&lt;/p&gt;

&lt;p&gt;As I said above, Štar&amp;rsquo;s current iterators are in a fairly rough state: a lot of this might change.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id="notes"&gt;Notes&lt;/h2&gt;

&lt;h3 id="declarations"&gt;Declarations&lt;/h3&gt;

&lt;p&gt;A form like&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(for* ((a (in-range 10))
       (b (in-range 10)))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;corresponds roughly to&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(for ((a (in-range 10)))
  (for ((b (in-range 10)))
    ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The problem is now how to make declarations which apply to &lt;code&gt;a&lt;/code&gt;. This is hard because CL doesn&amp;rsquo;t provide the tools you need to know whether a declaration refers to a variable or not: to know whether &lt;code&gt;(declare (foo a))&lt;/code&gt; refers to &lt;code&gt;a&lt;/code&gt; or not you need to know, at least, whether &lt;code&gt;foo&lt;/code&gt; names a type, which you can&amp;rsquo;t do. You often can guess, but not always.&lt;/p&gt;

&lt;p&gt;So, rather than trying to solve an intractable problem, Štar lets you specify some properties of a variable in the clause that binds it: you can say&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(for* (((a :type fixnum) (in-range 10))
       (b (in-range 10)))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;for instance. This is a bit ugly, but it solves the problem. It is only useful for &lt;code&gt;for*&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id="binding"&gt;Binding&lt;/h3&gt;

&lt;p&gt;Štar binds, rather than assigns:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(collecting
  (for ((a (in-list 1 2)))
    (collect
      (lambda (&amp;amp;optional (v vp))
        (if vp (setf a v) a)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will return two closures over independent bindings.&lt;/p&gt;

&lt;h2 id="epilogue"&gt;Epilogue&lt;/h2&gt;

&lt;p&gt;Štar&amp;rsquo;s source code is &lt;a href="https://github.com/tfeb/star"&gt;here&lt;/a&gt;. The manual is included with the source code but also &lt;a href="https://tfeb.github.io/star/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Štar is pronounced roughly &amp;lsquo;shtar&amp;rsquo;.&lt;/p&gt;

&lt;p&gt;Much of the inspiration for Štar came from my friend Zyni: thanks to her for the inspiration behind it, actually making me write it and for many other things.&lt;/p&gt;

&lt;p&gt;Štar is dedicated to her, and to Ian Anderson.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2024-05-15-an-iteration-construct-for-common-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;Some implementations have mechanisms for extending &lt;code&gt;loop&lt;/code&gt;.&amp;nbsp;&lt;a href="#2024-05-15-an-iteration-construct-for-common-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Symbol nicknames: a broken toy</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/10/12/symbol-nicknames-a-broken-toy/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-10-12-symbol-nicknames-a-broken-toy</id>
  <published>2023-10-12T14:08:27Z</published>
  <updated>2023-10-12T14:08:27Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;&lt;a href="https://github.com/tfeb/symbol-nicknames"&gt;Symbol nicknames&lt;/a&gt; allows multiple names to refer to the same symbol in supported implementations of Common Lisp. That may or may not be useful.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;People often say the Common Lisp package system is deficient. But a lot of the same people write code which is absolutely full of explicit package prefixes in what I can only suppose is an attempt to make programs harder to read. Somehow this is meant to be made better by using package-local nicknames for packages. And let&amp;rsquo;s not mention the unspeakable idiocy that is thinking that a package name like, say, &lt;code&gt;XML&lt;/code&gt; is suitable for any kind of general use at all. So forgive me if I don&amp;rsquo;t take their concerns too seriously.&lt;/p&gt;

&lt;p&gt;The CL package system can&amp;rsquo;t do all the things something like the Racket module system can do. But it&amp;rsquo;s not clear that, given its job of collecting symbols into, well, packages, it could do that much more than it currently does. Probably some kind of &amp;lsquo;package universe&amp;rsquo; notion such as Symbolics Genera had would be useful. But the namespace has to be anchored &lt;em&gt;somewhere&lt;/em&gt;, and if you&amp;rsquo;re willing to give packages domain-structured names in the obvious way &lt;em&gt;and&lt;/em&gt; spend time actually constructing a namespace for the language you want to use, it&amp;rsquo;s perfectly pleasant in my experience.&lt;/p&gt;

&lt;p&gt;One thing that &lt;em&gt;might&lt;/em&gt; be useful is to allow multiple names to refer to the same symbol. So for instance you might want to have &lt;code&gt;eq?&lt;/code&gt; be the same symbol as &lt;code&gt;eq&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (setf (nickname-symbol "EQ?") 'eq)
eq

&amp;gt; (eq 'eq? 'eq)
t

&amp;gt; (eq? 'eq 'eq?)
t&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This allows you to construct languages which have different names for things, but where the names are translated to the underlying name efficiently. As another example, let&amp;rsquo;s say you wanted to call &lt;code&gt;eql&lt;/code&gt; &lt;code&gt;equivalent-p&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (setf (nickname-symbol "EQUIVALENT-P") 'eql)
eql

&amp;gt; (eql 'eql 'equivalent-p)
t&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, now you can use &lt;code&gt;equivalent-p&lt;/code&gt; as a synonym for &lt;code&gt;eql&lt;/code&gt; &lt;em&gt;wherever&lt;/em&gt; it occurs:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (defmethod foo ((x (equivalent-p 1)))
    "x is 1")
#&amp;lt;standard-method foo nil ((eql 1)) 801005BD23&amp;gt;

&amp;gt; (foo 1)
"x is 1"&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Symbol nicknames is not completely portable as it requires hooking string-to-symbol lookup. It is supported in LispWorks and SBCL currently: it will load in other Lisps but will complain that it can&amp;rsquo;t infect them.&lt;/p&gt;

&lt;p&gt;Symbol nicknames is also not completely compatible with CL. In CL you can assume that &lt;code&gt;(find-symbol "FOO")&lt;/code&gt; either returns a symbol whose name is &lt;code&gt;"FOO"&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt; and &lt;code&gt;nil&lt;/code&gt;: with symbol nicknames you can&amp;rsquo;t. In the case where a nickname link has been followed the second value of &lt;code&gt;find-symbol&lt;/code&gt; will be &lt;code&gt;:nickname&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Symbol nicknames is a toy. I am not convinced that the idea is even useful, and if it is it probably needs to be thought about more than I have.&lt;/p&gt;

&lt;p&gt;But it exists.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">A horrible solution</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/05/04/a-horrible-solution/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-05-04-a-horrible-solution</id>
  <published>2023-05-04T11:33:41Z</published>
  <updated>2023-05-04T11:33:41Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;&lt;a href="https://www.tfeb.org/fragments/2023/05/03/two-sides-to-hygiene/"&gt;Yesterday&lt;/a&gt; I wrote an article describing one of the ways traditional Lisp macros can be unhygienic even when they appear to be hygienic. Here&amp;rsquo;s a horrible solution to that.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;The problem I described is that the expansion of a macro can refer to the values (usually the function values) of names, which the &lt;em&gt;user&lt;/em&gt; of the macro can bind, causing the macro to fail. So, given a function&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun call-with-foo (thunk)
  ...
  (funcall thunk))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then the macro layer on top of it&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro with-foo (&amp;amp;body forms)
  `(call-with-foo (lambda () ,@forms)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;is not hygienic so long as local functions named &lt;code&gt;call-with-foo&lt;/code&gt; are allowed:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(flet ((call-with-foo (...) ...))
  (with-foo ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;em&gt;sensible&lt;/em&gt; solution to this is to say, just as the standard does about symbols in the &lt;code&gt;CL&lt;/code&gt; package that you are not allowed to do that.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s another solution:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro with-foo (&amp;amp;body forms)
  `(funcall (symbol-function 'call-with-foo) (lambda () ,@forms)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is robust against anything short of top-level redefinition of &lt;code&gt;call-with-foo&lt;/code&gt;. And you can be mostly robust even against that:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro with-foo (&amp;amp;body forms)
  `(funcall (load-time-value (symbol-function 'call-with-foo))
            (lambda () ,@forms)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This still isn&amp;rsquo;t safe against really malignant users, since the load time of the macro&amp;rsquo;s definition and its uses are not generally the same. But it&amp;rsquo;s probably fairly good.&lt;/p&gt;

&lt;p&gt;I hope I never feel I have to use techniques like this.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Two sides to hygiene</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/05/03/two-sides-to-hygiene/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-05-03-two-sides-to-hygiene</id>
  <published>2023-05-03T11:28:09Z</published>
  <updated>2023-05-03T11:28:09Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;It&amp;rsquo;s tempting to think that by being sufficiently careful about names bound by traditional Lisp macros you can write macros which are hygienic. This is not true: it&amp;rsquo;s much harder than that.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="hygienic-macros"&gt;Hygienic macros&lt;/h2&gt;

&lt;p&gt;I do not fully understand all the problems which &lt;a href="https://en.wikipedia.org/wiki/Hygienic_macro"&gt;Scheme-style hygienic macros&lt;/a&gt; try to solve, and the implementation of the solutions is usually sufficiently difficult to understand that I have always been put off doing so, especially as the details of the implementation in &lt;a href="https://racket-lang.org/"&gt;Racket&lt;/a&gt;, the Scheme-related language I use most, seems to &lt;a href="https://users.cs.utah.edu/plt/scope-sets/"&gt;change every few years&lt;/a&gt;. I&amp;rsquo;m happy enough that I am mostly competent to &lt;em&gt;write&lt;/em&gt; the macros I need in Racket, without understanding the details of the implementation.&lt;/p&gt;

&lt;p&gt;Traditional Lisp macros are, to me, far more appealing because they work in such an explicit and simple way: you could pretty easily write a macroexpander which did most of what the Common Lisp macroexpander does, for instance. I have written several toy versions of such a thing: I&amp;rsquo;m sure most Lisp people have. Traditional Lisp macros are just functions between bits of language expressed explicitly as s-expressions: what could be simpler?&lt;/p&gt;

&lt;p&gt;In fact I am reasonably confident that, if I had to choose one, I&amp;rsquo;d choose CL&amp;rsquo;s macros over Racket&amp;rsquo;s: writing macros in raw CL is a bit annoying because you need explicit gensyms and you need to do pattern matching yourself. But you can write, and I &lt;a href="https://tfeb.org/fragments/2022/09/26/metatronic-macros/"&gt;have&lt;/a&gt; &lt;a href="https://tfeb.org/fragments/2022/07/21/two-simple-pattern-matchers-for-common-lisp/"&gt;written&lt;/a&gt; tools to make most of this go away. With these, writing macros in CL can often be very pleasant. And it&amp;rsquo;s easy to understand what is going on.&lt;/p&gt;

&lt;p&gt;What is far harder though, is to make it completely hygienic. Here&amp;rsquo;s one reason why.&lt;/p&gt;

&lt;h2 id="several-versions-of-a-macro-in-common-lisp"&gt;Several versions of a macro in Common Lisp&lt;/h2&gt;

&lt;p&gt;Let&amp;rsquo;s imagine I want a macro which allows you to select actions based on the interval a real number is in. It might look like this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(interval-case x
  ((0 1) ...)
  ((1) 2) ...)
  (otherwise ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here intervals are specified the way they are in type specifiers for reals:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;(a b)&lt;/code&gt; where &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are reals means \([a,b]\);&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;((a) b)&lt;/code&gt; where &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are reals means \((a,b]\);&lt;/li&gt;
 &lt;li&gt;and so on.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;There can be only one interval per clause, for simplicity.&lt;/p&gt;

&lt;p&gt;I will write several versions of this macro. For all of them I will use &lt;a href="https://tfeb.github.io/#destructuring-match-for-common-lisp"&gt;dsm&lt;/a&gt; and, later, &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#metatronic-macros"&gt;metatronic macros&lt;/a&gt; to make things better.&lt;/p&gt;

&lt;p&gt;First of all here&amp;rsquo;s a function&lt;sup&gt;&lt;a href="#2023-05-03-two-sides-to-hygiene-footnote-1-definition" name="2023-05-03-two-sides-to-hygiene-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt; which, given an interval specification, returns a form which will match numbers in that interval:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun compute-interval-form (v iv)
  (destructuring-match iv
    (((l) (h))
     (:when (and (realp l) (realp h)))
     `(&amp;lt; ,l ,v ,h))
    ((l (h))
     (:when (and (realp l) (realp h)))
     `(and (&amp;lt;= ,l ,v) (&amp;lt; ,v ,h)))
    (((l) h)
     (:when (and (realp l) (realp h)))
     `(and (&amp;lt; ,l ,v) (&amp;lt;= v ,h)))
    ((l h)
     (:when (and (realp l) (realp h)))
     `(&amp;lt;= ,l ,v ,h))
    (default
     (:when (member default '(t otherwise)))
     t)
    (otherwise
     (error "~S is not an interval designator" iv))))&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="a-hopeless-version"&gt;A hopeless version&lt;/h3&gt;

&lt;p&gt;Here is a version of this macro which is entirely hopeless:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro interval-case (n &amp;amp;body clauses)
  ;; Hopeless
  `(cond
    ,@(mapcar (lambda (clause)
                (destructuring-bind (iv &amp;amp;body forms) clause
                  `(,(compute-interval-form n iv) ,@forms)))
              clauses)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&amp;rsquo;s hopeless because of this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((x 1))
    (interval-case (incf x)
      ((1 (2)) '(1 (2)))
      ((2 (3)) '(2 (3)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So &lt;code&gt;(incf x)&lt;/code&gt; where &lt;code&gt;x&lt;/code&gt; is initially &lt;code&gt;1&lt;/code&gt; is apparently neither in \([1,2)\) nor \([2,3)\) which is strange. This is happening, of course, because the macro is multiply-evaluating its argument, which it should not do.&lt;/p&gt;

&lt;h3 id="an-obviously-unhygienic-repair"&gt;An obviously unhygienic repair&lt;/h3&gt;

&lt;p&gt;So let&amp;rsquo;s try to fix that:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro interval-case (n &amp;amp;body clauses)
  ;; Unhygenic
  `(let ((v ,n))
     (cond
      ,@(mapcar (lambda (clause)
                  (destructuring-bind (iv &amp;amp;body forms) clause
                    `(,(compute-interval-form 'v iv) ,@forms)))
                clauses))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, this is better:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((x 1))
    (interval-case (incf x)
      ((1 (2)) '(1 (2)))
      ((2 (3)) '(2 (3)))))
((2) (3))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;but &amp;hellip; not much better:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((x 1) (v 10))
    (interval-case (incf x)
      ((1 (2)) nil)
      ((2 (3)) v)))
2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The macro binds &lt;code&gt;v&lt;/code&gt;, which shadows the outer binding of &lt;code&gt;v&lt;/code&gt; and breaks everything.&lt;/p&gt;

&lt;h3 id="a-repair-which-might-be-hygienic"&gt;A repair which might be hygienic&lt;/h3&gt;

&lt;p&gt;Here is the normal way to fix that:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro interval-case (n &amp;amp;body clauses)
  ;; OK
  (let ((vn (make-symbol "V")))
    `(let ((,vn ,n))
       (cond
        ,@(mapcar (lambda (clause)
                    (destructuring-bind (iv &amp;amp;body forms) clause
                      `(,(compute-interval-form vn iv) ,@forms)))
                  clauses)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((x 1) (v 10))
    (interval-case (incf x)
      ((1 (2)) nil)
      ((2 (3)) v)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Good. I think it is possible to argue that this version of the macro is hygienic, at least in terms of names.&lt;/p&gt;

&lt;h3 id="a-simpler-repair-using-metatronic-macros"&gt;A simpler repair using metatronic macros&lt;/h3&gt;

&lt;p&gt;Here is the previous macro written using metatronic macros:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro/m interval-case (n &amp;amp;body clauses)
  ;; OK, easier
  `(let ((&amp;lt;v&amp;gt; ,n))
       (cond
        ,@(mapcar (lambda (clause)
                    (destructuring-bind (iv &amp;amp;body forms) clause
                      `(,(compute-interval-form '&amp;lt;v&amp;gt; iv) ,@forms)))
                  clauses))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is simpler to read and should be as good.&lt;/p&gt;

&lt;h3 id="an-alternative-approach-"&gt;An alternative approach &amp;hellip;&lt;/h3&gt;

&lt;p&gt;Although it is not entirely natural in the case of this macro, many macros can be written by having the macro expand into a call to a function, passing another function whose body is the body of the macro as an argument. These things often exist as pairs of &lt;code&gt;with-&lt;/code&gt;* (the macro) and &lt;code&gt;call-with-&lt;/code&gt;* (the function).&lt;/p&gt;

&lt;p&gt;We can persuade &lt;code&gt;interval-case&lt;/code&gt; to work like that: it&amp;rsquo;s not a natural macro to write that way and writing it that way will end up with something almost certainly less efficient as (at least the way I&amp;rsquo;ve written it) as it needs to interpret the interval specifications at runtime rather than compile them&lt;sup&gt;&lt;a href="#2023-05-03-two-sides-to-hygiene-footnote-2-definition" name="2023-05-03-two-sides-to-hygiene-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;. But I wanted to have just one example.&lt;/p&gt;

&lt;p&gt;Here is &lt;code&gt;call/intervals&lt;/code&gt;, the function layer:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun call/intervals (n ivs/thunks)
  ;; Given a real n and a list of (interval-spec thunk ...), find the
  ;; first spec that n matches and call its thunk.
  (if (null ivs/thunks)
      nil
    (destructuring-bind (iv thunk . more) ivs/thunks
      (if (destructuring-match iv
            (((l) (h))
             (:when (and (realp l) (realp h)))
             (&amp;lt; l n h))
            ((l (h))
             (:when (and (realp l) (realp h)))
             (and (&amp;lt;= l n) (&amp;lt; n h)))
            (((l) h)
             (:when (and (realp l) (realp h)))
             (and (&amp;lt; l n) (&amp;lt;= n h)))
            ((l h)
             (:when (and (realp l) (realp h)))
             (&amp;lt;= l n h))
            (default
             (:when (member default '(t otherwise)))
             t)
            (otherwise
             (error "~S is not an interval designator" iv)))
          (funcall thunk)
        (call/intervals n more)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As well, here is a &amp;lsquo;nospread&amp;rsquo; variation on &lt;code&gt;call/intervals&lt;/code&gt; which serves as an impedence matcher:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun call/intervals* (n &amp;amp;rest ivs/thunks)
  ;; Impedence matcher
  (declare (dynamic-extent ivs/thunks))
  (call/intervals n ivs/thunks))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now here&amp;rsquo;s the macro layer:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro interval-case (n &amp;amp;body clauses)
  ;; Purports to be hygienic
  `(call/intervals*
    ,n
    ,@(mapcan (lambda (clause)
                `(',(car clause)
                  (lambda () ,@(cdr clause))))
              clauses)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So we can test this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((x 1) (v 10))
    (interval-case (incf x)
      ((1 (2)) nil)
      ((2 (3)) v)))
10&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, OK, that&amp;rsquo;s good, right? This is another hygienic macro. Not so fast.&lt;/p&gt;

&lt;h3 id="which-is-not-hygienic"&gt;&amp;hellip; which is not hygienic&lt;/h3&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (flet ((call/intervals* (&amp;amp;rest junk)
           (declare (ignore junk))
           86))
    (interval-case 2
      ((1 2) 'two)))
86&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Not so hygienic, then.&lt;/p&gt;

&lt;h3 id="the-alternative-approach-in-racket"&gt;The alternative approach in Racket&lt;/h3&gt;

&lt;p&gt;Here is a similar alternative approach implemented in Racket:&lt;/p&gt;

&lt;pre class="brush: racket"&gt;&lt;code&gt;(define (call/intervals n ivs/thunks)
  ;; Here ivs/thunks is a list of (iv thunk) pairs, which is not the same
  ;; as the CL version: that's because I can't work out how to do the
  ;; syntax rule otherwise.
  (match ivs/thunks
    ['() #f]
    [(list (list iv thunk) more ...)
     (if
      (match iv
        [(list (list (? real? l))
               (list (? real? h)))
         (&amp;lt; l n h)]
        [(list (? real? l)
               (list (? real? h)))
         (and (&amp;lt;= l n) (&amp;lt; n h))]
        [(list (list (? real? l))
               (? real? h))
         (and (&amp;lt; l n) (&amp;lt;= n h))]
        [(list (? real? l) (? real? h))
         (&amp;lt;= l n h)]
        [(or 'otherwise #t)
         #t]
        [_
         (error 'call/intervals "~S is not an interval designator" iv)])
      (thunk)
      (call/intervals n more))]))

(define (call/intervals* n  . ivs/thunks)
  ;; impedence matcher (not so useful here)
  (call/intervals n ivs/thunks))

(define-syntax-rule (interval-case n (key body ...) ...)
  (call/intervals* n (list 'key (thunk body ...)) ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now:&lt;/p&gt;

&lt;pre class="brush: racket"&gt;&lt;code&gt;&amp;gt; (call/intervals* 1 (list '(0 1) (thunk 3)))
3
&amp;gt; (interval-case 2
    ((1 2) 'two))
'two
&amp;gt; (let ([call/intervals* (thunk* 86)])
    (interval-case 2
      ((1 2) 'two)))
'two
&amp;gt; (let ([call/intervals* (thunk* 86)])
    (call/intervals* 2))
86&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Racket this macro is hygienic.&lt;/p&gt;

&lt;h2 id="two-sides-to-hygiene"&gt;Two sides to hygiene&lt;/h2&gt;

&lt;p&gt;So the problem here is that there are at least &lt;em&gt;two sides to hygiene&lt;/em&gt; for macros:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;names they use, usually by binding variables but also in other ways, must not interfere with names used in the program where the macro is used;&lt;/li&gt;
 &lt;li&gt;the program where the macro is used must not be able to alter what names the macro &lt;em&gt;refers to&lt;/em&gt; mean.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;In both cases, of course, there need to be exceptions which are part of the macro&amp;rsquo;s contract with its users: &lt;code&gt;with-standard-io-syntax&lt;/code&gt; is allowed (and indeed required) to bind &lt;code&gt;*print-case*&lt;/code&gt; and many other variables.&lt;/p&gt;

&lt;p&gt;I think almost everyone understands the first of these problems, but the second is much less often thought about.&lt;/p&gt;

&lt;h2 id="dealing-with-this-problem-in-common-lisp"&gt;Dealing with this problem in Common Lisp&lt;/h2&gt;

&lt;p&gt;I think a full solution to this problem in CL would be very difficult: macros would have to refer to the names they rely on by names which were somewhow unutterable by the programs that used them. Short of actually writing a fully-fledged hygienic macro system for CL this sounds impractical.&lt;/p&gt;

&lt;p&gt;In practice the solution is to essentially extend what CL already does. For symbols (so, names) in the CL package there are &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/11_aba.htm"&gt;strong restrictions&lt;/a&gt; on what conforming programs may do. This program is not legal CL&lt;sup&gt;&lt;a href="#2023-05-03-two-sides-to-hygiene-footnote-3-definition" name="2023-05-03-two-sides-to-hygiene-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt; for instance:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(flet ((car (x) x))
  ... (car ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So the best answer is then, I think, to:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;use packages with well-defined interfaces in the form of exported symbols;&lt;/li&gt;
 &lt;li&gt;disallow or strongly discourage the use of internal symbols of packages by programs which are not part of the implementation of the package;&lt;/li&gt;
 &lt;li&gt;and finally place restrictions similar to those placed on the CL package on &lt;em&gt;exported&lt;/em&gt; symbols of your packages.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Note that package &lt;em&gt;locks&lt;/em&gt; don&amp;rsquo;t answer this problem: they usually forbid the modification of various attributes of symbols and the creation or deletion of symbols, but what is needed is considerably stronger than that: it needs to be the case that you can&amp;rsquo;t establish any kind of binding, even a lexical one, for symbols in the package.&lt;/p&gt;

&lt;p&gt;Is this a problem in practice? Probably not often. Do I still prefer traditional Lisp macros? Yes, I think so.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2023-05-03-two-sides-to-hygiene-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;This function what you would want to make more complicated to allow multiple intervals per clause.&amp;nbsp;&lt;a href="#2023-05-03-two-sides-to-hygiene-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-05-03-two-sides-to-hygiene-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;This interpretation could be avoided by havig the compiler turn the interval specifications into one-argument functions. I think it&amp;rsquo;s still not a natural way to write this macro.&amp;nbsp;&lt;a href="#2023-05-03-two-sides-to-hygiene-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-05-03-two-sides-to-hygiene-footnote-3-definition" class="footnote-definition"&gt;
   &lt;p&gt;Assuming that &lt;code&gt;car&lt;/code&gt; means &amp;lsquo;the symbol whose name is &lt;code&gt;"CAR"&lt;/code&gt; in the &lt;code&gt;"COMMON-LISP"&lt;/code&gt; package&amp;rsquo;.&amp;nbsp;&lt;a href="#2023-05-03-two-sides-to-hygiene-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Nirvana</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/05/02/nirvana/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-05-02-nirvana</id>
  <published>2023-05-02T13:16:58Z</published>
  <updated>2023-05-02T13:16:58Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;An article constructed from several emails from my friend Zyni, reproduced with her permission. Note that Zyni&amp;rsquo;s first language is not English.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Many people have tried to answer what is so special about Lisp by talking about many things.&lt;/p&gt;

&lt;p&gt;Such as interactive development, a thing common now to many languages of course, and if you use Racket with DrRacket not in fact how development usually works there at all. Are we to cast Racket into the outer darkness?&lt;sup&gt;&lt;a href="#2023-05-02-nirvana-footnote-1-definition" name="2023-05-02-nirvana-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Such as CLOS, a thing specific to Common Lisp: can you not achieve Lisp enlightenment unless you program in Common Lisp? Was Lisp enlightmenent impossible before CLOS existed? What stupid ideas. Could you implement CLOS in a language which was not Lisp? Certainly you could.&lt;/p&gt;

&lt;p&gt;Such as the CL condition system: a thing also specific to Common Lisp. Something also which could be implemented in any sufficiently dynamic language. Something almost nobody who writes in Common Lisp understands I think.&lt;/p&gt;

&lt;p&gt;And so it goes on.&lt;/p&gt;

&lt;p&gt;None of this is the answer. None of this is close to the answer. To find the answer ask &lt;em&gt;why&lt;/em&gt; did these things arise in Lisp first? What is the property of Lisp which is in fact unique to Lisp and which &lt;em&gt;defines&lt;/em&gt; Lisp in strict sense that if any other language had this property &lt;em&gt;it would be a Lisp&lt;/em&gt;? To see answer to this you must understand &lt;a href="https://www.tfeb.org/fragments/2022/10/03/bradshaw-s-laws/" title="Bradshaw's law"&gt;Bradshaw&amp;rsquo;s law&lt;/a&gt; and my corollary to it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bradshaw&amp;rsquo;s law.&lt;/strong&gt; &lt;em&gt;All sufficiently large software systems end up being programming languages.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zyni&amp;rsquo;s corollary.&lt;/strong&gt; &lt;em&gt;At whatever size you think Bradshaw&amp;rsquo;s law applies, it applies sooner than that.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This means that &lt;em&gt;all programming is language construction&lt;/em&gt;.&lt;sup&gt;&lt;a href="#2023-05-02-nirvana-footnote-2-definition" name="2023-05-02-nirvana-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt; When you write a program you are writing a language in which to express the problem you wish to solve.&lt;/p&gt;

&lt;p&gt;Now you can begin understand what is so interesting about Lisp. In almost all programming languages when you solve a problem you define a lot of new words for the language you have, and perhaps you define elaborate classifications of the nouns of the language you will allow. But you can do nothing with the structure of the language you must use because the language will not allow that: it has a fixed grammar handed down by the great and good who designed it who are sometimes not fools. And indeed you are fiercely discouraged from even understanding what it is you are doing: discouraged from understanding that you are building a new language.&lt;/p&gt;

&lt;p&gt;And quite soon (sooner than you think and in fact immediately) you find you must actually have new structure, new &lt;em&gt;grammar&lt;/em&gt;. But you cannot do this easily both because the language you use does not allow it and also because you do not know what it is you are doing – you do not realise that you are making a language. So probably you use a templating system or something and build an awful horror. Often this horror will have nested languages where inner languages appear in strings in outer languages. Often it will have evaluation rules so obscure and inconsistent that it is impossible for humans to write safe large programs in this language (Unix shells: I look at you). We have all seen these things.&lt;/p&gt;

&lt;p&gt;And so you live out your life crawling in the dirt, never understanding what thing it is of which you are making a very bad, very unsafe, very ugly version. Because you have been taught there is only mud so all you do is pile up structures out of mud, to be washed away by the next rain. A little way over is a tribe who knows only straw and they build structures from straw which blow away in the first wind. You hate them; they hate you. Sometimes you have little wars.&lt;/p&gt;

&lt;p&gt;What, on the other hand, do you do in Lisp? Well, few days ago I needed a way to express the idea of searching some (very) large structure and being able to fail in a structured way. So after ten minutes work, my program now says things like this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun big-serch-thing (thing)
  (attempting
    (quick-and-dirty thing)
    (try-harder thing)))

(defun try-harder (thing)
  (walking-thing (node thing :level 0)
    (attempting
      (first-pass thing)
      (desparate-fallback thing))))

(defun first-pass (thing)
  ...
  (when doom (fail))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well it does not matter what this does and this is not what my program is actually like, but what is clear just by looking is that &lt;em&gt;this language is not Common Lisp&lt;/em&gt;. Instead it is Common Lisp extended with at least two new grammatical constructs: &lt;code&gt;attempting&lt;/code&gt; with its friend &lt;code&gt;fail&lt;/code&gt; which looks like a verb but in fact is a control construct really, and &lt;code&gt;walking-thing&lt;/code&gt; which is some kind of new iteration construct perhaps.&lt;/p&gt;

&lt;p&gt;And there is more: when you look at &lt;code&gt;attempting&lt;/code&gt; you will find it is implemented (by a function which) uses a construct called &lt;code&gt;looping&lt;/code&gt; which is &lt;em&gt;another&lt;/em&gt; extension to Common Lisp. And similarly for &lt;code&gt;walking-thing&lt;/code&gt; (which is not really called that) which uses I think four separate new grammatical constructs I do not remember.&lt;/p&gt;

&lt;p&gt;And there is more: when I started this essay these constructs were mostly as I showed above, but we have decided this was wrong, so the new language is now somewhat different and somewhat richer. A few more tens of minutes of work, most of it altering the existing programs in the old language to use the new language. The new language is even defined using a language-extending construct which itself is an extension to CL&amp;rsquo;s provided ones.&lt;/p&gt;

&lt;p&gt;And this is how you program in Lisp. &lt;em&gt;In Lisp, writing programs is building languages&lt;/em&gt;: in Lisp to solve a problem is to first build a language in which the problem may be solved. And because doing this is so easy in Lisp, this is what you do even for very small problems: you incrementally extend the grammar of the language &amp;mdash; not just its lexicon &amp;mdash; to create a language in which to describe the problem.&lt;/p&gt;

&lt;p&gt;Well, this is not surprising, is it? This is what the laws imply: programming &lt;em&gt;is&lt;/em&gt; constructing languages, and this applies even for very small programs. What is surprising is that so few languages encourage this. And because they do not we end up with the horror we all know. Perhaps even this is not surprising: any language which supports this well will have all the characteristics of Lisp, will in fact &lt;em&gt;be&lt;/em&gt; a Lisp. So no other languages do this because to do it requires being Lisp. So why is Lisp not more popular? Well, answer is fairly easy but this is discussion for another day, I think.&lt;/p&gt;

&lt;p&gt;And now we see why Lisp got features first: because it could. Let us say you wish to explore an object system in Lisp. Well, perhaps you will want a class-defining construct, so you write a macro, &lt;code&gt;define-class&lt;/code&gt; or something. And you wish to be able to send messages, so you write a &lt;code&gt;send&lt;/code&gt; function and then you modify the readtable so &lt;code&gt;[o message ...]&lt;/code&gt; is &lt;code&gt;(send o message ...)&lt;/code&gt;. And perhaps you wish some new binding construct for fields so you write &lt;code&gt;with-fields&lt;/code&gt; and so, and so.&lt;/p&gt;

&lt;p&gt;And now you have a new language. If you were careful you may even have constructed that new language inside a single running Lisp image. And this took, perhaps, some hours. And later, you decide that no, you wish your new language to be different, so you change it. Another few hours. Eventually, in a different world, you call this part of the language ZLOS and there is a standard.&lt;/p&gt;

&lt;p&gt;And this is why these linguistic innovations happen in Lisp: because Lisp is a machine for linguistic innovation. It is &lt;em&gt;that&lt;/em&gt; feature of Lisp which makes it interesting, and it is &lt;em&gt;only&lt;/em&gt; that feature: both because all other features derive from that one and because to have that feature is to be Lisp.&lt;/p&gt;

&lt;p&gt;That is all.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2023-05-02-nirvana-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;Do not answer this or I will kill you with a stale loaf of bread.&amp;nbsp;&lt;a href="#2023-05-02-nirvana-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-05-02-nirvana-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;This is exaggeration: if you define &lt;em&gt;no&lt;/em&gt; names in your program you are, perhaps, not constructing a language.&amp;nbsp;&lt;a href="#2023-05-02-nirvana-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Something unclear in the Common Lisp standard</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/04/18/something-unclear-in-the-common-lisp-standard/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-04-18-something-unclear-in-the-common-lisp-standard</id>
  <published>2023-04-18T09:53:46Z</published>
  <updated>2023-04-18T09:53:46Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;There is what I think is a confusion as to bound declarations in the Common Lisp standard. I may be wrong about this, but I think I&amp;rsquo;m correct.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="bound-and-free-declarations"&gt;Bound and free declarations&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/03_c.htm"&gt;Declarations&lt;/a&gt; in Common Lisp can be either &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/03_cd.htm"&gt;bound or free&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;a &lt;strong&gt;bound&lt;/strong&gt; declaration appears at the head of a binding form and applies to a variable or function binding made by that form;&lt;/li&gt;
 &lt;li&gt;a &lt;strong&gt;free&lt;/strong&gt; declaration is any declaration which is not bound.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;There are declarations which do not apply to bindings, such as &lt;code&gt;optimize&lt;/code&gt;: these are always free.&lt;/p&gt;

&lt;h2 id="examples-of-bound-and-free-declarations"&gt;Examples of bound and free declarations&lt;/h2&gt;

&lt;p&gt;In the form&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((x 1))
  (declare (type integer x))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;the declaration is bound and applies to the binding of &lt;code&gt;x&lt;/code&gt;. In the form&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((/x/ 1))
  (declare (special /x/)
           (optimize (speed 3)))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;the &lt;code&gt;special&lt;/code&gt; declaration is bound and applies to the binding of &lt;code&gt;/x/&lt;/code&gt;, while the &lt;code&gt;optimize&lt;/code&gt; declaration is free.&lt;/p&gt;

&lt;p&gt;In the form&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((x 1))
  (locally
    (declare (type integer x)
             (optimize speed))
    ...)
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Both declarations are free and apply only to the body of the &lt;code&gt;locally&lt;/code&gt; form.&lt;/p&gt;

&lt;h2 id="declarations-which-may-not-be-ignored"&gt;Declarations which may not be ignored&lt;/h2&gt;

&lt;p&gt;Most declarations may be ignored by the implementation: this is the case for all type declarations, for instance. Two may not be:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;notinline&lt;/code&gt; forbids inline compilation of the functions it names;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;special&lt;/code&gt; requires dynamic bindings to be made when it is bound, and requires references to be to dynamic, not lexical bindigns when it is free.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;I&amp;rsquo;m going to exploit the non-ignorability of &lt;code&gt;special&lt;/code&gt; declarations to show a case where the confusion arises.&lt;/p&gt;

&lt;h2 id="the-confusion"&gt;The confusion&lt;/h2&gt;

&lt;p&gt;Forms like &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm"&gt;&lt;code&gt;let*&lt;/code&gt;&lt;/a&gt; bind &lt;em&gt;sequentially&lt;/em&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let* ((x 1) (y x))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;first binds &lt;code&gt;x&lt;/code&gt; and then binds &lt;code&gt;y&lt;/code&gt; to the value of &lt;code&gt;x&lt;/code&gt;. Now, I am not sure of the standard ever says this, but all implementations I have tried take this to mean that &lt;em&gt;the same name can be bound several times by &lt;code&gt;let*&lt;/code&gt;&lt;/em&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let* ((x 1) (x x))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;is legal, if stylistically awful. That&amp;rsquo;s because the obvious transformation of &lt;code&gt;let*&lt;/code&gt; into nested &lt;code&gt;let&lt;/code&gt;s turns this into:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((x 1))
  (let ((x x))
    ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which is clearly fine.&lt;/p&gt;

&lt;p&gt;So now we come to the problem: what should this mean?&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let* ((x 1) (x x))
  (declare (type fixnum x))
  ...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which binding of &lt;code&gt;x&lt;/code&gt; does the declaration apply to? The standard does not say. In this case it might not matter, because this declaration can be ignored, but here is a case where it &lt;em&gt;does&lt;/em&gt; matter:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let (c)
  (let* ((/x/ 1)
         (/x/ (progn
                (setf c (lambda () /x/))
                2)))
    (declare (special /x/))
    (values c (lambda () /x/))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This expression returns two values, both of which are functions:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;if the first &lt;code&gt;/x/&lt;/code&gt; is special then calling the first function will result in an error;&lt;/li&gt;
 &lt;li&gt;if the second &lt;code&gt;/x/&lt;/code&gt; is special then calling the second function will result in an error.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;So using this trick you can know whether the first binding, second binding, or both bindings are affected by the &lt;code&gt;special&lt;/code&gt; declaration.&lt;/p&gt;

&lt;p&gt;And, again, the standard does not say which binding is affected, or whether both should be. And implementations differ. Given the following file&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(in-package :cl-user)  

(defun call-ok-p (f)
  (multiple-value-bind (v c)
      (ignore-errors
       (funcall f)
       t)
    (declare (ignore c))
    v))

(defun ts ()
  (multiple-value-bind (one two)
      (let (c)
        (let* ((/x/ 1)
               (/x/ (progn
                      (setf c (lambda () /x/))
                      2)))
          (declare (special /x/))
          (values c (lambda () /x/))))
    (values (call-ok-p one)
            (call-ok-p two))))

(multiple-value-bind (first-lexical second-lexical) (ts)
  (format t "~&amp;amp;first  ~:[special~;lexical~]~%~
               second ~:[special~;lexical~]~%"
          first-lexical second-lexical))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;SBCL&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;first  lexical
second special&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;CCL&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;first  special
second special&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;LispWorks&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;first  special
second special&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="what-should-the-answer-be"&gt;What should the answer be?&lt;/h2&gt;

&lt;p&gt;I think that the interpretation taken by CCL and LispWorks is better: in forms like this declarations should apply to &lt;em&gt;all&lt;/em&gt; the bindings made by the form. An alternative answer is that the declarations should apply to the &lt;em&gt;visible&lt;/em&gt; bindings at the point of the declaration, which is the approach taken by SBCL.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s tempting to say that the obvious rewrite of &lt;code&gt;let*&lt;/code&gt; as nested &lt;code&gt;let&lt;/code&gt;s gives you the SBCL answer, but it does not. In a form like&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let* ((x 3) (y x))
  (declare (type integer x)
           (type (integer 0) y))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This must be rewritten as&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((x 3))
  (declare (type integer x))
  (let ((y x))
    (declare (type (integer 0) y))
    ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So the declaration for &lt;code&gt;x&lt;/code&gt; must be raised out of the inner &lt;code&gt;let&lt;/code&gt; so it remains bound: the implementation already has to do work to get declarations in the right place and can&amp;rsquo;t just naïvely rewrite the form.&lt;/p&gt;

&lt;p&gt;I prefer the first interpretation both because I think it represents what people are likely to want more closely, but also because I think the standard could be interpreted as meaning that without being rewritten.&lt;/p&gt;

&lt;h2 id="does-this-matter"&gt;Does this matter?&lt;/h2&gt;

&lt;p&gt;Probably only in very obscure cases! I just thought it was interesting.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Thanks to vrious people on the Lisp-HUG mailing list for coming up with this.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Measuring some tree-traversing functions</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/03/26/measuring-some-tree-traversing-functions/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-03-26-measuring-some-tree-traversing-functions</id>
  <published>2023-03-26T09:25:50Z</published>
  <updated>2023-03-26T09:25:50Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;In a &lt;a href="https://www.tfeb.org/fragments/2023/03/13/variations-on-a-theme/" title="Variations on a theme"&gt;previous article&lt;/a&gt; my friend Zyni wrote some variations on a list-flattening function, some of which were &amp;lsquo;recursive&amp;rsquo; and some of which &amp;lsquo;iterative&amp;rsquo;, managing the stack explicitly. We thought it would be interesting to see what the performance differences were, both for this function and a more useful variant which searches a tree rather than flattening it.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="what-we-measured"&gt;What we measured&lt;/h2&gt;

&lt;p&gt;The code we used is &lt;a href="https://github.com/tfeb/zyni-flatten" title="sample code"&gt;here&lt;/a&gt;&lt;sup&gt;&lt;a href="#2023-03-26-measuring-some-tree-traversing-functions-footnote-1-definition" name="2023-03-26-measuring-some-tree-traversing-functions-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;. We measured four variations of each of two functions.&lt;/p&gt;

&lt;h3 id="list-flattening"&gt;List flattening&lt;/h3&gt;

&lt;p&gt;All these functions use &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#collecting-lists-forwards-and-accumulating-collecting" title="collecting"&gt;&lt;code&gt;collecting&lt;/code&gt;&lt;/a&gt; to build their results forwards. They live in &lt;a href="https://github.com/tfeb/zyni-flatten/blob/main/flatten-variants.lisp" title="flatten-variants.lisp"&gt;&lt;code&gt;flatten-variants.lisp&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;flatten/implicit-stack&lt;/code&gt; works in the obvious recursive way, with an implicit stack. This uses &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#applicative-iteration-iterate" title="iterate"&gt;&lt;code&gt;iterate&lt;/code&gt;&lt;/a&gt; to express the local recursive function.&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;flatten/explicit-stack&lt;/code&gt; uses an explicit stack (called &lt;code&gt;agenda&lt;/code&gt; in the code) represented as a vector, and uses &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#decomposing-iteration-simple-loops" title="looping"&gt;&lt;code&gt;looping&lt;/code&gt;&lt;/a&gt; to express iteration.&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;flatten/explicit-stack/adja&lt;/code&gt; is like the previous function but it is willing to extend the explicit stack, which it does by using &lt;code&gt;adjust-array&lt;/code&gt; and assignment.&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;flatten/explicit-stack/adjb&lt;/code&gt; is like &lt;code&gt;flatten/explicit-stack/adja&lt;/code&gt; but uses a local tail-recursive function to &lt;em&gt;bind&lt;/em&gt; the extended stack rather than assignment.&lt;/li&gt;
 &lt;li&gt;Finally &lt;code&gt;flatten/consy-stack&lt;/code&gt; is very close to Zyni&amp;rsquo;s original iterative solution: it represents the stack as a list. This version necessarily conses fairly copiously.&lt;/li&gt;&lt;/ul&gt;

&lt;h3 id="searching-cons-trees"&gt;Searching cons trees&lt;/h3&gt;

&lt;p&gt;These functions, in &lt;a href="https://github.com/tfeb/zyni-flatten/blob/main/treesearch-variants.lisp" title="treesearch-variants.lisp"&gt;&lt;code&gt;treesearch-variants.lisp&lt;/code&gt;&lt;/a&gt;, correspond to the flattening variants, except they are searching for some atomic value in the tree of conses:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;search/implicit-stack&lt;/code&gt; uses an implicit stack;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;search/explicit-stack&lt;/code&gt; uses a vector;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;search/explicit-stack/adja&lt;/code&gt; uses a vector and adjusts by assignment;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;search/explicit-stack/adjb&lt;/code&gt; uses a vector and adjusts by binding;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;search/consy-stack&lt;/code&gt; uses a consy stack.&lt;/li&gt;&lt;/ul&gt;

&lt;h3 id="notes-on-the-code"&gt;Notes on the code&lt;/h3&gt;

&lt;p&gt;The functions all have &lt;code&gt;(declare (optimize (speed 3)))&lt;/code&gt; but specifically &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; turn off safety or use implementation-specific settings: we wanted to test code we felt we&amp;rsquo;d be happy running, and that means code compiled with reasonable settings for safety: if you turn safety off you&amp;rsquo;re brave, foolish, or both.&lt;/p&gt;

&lt;p&gt;We did not compare &lt;code&gt;looping&lt;/code&gt; with &lt;code&gt;do&lt;/code&gt; or &lt;code&gt;loop&lt;/code&gt;: we probably should. However the expansion of &lt;code&gt;looping&lt;/code&gt; is pretty straightforward:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(looping ((this o) (depth 0))
  (declare ...)
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Turns into&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((this o) (depth 0))
  (declare ...)
  (block nil
    (tagbody
      #:start
      (multiple-value-setq (this depth) ...)
      (go #:start))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The only real question here, we think is whether &lt;code&gt;multiple-value-setq&lt;/code&gt; is compiled well: brief inspection implies it is. We should probably still compare the current version with more &amp;lsquo;native CL&amp;rsquo; variants.&lt;/p&gt;

&lt;p&gt;The variants which use a vector as a stack maintain the current element themselves: that&amp;rsquo;s because we tested using a fill pointer and &lt;code&gt;vector-push&lt;/code&gt; / &lt;code&gt;vector-pop&lt;/code&gt; and it was really significantly slower in both implementations.&lt;/p&gt;

&lt;h2 id="what-we-did"&gt;What we did&lt;/h2&gt;

&lt;h3 id="the-lisp-implementations-we-used"&gt;The Lisp implementations we used&lt;/h3&gt;

&lt;p&gt;We used LispWorks 8.0 and very recent SBCL builds, compiled from the &lt;code&gt;master&lt;/code&gt; branch no more than a few days before we ran the tests in mid March 2023.&lt;/p&gt;

&lt;p&gt;In the case of SBCL we paid attention to notes and warnings during compilation. The significant one we did &lt;em&gt;not&lt;/em&gt; address was that it complained vociferously about not being able to optimize calls to &lt;code&gt;eql&lt;/code&gt;: that&amp;rsquo;s because we don&amp;rsquo;t know the type of the thing we are searching for: it &lt;em&gt;needs&lt;/em&gt; to do the work it is trying to avoid. Apart from this the only warnings were about the computation of the new length of the agenda, which never actually happens in the tests we ran.&lt;/p&gt;

&lt;h3 id="the-machines-we-benchmarked-on"&gt;The machines we benchmarked on&lt;/h3&gt;

&lt;p&gt;We both have M1-based Macbook Airs so this is what we used. In particular we have not run any benchmarks on x64.&lt;/p&gt;

&lt;h3 id="what-we-ran"&gt;What we ran&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;make-car-cdr&lt;/code&gt;, in &lt;a href="https://github.com/tfeb/zyni-flatten/blob/main/common.lisp" title="common.lisp"&gt;&lt;code&gt;common.lisp&lt;/code&gt;&lt;/a&gt;, makes a list where each element is a chain linked by cars, finally terminating in a specified element. Controlling the length of the list and the depth of the chains gives the functions more iterative or more recursive work to do respectively. The benchmarking code then made a series of suitable structures of increasing size and timed many iterations of each function on the same structure, computing the time per call. We then wrote a program in Racket to plot the results on axes of &amp;lsquo;breadth&amp;rsquo; (length of the list) and &amp;lsquo;depth&amp;rsquo; (depth of the car-linked chain). For the search functions the element being searched for was not in the tree so they had to do as much work as possible.&lt;/p&gt;

&lt;p&gt;Life was usually arranged so that the initial agenda was big enough for the functions which used a vector as the agenda, so none of that aspect of them was teated, except for one case below. Apart from that case, the &amp;lsquo;vector stack&amp;rsquo; timings refer to &lt;code&gt;flatten/explicit-stack&lt;/code&gt; and &lt;code&gt;treesearch/explicit-stack&lt;/code&gt;, not the adjustable-stack variants.&lt;/p&gt;

&lt;h2 id="some-results"&gt;Some results&lt;/h2&gt;

&lt;p&gt;We timed 1,000 iterations of each call, for list lengths (breadth in the plots and below) from 30 to 1,000 in steps of 10 and depths (depth in the plots and below) from 10 to 300 in steps of 10, computing times in μs per iteration. Neither of us knows anything about how data like this should be best presented but simply plotting the performance surfaces seemed reasonable. We used bilinear interpolation to make the surface from the points&lt;sup&gt;&lt;a href="#2023-03-26-measuring-some-tree-traversing-functions-footnote-2-definition" name="2023-03-26-measuring-some-tree-traversing-functions-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h3 id="lispworks"&gt;LispWorks&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="/fragments/img/2023/zyni-flatten/lw-treesearch-implicit-vector.svg" alt="Treesearch: implicit compared with vector stack" /&gt;
 &lt;p class="caption"&gt;Treesearch: implicit compared with vector stack&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;This is nicely linear in both breadth and depth, and so quadratic in breadth \(\times\) depth. And it&amp;rsquo;s easy to see that for LW using the implicit stack is faster than the manually-managed stack.&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="/fragments/img/2023/zyni-flatten/lw-treesearch-vector-consy.svg" alt="Treesearch: vector stack compared with consy stack" /&gt;
 &lt;p class="caption"&gt;Treesearch: vector stack compared with consy stack&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;This compares the vector stack with the consy stack, for treesearch. The consy stack is slightly faster which surprised us. This conses a list as long as the depth of the tree for each &amp;lsquo;leftward&amp;rsquo; branch, and then immediately unwinds that and throws the whole list away. So it creates significant garbage, but the allocation and garbage collection overhead together is still faster than using a vector. Consing really is (almost) free.&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="/fragments/img/2023/zyni-flatten/lw-treesearch-flatten.svg" alt="Treesearch compared with flatten, both with implicit stacks" /&gt;
 &lt;p class="caption"&gt;Treesearch compared with flatten, both with implicit stacks&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;Here is more evidence that consing is very cheap: the difference between treesearch (which does not cons) and flatten (which does) is tiny.&lt;/p&gt;

&lt;h3 id="sbcl"&gt;SBCL&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="/fragments/img/2023/zyni-flatten/sbcl-treesearch-implicit-vector.svg" alt="Treesearch: implicit compared with vector stack" /&gt;
 &lt;p class="caption"&gt;Treesearch: implicit compared with vector stack&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;So here is SBCL. For SBCL explicitly managing the stack as a vector is significantly faster than the implicit stack. Something that is also apparent here is how variable SBCL&amp;rsquo;s timings are compared with LW&amp;rsquo;s: we don&amp;rsquo;t know why that is although we suspect it might be because SBCL&amp;rsquo;s garbage collector is more intrusive than LW&amp;rsquo;s. We also don&amp;rsquo;t know whether this variation is repeatable, or whether it&amp;rsquo;s due to a single very slow run or something like that.&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="/fragments/img/2023/zyni-flatten/sbcl-treesearch-vector-consy.svg" alt="Treesearch: vector stack compared with consy stack" /&gt;
 &lt;p class="caption"&gt;Treesearch: vector stack compared with consy stack&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;For SBCL the consy stack is significantly slower than the vector stack, so for SBCL the vector stack is the fastest.&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="/fragments/img/2023/zyni-flatten/sbcl-treesearch-flatten.svg" alt="Treesearch compared with flatten, both with implicit stacks" /&gt;
 &lt;p class="caption"&gt;Treesearch compared with flatten, both with implicit stacks&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;SBCL has a slightly larger difference between treesearch and flatten, with flatten being slower. There are also curious &amp;lsquo;waves&amp;rsquo; in the plot as depth increases.&lt;/p&gt;

&lt;h3 id="lispworks-compared-with-sbcl"&gt;LispWorks compared with SBCL&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="/fragments/img/2023/zyni-flatten/lw-sbcl-treesearch-implicit.svg" alt="Treesearch: SBCL compared with Lispworks, implicit stacks" /&gt;
 &lt;p class="caption"&gt;Treesearch: SBCL compared with Lispworks, implicit stacks&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;LW is significantly faster than SBCL for implicit stacks except for very small depths.&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="/fragments/img/2023/zyni-flatten/lw-sbcl-treesearch-best.svg" alt="Treesearch: SBCL compared with Lispworks, best stacks" /&gt;
 &lt;p class="caption"&gt;Treesearch: SBCL compared with Lispworks, best stacks&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;This compares LW using an implicit stack with SBCL using an explicit vector stack. The difference is pretty small now.&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="/fragments/img/2023/zyni-flatten/lw-sbcl-flatten-consy.svg" alt="Flatten: SBCL compared with Lispworks, consy stacks" /&gt;
 &lt;p class="caption"&gt;Flatten: SBCL compared with Lispworks, consy stacks&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;This was meant to be the worst-case for both: flattening and a consy stack. But it&amp;rsquo;s not particularly informative, I think.&lt;/p&gt;

&lt;h3 id="the-outer-reaches-lispworks-with-a-deep-tree"&gt;The outer reaches: LispWorks with a deep tree&lt;/h3&gt;

&lt;p&gt;We did one run with the maximum depth set to 10,000 with a step of 500, and maximum breadth set to 1,000 with a step of 100, averaged over 100 iterations instead of 1,000. This is too deep for LW&amp;rsquo;s stack, but LW allows stack extension, and we wrote what later became &lt;a href="https://github.com/tfeb/tfeb-lisp-implementation-hax/blob/main/lw/modules/allowing-stack-extensions.lisp"&gt;this&lt;/a&gt; to extend the stack as required. Note that this happens only during the first recursion into the left-hand branch of the tree so has minimal effect on performance. This also used &lt;code&gt;search/explicit-stack/adjb&lt;/code&gt; for the vector stack.&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="/fragments/img/2023/zyni-flatten/lw-treesearch-implicit-vector-deep.svg" alt="Treesearch: implicit compared with consy stack, deep tree" /&gt;
 &lt;p class="caption"&gt;Treesearch: implicit compared with consy stack, deep tree&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;As before the implicit stack is much better for LW. This is much more bumpy than LW was for smaller depths, this might have been because the machine did other things while it was running but we don&amp;rsquo;t think so.&lt;/p&gt;

&lt;h2 id="some-conclusions"&gt;Some conclusions&lt;/h2&gt;

&lt;p&gt;None of the differences were really large. In particular there&amp;rsquo;s no enormous advantage from managing the stack yourself.&lt;/p&gt;

&lt;p&gt;Consing and the resulting garbage-collection does really seem to be very cheap, especially in LispWorks: the days of long GC pauses are long gone.&lt;/p&gt;

&lt;p&gt;We were surprised that LispWorks was fairly reliably faster than SBCL: surprised enough that we ran everything several times to be sure. It&amp;rsquo;s also interesting how much smoother LW&amp;rsquo;s performance surface is in most cases.&lt;/p&gt;

&lt;p&gt;It is possible that our implementations just suck, of course.&lt;/p&gt;

&lt;p&gt;Mostly it&amp;rsquo;s just some pretty pictures.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2023-03-26-measuring-some-tree-traversing-functions-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;All of the functions should be portable CL. Some of the mechanism for expressing dependencies and loading things is not. However it should be easy for anyone to run this if they wish to.&amp;nbsp;&lt;a href="#2023-03-26-measuring-some-tree-traversing-functions-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-03-26-measuring-some-tree-traversing-functions-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;Getting the bilinear interpolation right took longer than anything else, and perhaps longer than everything else put together.&amp;nbsp;&lt;a href="#2023-03-26-measuring-some-tree-traversing-functions-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">The absurdity of stacks</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/03/25/the-absurdity-of-stacks/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-03-25-the-absurdity-of-stacks</id>
  <published>2023-03-25T10:57:19Z</published>
  <updated>2023-03-25T10:57:19Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Very often people regard the stack as a scarce, expensive resource, while the heap is plentiful and very cheap. This is absurd: the stack is memory, the heap is also memory. Deforming programs so they are &amp;lsquo;iterative&amp;rsquo; in order that they do not run out of the stack we imagine to be so costly is ridiculous: if you have a program which is inherently recursive, let it be recursive.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;In a &lt;a href="https://www.tfeb.org/fragments/2023/03/13/variations-on-a-theme/" title="Variations on a theme"&gt;previous article&lt;/a&gt; my friend Zyni wrote some variations on a list-flattening function&lt;sup&gt;&lt;a href="#2023-03-25-the-absurdity-of-stacks-footnote-1-definition" name="2023-03-25-the-absurdity-of-stacks-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;, some of which were &amp;lsquo;recursive&amp;rsquo; and some of which &amp;lsquo;iterative&amp;rsquo;. Of course, the ones which claim to be iterative are, in fact, recursive: any procedure which traverses a recursively-defined data structure such as a tree of conses is necessarily recursive. The &amp;lsquo;iterative&amp;rsquo; versions just use an explicitly-maintained stack rather than the implicit stack provided by the language. That makes sense only if stack space is very small compared to the heap and must therefore be conserved. And, well, for many systems that&amp;rsquo;s true. But it is small only because we have administratively decided it should be small: the stack is just memory. If there is plenty of memory for the heap, there is plenty for the stack.&lt;/p&gt;

&lt;p&gt;There are, or may be, arguments for why stacks needed to be small on ancient machines. The history is fascinating, but it is not relevant to today&amp;rsquo;s systems, other than tiny embedded ones. The persistent view of modern machines as giant PDP&amp;ndash;11s has been a blight for well over two decades now: it needs to stop.&lt;/p&gt;

&lt;p&gt;The argument that the stack should be small often seems to be that, if it&amp;rsquo;s not, people will write programs which run away. That&amp;rsquo;s spurious: if such a program is, in fact, iterative, then good compilers will eliminate the tail calls and it will not use stack: a small limit on the stack will not help. If it&amp;rsquo;s really recursive then why should it run out of storage before its conversion to a program which manages the stack explicitly does? Of course &lt;em&gt;that&amp;rsquo;s exactly what compilers which do &lt;a href="https://en.wikipedia.org/wiki/Continuation-passing_style?wprov=sfti1" title="continuation-passing style"&gt;CPS conversion&lt;/a&gt; already do&lt;/em&gt;: programs written using compilers which do that won&amp;rsquo;t have these weird stack limits in the first place. But it should not be necessary to rely on a CPS-converting compiler, or to write in continuation-passing style manually to avoid stack usage: it should be used for other reasons, because the stack is not, in fact, expensive.&lt;/p&gt;

&lt;p&gt;Still less should people feel the need to write programs which explicitly manage a stack except in extraordinary cases.&lt;/p&gt;

&lt;p&gt;There need to be &lt;em&gt;some&lt;/em&gt; limits on stack size, just as there need to be &lt;em&gt;some&lt;/em&gt; limits on heap size, but making the limit on stack size far smaller than the limit on heap size simply encourages people to believe things which aren&amp;rsquo;t true, and to live in fear of recursive programs.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2023-03-25-the-absurdity-of-stacks-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;I still want to know how often functions like this are used in real life.&amp;nbsp;&lt;a href="#2023-03-25-the-absurdity-of-stacks-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Variations on a theme</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/03/13/variations-on-a-theme/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-03-13-variations-on-a-theme</id>
  <published>2023-03-13T12:36:33Z</published>
  <updated>2023-03-13T12:36:33Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;My friend Zyni wrote a comment to a thread on reddit with some variations on a list-flattening function. We&amp;rsquo;ve since spent some time thinking about things related to this, which is written up in a following article. Here is her comment so the following article can refer to it. Other than notes at the end the following text is Zyni&amp;rsquo;s, not mine.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="httpswwwredditcomrcommonlispcomments11o1wvmcommentjbt9n54utmsourceshareutmmediumweb2xcontext3the-reddit-comment-by-zyni"&gt;&lt;a href="https://www.reddit.com/r/Common_Lisp/comments/11o1wvm/comment/jbt9n54/?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3"&gt;The reddit comment by Zyni&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;First of all we all know that CL does not promise to optimize tail recursion: means that tail recursive program may generate recursive not iterative process. So recursive program in CL &lt;em&gt;even if tail recursive&lt;/em&gt; is not safe on data of unknown size, assuming stack is limited.&lt;/p&gt;

&lt;p&gt;But let us assume as good implementations do that tail recursion is optimized in implementation (no need for general tail calls here but is obvious nice thing if implementations do this). Certainly if we are deploying code in space we know what implementation we use and can check this.&lt;/p&gt;

&lt;p&gt;So we look at this supposed wonder of code, which I rewrite slightly to use &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#applicative-iteration-iterate" title="iterate"&gt;&lt;code&gt;iterate&lt;/code&gt; macro&lt;/a&gt; which is simply Scheme&amp;rsquo;s named-&lt;code&gt;let&lt;/code&gt; to be compatible with later examples:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun flatten (o)
  ;; original terrible one
  (iterate ftn ((x o) (accumulator '()))
    (typecase x
      (null accumulator)
      (cons (ftn (car x) (ftn (cdr x) accumulator)))
      (t (cons x accumulator)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This &amp;hellip; is really bad program. It makes an essential mistake that it wishes to build result forwards but lists wish to be built backwards, so it must therefore recurse (not tail) on cdr of structure first. But most list-based structures have little weight in car but much in cdr, so this will fail &lt;em&gt;even on list which is already flat&lt;/em&gt;: &lt;code&gt;(flatten (make-list 100000 :initial-element 1))&lt;/code&gt; will fail if your example fails.&lt;/p&gt;

&lt;p&gt;Any person presenting this code as good example should be ashamed of self.&lt;/p&gt;

&lt;p&gt;So first change: we accept that we must build lists backwards but we change program so that tail call is on cdr not car, and reverse result:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun flatten (o)
  ;; not TR but better on usual assumptions
  (nreverse
   (iterate ftn ((x o) (accumulator '()))
     (typecase x
       (null accumulator)
       (cons (ftn (cdr x) (ftn (car x) accumulator)))
       (t (cons x accumulator))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This function will be fine on assumption of structures which have most weight in their cdrs, which often is true.&lt;/p&gt;

&lt;p&gt;Well, you say, ugly &lt;code&gt;reverse&lt;/code&gt;. OK this is easy: we simply add in a &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#collecting-lists-forwards-and-accumulating-collecting" title="collecting"&gt;&lt;code&gt;collecting&lt;/code&gt; macro&lt;/a&gt; which allows construction of list forwards, implementation is obvious (tail pointer). Now we have done this we can also reorder calls to be more obvious (car call, not TR, is now first):&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun flatten (o)
  ;; not TR, better on usual assumptions, no reverse
  (collecting
    (iterate ftn ((x o))
      (typecase x
        (cons
         (ftn (car x))
         (ftn (cdr x)))
        (null)
        (t (collect x))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is still not fully TR, so will fail on structures which have much weight in car.&lt;/p&gt;

&lt;p&gt;Well, of course, we can deal with this as well: we use explicit agenda to move stack onto heap and turn into pure tail recursive version. First one which builds list backwards in obvious way, therefore needs &lt;code&gt;reverse&lt;/code&gt; again:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun flatten (o)
  ;; pure TR
  (iterate ftn ((agenda (list o))
                (accumulator '()))
    (if (null agenda)
        ;; can write own reverse as tail recursive of course if wish
        ;; to be pure of heart
        (nreverse accumulator)
      (destructuring-bind (this . more) agenda
        (typecase this
          (null
           (ftn more accumulator))
          (cons
           (ftn (list* (car this) (cdr this) more) accumulator))
          (t
           (ftn more (cons this accumulator))))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Assuming implementation optimizes tail recursion this will flatten completely arbitrary structure limited only by memory.&lt;/p&gt;

&lt;p&gt;We can avoid this reversery of course:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun flatten (o)
  ;; pure TR, no reverse
  (collecting
    (iterate ftn ((agenda (list o)))
      (when (not (null agenda))
        (destructuring-bind (this . more) agenda
          (typecase this
            (null
             (ftn more))
            (cons
             (ftn (list* (car this) (cdr this) more)))
            (t
             (collect this)
             (ftn more))))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As before this is limited only by memory assuming implementation optimizes tail calls.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Well, I have written Lisp for only couple of years really (but have maths background). But even I can see that this idea of having to put scary label on recursive function is very bad. Instead people using such code should perhaps &lt;em&gt;read it and understand it&lt;/em&gt; to see what its problems and advantages are. Radical idea, I know.&lt;/p&gt;

&lt;p&gt;Finally idea that stack space is scarce may or may not be true. Example, if we rewrite original version in Racket (first Lisp I used before being lured to dark side):&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(define (flatten o)
  (let ftn ([x o] [accumulator '()])
    (cond
      [(null? x) accumulator]
      [(cons? x) (ftn (car x) (ftn (cdr x) accumulator))]
      [else (cons x accumulator)])))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will happily &amp;lsquo;flatten&amp;rsquo; 100,000 element list and is only limited by memory available because Racket does not treat stack same way.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Finally here is variant of final version using &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#decomposing-iteration-simple-loops" title="simple loops"&gt;&lt;code&gt;looping&lt;/code&gt; macro&lt;/a&gt; which does applicative iteration: this is iterative, on any implementation:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun flatten (o)
  ;; Iterative
  (collecting
    (looping ((agenda (list o)))
      (when (null agenda)
        (return))
      (destructuring-bind (this . more) agenda
        (typecase this
          (null more)
          (cons (list* (car this) (cdr this) more))
          (t (collect this) more))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;looping&lt;/code&gt; part of this turns into:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((agenda (list o)))
  (block nil
    (tagbody
     #:start (setq agenda
                   (progn
                     (when (null agenda) (return))
                     (destructuring-bind (this . more) agenda
                       (typecase this
                         (null more)
                         (cons (list* (car this) (cdr this) more))
                         (t (collect this) more)))))
             (go #:start))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which is iterative.&lt;/p&gt;

&lt;p&gt;I think &lt;code&gt;iterate&lt;/code&gt; one is nicer.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id="notes-from-tim"&gt;Notes from Tim&lt;/h2&gt;

&lt;p&gt;English is Zyni&amp;rsquo;s third language: she wanted me to fix up the above but I refused as I find the way she writes so charming.&lt;/p&gt;

&lt;p&gt;Both of us would like to know how often &lt;code&gt;flatten&lt;/code&gt; is actually used: everyone seems to be very keen on it, but we can&amp;rsquo;t think of any cases where we&amp;rsquo;ve ever wanted it or anything very much like it.&lt;/p&gt;

&lt;p&gt;All of the macros referenced are &amp;lsquo;mine&amp;rsquo; in a somewhat loose sense: They&amp;rsquo;re all published by me, and some of them are mine, some of them were mine but have been made much better by Zyni, some of them are really hers. There are generally comments in the code. Zyni refuses to have anything but a very minimal internet presence for reasons I used to think were absurd but no longer do: you can&amp;rsquo;t be too careful when your parents and by extension you might be on the wrong side of Putin.&lt;/p&gt;

&lt;p&gt;Zyni is not her real name, obviously.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Two tiny Lisp evaluators</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/02/27/two-tiny-lisp-evaluators/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-02-27-two-tiny-lisp-evaluators</id>
  <published>2023-02-27T14:19:38Z</published>
  <updated>2023-02-27T14:19:38Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Everyone who has written Lisp has written tiny Lisp evaluators in Lisp: here are two more.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Following two &lt;a href="https://tfeb.org/fragments/2023/02/22/how-to-understand-closures-in-common-lisp/"&gt;recent&lt;/a&gt; &lt;a href="https://tfeb.org/fragments/2023/02/27/dynamic-binding-without-special-in-common-lisp/"&gt;articles&lt;/a&gt; I wrote on scope and extent in Common Lisp, I thought I would finish with two very tiny evaluators for dynamically and lexically bound variants on a tiny Lisp.&lt;/p&gt;

&lt;h2 id="the-language"&gt;The language&lt;/h2&gt;

&lt;p&gt;The tiny Lisp these evaluators interpret is not minimal: it has constructs other than &lt;code&gt;lambda&lt;/code&gt;, and even has assignment. But it is pretty small. Other than the binding rules the languages are identical.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;λ&lt;/code&gt;&lt;/strong&gt; &amp;amp; &lt;strong&gt;&lt;code&gt;lambda&lt;/code&gt;&lt;/strong&gt; are synonyms and construct procedures, which can take any number of arguments;&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;quote&lt;/code&gt;&lt;/strong&gt; quotes its argument;&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;if&lt;/code&gt;&lt;/strong&gt; is conditional expression (the else part is optional);&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;set!&lt;/code&gt;&lt;/strong&gt; is assignment and mutates a binding.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;That is all that exists.&lt;/p&gt;

&lt;p&gt;Both evaluators understand primitives, which are usually just functions in the underlying Lisp: since the languages are Lisp&amp;ndash;1s, you could also expose other sorts of things of course (for instance true and false values). You can provide a list of initial bindings to them to define useful primitives.&lt;/p&gt;

&lt;h2 id="requirements"&gt;Requirements&lt;/h2&gt;

&lt;p&gt;Both evaluators rely on my &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#applicative-iteration-iterate"&gt;iterate&lt;/a&gt; and &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#simple-pattern-matching-spam"&gt;spam&lt;/a&gt; hacks: they could easily be rewritten not to do so.&lt;/p&gt;

&lt;h2 id="the-dynamic-evaluator"&gt;The dynamic evaluator&lt;/h2&gt;

&lt;p&gt;A procedure is represented by a structure which has a list of formals and a body of one or more forms.&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defstruct (procedure
            (:print-function
             (lambda (p s d)
               (declare (ignore d))
               (print-unreadable-object (p s)
                 (format s "λ ~S" (procedure-formals p))))))
  (formals '())
  (body '()))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The evaluator simply dispatches on the type of thing and then on the operator for compound forms.&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun evaluate (thing bindings)
  (typecase thing
    (symbol
     (let ((found (assoc thing bindings)))
       (unless found
         (error "~S unbound" thing))
       (cdr found)))
    (list
     (destructuring-bind (op . arguments) thing
       (case op
         ((lambda λ)
          (matching arguments
            ((head-matches (list-of #'symbolp))
             (make-procedure :formals (first arguments)
                             :body (rest arguments)))
            (otherwise
             (error "bad lambda form ~S" thing))))
         ((quote)
          (matching arguments
            ((list-matches (any))
             (first arguments))
            (otherwise
             (error "bad quote form ~S" thing))))
         ((if)
          (matching arguments
            ((list-matches (any) (any))
             (if (evaluate (first arguments) bindings)
                 (evaluate (second arguments) bindings)))
            ((list-matches (any) (any) (any))
             (if (evaluate (first arguments) bindings)
                 (evaluate (second arguments) bindings)
               (evaluate (third arguments) bindings)))
            (otherwise
             (error "bad if form ~S" thing))))
         ((set!)
          (matching arguments
            ((list-matches #'symbolp (any))
             (let ((found (assoc (first arguments) bindings)))
               (unless found
                 (error "~S unbound" (first arguments)))
               (setf (cdr found) (evaluate (second arguments) bindings))))
            (otherwise
             (error "bad set! form ~S" thing))))
         (t
          (applicate (evaluate (first thing) bindings)
                     (mapcar (lambda (form)
                               (evaluate form bindings))
                             (rest thing))
                     bindings)))))
    (t thing)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The interesting thing here is that &lt;code&gt;applicate&lt;/code&gt; needs to know the current set of bindings so it can extend them dynamically.&lt;/p&gt;

&lt;p&gt;Here is &lt;code&gt;applicate&lt;/code&gt; which has a case for primitives and procedures&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun applicate (thing arguments bindings)
  (etypecase thing
    (function
     ;; a primitive
     (apply thing arguments))
    (procedure
     (iterate bind ((vtail (procedure-formals thing))
                    (atail arguments)
                    (extended-bindings bindings))
       (cond
        ((and (null vtail) (null atail))
         (iterate eval-body ((btail (procedure-body thing)))
           (if (null (rest btail))
               (evaluate (first btail) extended-bindings)
             (progn
               (evaluate (first btail) extended-bindings)
               (eval-body (rest btail))))))
        ((null vtail)
         (error "too many arguments"))
        ((null atail)
         (error "not enough arguments"))
        (t
         (bind (rest vtail)
               (rest atail)
               (acons (first vtail) (first atail)
                      extended-bindings))))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The thing that makes this evaluator dynamic is that the bindings that &lt;code&gt;applicate&lt;/code&gt; extends are those it was given: procedures do not remember bindings.&lt;/p&gt;

&lt;h2 id="the-lexical-evaluator"&gt;The lexical evaluator&lt;/h2&gt;

&lt;p&gt;A procedure is represented by a structure as before, but this time it has a set of bindings associated with it: the bindings in place when it was created.&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defstruct (procedure
            (:print-function
             (lambda (p s d)
               (declare (ignore d))
               (print-unreadable-object (p s)
                 (format s "λ ~S" (procedure-formals p))))))
  (formals '())
  (body '())
  (bindings '()))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The evaluator is almost identical:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun evaluate (thing bindings)
  (typecase thing
    (symbol
     (let ((found (assoc thing bindings)))
       (unless found
         (error "~S unbound" thing))
       (cdr found)))
    (list
     (destructuring-bind (op . arguments) thing
       (case op
         ((lambda λ)
          (matching arguments
            ((head-matches (list-of #'symbolp))
             (make-procedure :formals (first arguments)
                             :body (rest arguments)
                             :bindings bindings))
            (otherwise
             (error "bad lambda form ~S" thing))))
         ((quote)
          (matching arguments
            ((list-matches (any))
             (first arguments))
            (otherwise
             (error "bad quote form ~S" thing))))
         ((if)
          (matching arguments
            ((list-matches (any) (any))
             (if (evaluate (first arguments) bindings)
                 (evaluate (second arguments) bindings)))
            ((list-matches (any) (any) (any))
             (if (evaluate (first arguments) bindings)
                 (evaluate (second arguments) bindings)
               (evaluate (third arguments) bindings)))
            (otherwise
             (error "bad if form ~S" thing))))
         ((set!)
          (matching arguments
            ((list-matches #'symbolp (any))
             (let ((found (assoc (first arguments) bindings)))
               (unless found
                 (error "~S unbound" (first arguments)))
               (setf (cdr found) (evaluate (second arguments) bindings))))
            (otherwise
             (error "bad set! form ~S" thing))))
         (t
          (applicate (evaluate (first thing) bindings)
                     (mapcar (lambda (form)
                               (evaluate form bindings))
                             (rest thing)))))))
    (t thing)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The differences are that when constructing a procedure the current bindings are recorded in the procedure, and it is no longer necessary to pass bindings to &lt;code&gt;applicate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;applicate&lt;/code&gt; is also almost identical:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun applicate (thing arguments)
  (etypecase thing
    (function
     ;; a primitive
     (apply thing arguments))
    (procedure
     (iterate bind ((vtail (procedure-formals thing))
                    (atail arguments)
                    (extended-bindings (procedure-bindings thing)))
       (cond
        ((and (null vtail) (null atail))
         (iterate eval-body ((btail (procedure-body thing)))
           (if (null (rest btail))
               (evaluate (first btail) extended-bindings)
             (progn
               (evaluate (first btail) extended-bindings)
               (eval-body (rest btail))))))
        ((null vtail)
         (error "too many arguments"))
        ((null atail)
         (error "not enough arguments"))
        (t
         (bind (rest vtail)
               (rest atail)
               (acons (first vtail) (first atail)
                      extended-bindings))))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The difference is that the bindings it extends when binding arguments are the bindings which the procedure remembered, not the dynamically-current bindings, which it does not even know.&lt;/p&gt;

&lt;h2 id="the-difference-between-them"&gt;The difference between them&lt;/h2&gt;

&lt;p&gt;Here is the example that shows how these two evaluators differ.&lt;/p&gt;

&lt;p&gt;With the dynamic evaluator:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;? ((λ (f)
     ((λ (x)
        ;; bind x to 1 around the call to f
        (f))
      1))
   ((λ (x)
      ;; bind x to 2 when the function that will be f is created
      (λ () x))
    2))
1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The binding in effect is the dynamically current one, not the one that was in effect when the procedure was created.&lt;/p&gt;

&lt;p&gt;With the lexical evaluator:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;? ((λ (f)
     ((λ (x)
        ;; bind x to 1 around the call to f
        (f))
      1))
   ((λ (x)
      ;; bind x to 2 when the function that will be f is created
      (λ () x))
    2))
2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the binding in effect is the one that existed when the procedure was created.&lt;/p&gt;

&lt;p&gt;Something more interesting is how you create recursive procedures in the lexical evaluator. With suitable bindings for primitives, it&amp;rsquo;s easy to see that this can&amp;rsquo;t work:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;((λ (length)
   (length '(1 2 3)))
 (λ (l)
   (if (null? l)
       0
       (+ (length (cdr l)) 1))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It can&amp;rsquo;t work because &lt;code&gt;length&lt;/code&gt; is not in scope in the body of &lt;code&gt;length&lt;/code&gt;. it &lt;em&gt;will&lt;/em&gt; work in the dynamic evaluator.&lt;/p&gt;

&lt;p&gt;The first fix, which is similar to what Scheme does with &lt;code&gt;letrec&lt;/code&gt;, is to use assignment to mutate the binding so it is correct:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;((λ (length)
   (set! length (λ (l)
                  (if (null? l)
                      0
                      (+ (length (cdr l)) 1))))
   (length '(1 2 3)))
 0)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the initial value of &lt;code&gt;length&lt;/code&gt; is never used.&lt;/p&gt;

&lt;p&gt;The second fix is to use something like &lt;a href="https://tfeb.org/fragments/2020/03/09/the-u-combinator/"&gt;the U combinator&lt;/a&gt; (you could use Y of course: I think U is simpler to understand):&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;((λ (length)
   (length '(1 2 3)))
 (λ (l)
   ((λ (c)
      (c c l 0))
    (λ (c t s)
      (if (null? t)
          s
          (c c (cdr t) (+ s 1)))))))&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="source-code"&gt;Source code&lt;/h2&gt;

&lt;p&gt;These two evaluators, together with a rudimentary REPL which can use either of them, can be found &lt;a href="https://github.com/tfeb/tiny-eval"&gt;here&lt;/a&gt;.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Dynamic binding without special in Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/02/27/dynamic-binding-without-special-in-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-02-27-dynamic-binding-without-special-in-common-lisp</id>
  <published>2023-02-27T09:53:27Z</published>
  <updated>2023-02-27T09:53:27Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;In Common Lisp, dynamic bindings and lexical bindings live in the same namespace. They don&amp;rsquo;t have to.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Common Lisp has &lt;a href="https://www.tfeb.org/fragments/2023/02/22/how-to-understand-closures-in-common-lisp/" title="How to understand closures in Common Lisp"&gt;two sorts of bindings for variables&lt;/a&gt;: lexical binding and dynamic binding. Lexical binding has lexical scope &amp;mdash; the binding is available where it is visible in source code &amp;mdash; and indefinite extent &amp;mdash; the binding is available as long as any code might reference it. Dynamic binding has indefinite scope &amp;mdash; the binding is available to any code which runs between when the binding is established and when control leaves the form which established it &amp;mdash; and dynamic extent &amp;mdash; the binding ceases to exist when control leaves the binding form.&lt;/p&gt;

&lt;p&gt;These are really two very different things. However CL places both of these kinds of bindings into the same namespace, relying on &lt;code&gt;special&lt;/code&gt; declarations and proclamations to tell the system which sort of binding to create and reference for a given name.&lt;/p&gt;

&lt;p&gt;That doesn&amp;rsquo;t have to be the case: it&amp;rsquo;s possible in CL to completely isolate these two namespaces from each other. This means you could write code where all variable references were to lexical bindings and where dynamic bindings were created and referenced by a completely different set of operators. Here is an example of that. Following practice in some old Lisps I will call this &amp;lsquo;fluid&amp;rsquo; binding. I will also use &lt;code&gt;/&lt;/code&gt; to delimit the names of fluid variables simply to distinguish them from normal variables.&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun inner (varname value)
  (setf (fluid-value varname) value))

(defun outer (varname value)
  (call/fluid-bindings
   (lambda ()
     (values
      (fluid-value varname)
      (progn
        (inner varname (1+ value))
        (fluid-value varname))))
   (list varname)
   (list value)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (outer '/v/ 1)
1
2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here are a set of operators for dealing with these fluid variables:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;fluid-value&lt;/code&gt;&lt;/strong&gt; accesses the value of a fluid variable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;fluid-boundp&lt;/code&gt;&lt;/strong&gt; tells you if a name is bound as a fluid variable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;call/fluid-bindings&lt;/code&gt;&lt;/strong&gt; calls a function with one or more fluid variables bound.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;define-fluid&lt;/code&gt;&lt;/strong&gt; (not used above) defines a global value for a fluid variable.&lt;/p&gt;

&lt;p&gt;Well, of course you can do something like this using an explicit binding stack and a single special variable to hang it from. But that&amp;rsquo;s not how this works: these &amp;lsquo;fluid variables&amp;rsquo; are just CL&amp;rsquo;s dynamic variables:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun call/print-base (f base)
  (call/fluid-bindings  f '(*print-base*) (list base)))&lt;/code&gt;&lt;/pre&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (call/print-base
   (lambda ()
     *print-base*)
   2)
2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So how does this work? Well &lt;code&gt;fluid-value&lt;/code&gt; and &lt;code&gt;fluid-boundp&lt;/code&gt; are obvious:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun fluid-value (s)
  (symbol-value s))

(defun (setf fluid-value) (n s)
  (setf (symbol-value s) n))

(defun fluid-boundp (s)
  (boundp s))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And the trick now is that &lt;em&gt;CL gives you enough mechanism to bind named dynamic variables yourself&lt;/em&gt;, that mechanism being &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/s_progv.htm" title="progv"&gt;progv&lt;/a&gt;, which&lt;/p&gt;

&lt;blockquote&gt;
 &lt;p&gt;[&amp;hellip;] allows binding one or more dynamic variables whose names may be determined at run time [&amp;hellip;]&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;So now &lt;code&gt;call/fluid-bindings&lt;/code&gt; just uses &lt;code&gt;progv&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun call/fluid-bindings (f fluids values)
  (progv fluids values (funcall f)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally &lt;code&gt;define-fluid&lt;/code&gt; looks like this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro define-fluid (var &amp;amp;optional (value nil)
                            (doc nil docp))
  `(progn
     (setf (fluid-value ',var) ,value)
     ,@(if docp
           `((setf (documentation ',var 'variable) ',doc))
         '())
     ',var))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The interesting thing here is that there are no &lt;code&gt;special&lt;/code&gt; declarations or proclamations: you can create and bind new fluid variables without any recourse to &lt;code&gt;special&lt;/code&gt; at all, in a way which is completely compatible with the existing dynamic variables, because fluid variables &lt;em&gt;are&lt;/em&gt; dynamic variables.&lt;/p&gt;

&lt;p&gt;So one way of thinking about &lt;code&gt;special&lt;/code&gt; is that it is a declaration that says &amp;lsquo;for this variable name, access the namespace of dynamic bindings rather than lexical bindings&amp;rsquo;. This is not really what &lt;code&gt;special&lt;/code&gt; was of course in Lisps before CL &amp;mdash; it was historically closer to an instruction to use the interpreter&amp;rsquo;s variable binding mechanism in compiled code &amp;mdash; but you can think of it this way in CL, where the interpreter and compiler do not have separate binding rules.&lt;/p&gt;

&lt;p&gt;And, of course, using something like the above, you could write code in CL where all variable bindings were lexical and dynamic variables lived entirely in their own namespace. For instance this works fine:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun f ()
  (let ((x 2))
    (call/fluid-bindings
     (lambda ()
       (values x (fluid-value 'x)))
     '(x) '(3))))&lt;/code&gt;&lt;/pre&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (f)
2
3&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The reference to &lt;code&gt;x&lt;/code&gt; as a variable refers to its lexical binding, while &lt;code&gt;(fluid-value 'x)&lt;/code&gt; refers to its dynamic binding.&lt;/p&gt;

&lt;p&gt;Whether writing code like that would be useful I am not sure: I think that the &lt;code&gt;*&lt;/code&gt;-convention for dynamic variables is perfectly fine in fact. But it is perhaps interesting to see that you can think of dynamic bindings in CL this way.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">How to understand closures in Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/02/22/how-to-understand-closures-in-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-02-22-how-to-understand-closures-in-common-lisp</id>
  <published>2023-02-22T13:51:07Z</published>
  <updated>2023-02-22T13:51:07Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;The first rule of understanding closures is that you do not talk about closures. The second rule of understanding closures in Common Lisp is that &lt;em&gt;you do not talk about closures&lt;/em&gt;. These are all the rules.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;There is a lot of elaborate bowing and scraping about closures in the Lisp community. But despite that &lt;em&gt;a closure isn&amp;rsquo;t actually a thing&lt;/em&gt;: the thing people call a closure is just a function which obeys the language&amp;rsquo;s rules about the scope and extent of bindings. &lt;em&gt;Implementors&lt;/em&gt; need to care about closures: users just need to understand the rules for bindings. So rather than obsessing about this magic invisible thing which doesn&amp;rsquo;t actually exist in the language, I suggest that it is far better simply to think about the rules which cover &lt;em&gt;bindings&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id="angels-and-pinheads"&gt;Angels and pinheads&lt;/h2&gt;

&lt;p&gt;It&amp;rsquo;s easy to see why this has happened: &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm" title="HyperSpec"&gt;the CL standard&lt;/a&gt; has a lot of discussion of &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_l.htm#lexical_closure" title="lexical closure"&gt;lexical closures&lt;/a&gt;, &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_l.htm#lexical_environment" title="lexical environment"&gt;lexical&lt;/a&gt; and &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_d.htm#dynamic_environment" title="dynamic environment"&gt;dynamic&lt;/a&gt; environments and so on. So it&amp;rsquo;s tempting to think that this way of thinking about things is &amp;lsquo;the one true way&amp;rsquo; because it has been blessed by those who went before us. And indeed CL does have &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/03_aad.htm" title="environment objects"&gt;objects representing part of the lexical environment&lt;/a&gt; which are given to macro functions. Occasionally these are even useful. But there are &lt;em&gt;no&lt;/em&gt; objects which represent closures as distinct from functions, and &lt;em&gt;no&lt;/em&gt; predicates which tell you if a function is a closure or not in the standard language: closures simply do not exist as objects distinct from functions at all. They were useful, perhaps, as part of the text which &lt;em&gt;defined&lt;/em&gt; the language, but they are nowhere to be found in the language itself.&lt;/p&gt;

&lt;p&gt;So, with the exception of the environment objects passed to macros, &lt;em&gt;none&lt;/em&gt; of these objects exist in the language. They may exist in implementations, and might even be exposed by some implementations, but from the point of the view of the language they simply do not exist: if I give you a function object you cannot know if it is a closure or not.&lt;/p&gt;

&lt;p&gt;So it is strange that people spend so much time worrying about these objects which, if they even exist in the implementation, can&amp;rsquo;t be detected by anyone using the standard language. This is worrying about angels and pinheads: wouldn&amp;rsquo;t it be simpler to simply understand what the rules of the language actually say should observably happen? I think it would.&lt;/p&gt;

&lt;p&gt;I am not arguing that the terminology used by the standard is wrong! All I am arguing is that, if you think you want to understand closures, you might instead be better off understanding the rules that give rise to them. And when you have done that you may suddenly find that closures have simply vanished into the mist: all you need is the rules.&lt;/p&gt;

&lt;h2 id="history"&gt;History&lt;/h2&gt;

&lt;p&gt;Common Lisp is steeped in history: it is full of traces of the Lisps which went before it. This is intentional: one goal of CL was to enable programs written in those earlier Lisps &amp;mdash; which were &lt;em&gt;all&lt;/em&gt; Lisps at that time of course &amp;mdash; to run without extensive modification.&lt;/p&gt;

&lt;p&gt;But one place where CL &lt;em&gt;didn&amp;rsquo;t&lt;/em&gt; steep itself in history is in exactly the areas that you need to understand to understand closures. Before Common Lisp (really, before Scheme), people spent a lot of time writing papers about &lt;a href="https://en.wikipedia.org/wiki/Funarg_problem" title="the funarg problem"&gt;the funarg problem&lt;/a&gt; and describing and implementing more-or-less complicated ways of resolving it. Then Scheme came along and decided that this was all nonsense and that it could just be made to go away by implementing the language properly. And the Common Lisp designers, who knew about Scheme, said that, well, if Scheme can do this, then we can do this as well, and so they also made it the problem vanish, although not in quite such an extreme way as Scheme did.&lt;/p&gt;

&lt;p&gt;And this is now ancient history: these predecessor Lisps to CL are all at least 40 years old now. I am, just, old enough to have used some of them when they were current, but for most CL programmers these questions were resolved before they were born. The history is very interesting, but you do not need to steep yourself in it to understand closures.&lt;/p&gt;

&lt;h2 id="bindings"&gt;Bindings&lt;/h2&gt;

&lt;p&gt;So the notion of a closure is part of the history behind CL: a hangover from the time when people worried about the funarg problem; a time before they understood that the whole problem could simply be made to go away. So, again, if you think you want to understand closures, the best approach is to understand something else: to understand &lt;em&gt;bindings&lt;/em&gt;. Just as with closures, bindings do not exist as objects in the language, although you &lt;em&gt;can&lt;/em&gt; make some enquiries about some kinds of bindings in CL. They are also a concept which exists in many programming languages, not just CL.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;binding&lt;/strong&gt; is an association between a name &amp;mdash; a symbol &amp;mdash; and something. The most common binding is a variable binding, which is an association between a name and a value. There are other kinds of bindings however: the most obvious kind in CL is a function binding: an association between a name and a function object. And for example within a (possibly implicit) &lt;code&gt;block&lt;/code&gt; there is a binding between the name of the block and a point to which you can jump. And there are other kinds of bindings in CL as well, and the set is extensible. &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_b.htm#binding" title="binding"&gt;The CL standard&lt;/a&gt; only calls variable bindings &amp;lsquo;bindings&amp;rsquo;, but I am going to use the term more generally.&lt;/p&gt;

&lt;p&gt;Bindings are established by some binding construct and are usually not first-class objects in CL: they are just as vaporous as closures and environments. Nevertheless they are a powerful and useful idea.&lt;/p&gt;

&lt;h2 id="what-can-be-bound"&gt;What can be bound?&lt;/h2&gt;

&lt;p&gt;By far the most common kind of binding is a &lt;strong&gt;variable binding&lt;/strong&gt;: an association between a name and a value. However there are other kinds of bindings: associations between names and other things. I&amp;rsquo;ll mention those briefly at the end, but in everything else that follows it&amp;rsquo;s safe to assume that &amp;lsquo;binding&amp;rsquo; means &amp;lsquo;variable binding&amp;rsquo; unless I say otherwise.&lt;/p&gt;

&lt;h2 id="scope-and-extent"&gt;Scope and extent&lt;/h2&gt;

&lt;p&gt;For both variable bindings and other kinds of bindings there are two interesting questions you can ask:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;em&gt;where&lt;/em&gt; is the binding available?&lt;/li&gt;
 &lt;li&gt;&lt;em&gt;when&lt;/em&gt; is the binding visible?&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The first question is about the &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#scope" title="scope"&gt;&lt;strong&gt;scope&lt;/strong&gt;&lt;/a&gt; of the binding. The second is about the &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_e.htm#extent" title="extent"&gt;&lt;strong&gt;extent&lt;/strong&gt;&lt;/a&gt; of the binding.&lt;/p&gt;

&lt;p&gt;Each of these questions has (at least) two possible answers giving (at least) four possibilities. CL has bindings which use three of these possibilities and the fourth in a restricted case: two and a restricted version of a third for variable bindings, the other one for some other kinds of bindings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scope.&lt;/strong&gt; The two options are:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;the binding may be available only in code where the binding construct is visible;&lt;/li&gt;
 &lt;li&gt;or the binding may be available during all code which runs between where the binding is established and where it ends, regardless of whether the binding construct is visible.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;What does &amp;lsquo;visible&amp;rsquo; mean? Well, given some binding form, it means that the bindings it establishes are visible to all the code that is inside that form in the source. So, in a form like &lt;code&gt;(let ((x 1)) ...)&lt;/code&gt; the binding of &lt;code&gt;x&lt;/code&gt; is visible to the code that replaces the ellipsis, including any code introduced by macroexpansion, and only to that code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extent.&lt;/strong&gt; The two options are:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;the binding may exist only during the time that the binding construct is active, and goes away when control leaves it;&lt;/li&gt;
 &lt;li&gt;or the binding may exist as long as there is any possibility of reference.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Unfortunately the CL standard is, I think, slightly inconsistent in its naming for these options. However I&amp;rsquo;m going to use the standard&amp;rsquo;s terms with one exception. Here they are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scope&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;when a binding is available only when visible this called &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_l.htm#lexical_scope" title="lexical scope"&gt;&lt;strong&gt;lexical scope&lt;/strong&gt;&lt;/a&gt;;&lt;/li&gt;
 &lt;li&gt;when a binding available to all code within the binding construct this is called &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_i.htm#indefinite_scope" title="indefinite scope"&gt;&lt;strong&gt;indefinite scope&lt;/strong&gt;&lt;/a&gt;&lt;sup&gt;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-1-definition" name="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Extent&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;when a binding ends at the end of the binding form this is called &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_d.htm#dynamic_extent" title="dynamic extent"&gt;&lt;strong&gt;dynamic extent&lt;/strong&gt;&lt;/a&gt;&lt;sup&gt;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-2-definition" name="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;;&lt;/li&gt;
 &lt;li&gt;when a binding available indefinitely this called &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_i.htm#indefinite_extent" title="indefinite extent"&gt;&lt;strong&gt;indefinite extent&lt;/strong&gt;&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The term from the standard I am &lt;em&gt;not&lt;/em&gt; going to use is &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_d.htm#dynamic_scope" title="dynamic scope"&gt;&lt;strong&gt;dynamic scope&lt;/strong&gt;&lt;/a&gt;, which it defines to mean the combination of indefinite scope and dynamic extent. I am not going to use this term because I think it is confusing: although it has &amp;lsquo;scope&amp;rsquo; in its name it concerns both scope and extent. Instead I will introduce better, commonly used, terms below for the interesting combinations of scope and extent.&lt;/p&gt;

&lt;p&gt;The four possibilities for bindings are then:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;lexical scope and dynamic extent;&lt;/li&gt;
 &lt;li&gt;lexical scope and indefinite extent;&lt;/li&gt;
 &lt;li&gt;indefinite scope and dynamic extent;&lt;/li&gt;
 &lt;li&gt;indefinite scope and indefinite extent.&lt;/li&gt;&lt;/ul&gt;

&lt;h2 id="the-simplest-kind-of-binding"&gt;The simplest kind of binding&lt;/h2&gt;

&lt;p&gt;So then let&amp;rsquo;s ask: what is the simplest kind of binding to understand? If you are reading some code and you see a reference to a binding then what choice from the above options will make it easiest for you to understand whether that reference is valid or not?&lt;/p&gt;

&lt;p&gt;Well, the first thing is that you&amp;rsquo;d like to be able to know &lt;em&gt;by looking at the code&lt;/em&gt; whether a reference is valid or not. That means that the binding construct should be &lt;em&gt;visible&lt;/em&gt; to you, or that the binding should have lexical scope. Compare the following two fragments of code:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun simple (x)
  ...
  (+ x 1)
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun confusing ()
  ...
  (+ *x* 1)
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, in the first one you can tell, just by looking at the code, that the reference to &lt;code&gt;x&lt;/code&gt; is valid: the function, when called, establishes a binding of &lt;code&gt;x&lt;/code&gt; and you can see that when reading the code. In the second one you just have to assume that the reference to &lt;code&gt;*x*&lt;/code&gt; is valid: you can&amp;rsquo;t tell by reading the code whether it is or not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lexical scope&lt;/strong&gt; makes it easiest for people reading the code to understand it, and in particular it is easier to understand than indefinite scope. It is the simplest kind of scoping to understand for people reading the code.&lt;/p&gt;

&lt;p&gt;So that leaves extent. Well, in the two examples above definite or indefinite extent makes no difference to how simple the code is to understand: once the functions return there&amp;rsquo;s no possibility of reference to the bindings anyway. To expose the difference we need somehow to construct some object which can refer to a binding &lt;em&gt;after the function has returned&lt;/em&gt;. We need something like this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun maker (x)
  ...
  &amp;lt;construct object which refers to binding of x&amp;gt;)

(let ((o (maker 1)))
  &amp;lt;use o somehow to cause it to reference the binding of x&amp;gt;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, what it this object going to be? What sort of things reference bindings? &lt;em&gt;Code&lt;/em&gt; references bindings, and the objects which contain code are &lt;em&gt;functions&lt;/em&gt;&lt;sup&gt;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-3-definition" name="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt;. What we need to do is construct and return a function:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun maker (x)
  (lambda (y)
    (+ x y)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and then cause this function to reference the binding by calling it:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((f (maker 1)))
  (funcall f 2))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So now we can, finally, ask: what is the choice for the &lt;em&gt;extent&lt;/em&gt; of the binding of &lt;code&gt;x&lt;/code&gt; which makes this code simplest to understand? Well, the answer is that unless the binding of &lt;code&gt;x&lt;/code&gt; remains visible to the function that is created in &lt;code&gt;maker&lt;/code&gt;, this code &lt;em&gt;can&amp;rsquo;t work at all&lt;/em&gt;. It would have to be the case that it was simply not legal to return functions like this from other functions. Functions, in other words, would not be first-class objects.&lt;/p&gt;

&lt;p&gt;Well, OK, that&amp;rsquo;s a possibility, and it makes the above code simple to understand: it&amp;rsquo;s not legal and it&amp;rsquo;s easy to see that it is not. Except consider this small variant on the above:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun maybe-maker (x return-identity-p)
  (if return-identity-p
      #'identity
    (lambda (y)
      (+ x y))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There is &lt;em&gt;no way to know&lt;/em&gt; from reading this code whether &lt;code&gt;maybe-maker&lt;/code&gt; will return the nasty anonymous function or the innocuous &lt;code&gt;identity&lt;/code&gt; function. If it is not allowed to return anonymous functions in this way then there is &lt;em&gt;no way of knowing&lt;/em&gt; whether&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(funcall (maybe-maker 1 (zerop (random 2)))
         2)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;is correct or not. This is certainly not simple: in fact it is a horrible nightmare. Another way of saying this is that you&amp;rsquo;d be in a situation where&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(let ((a 1))
  (funcall (lambda ()
             a)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;would work, but&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(funcall (let ((a 1))
           (lambda ()
             a)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;would not. There are languages which work that way: those languages suck.&lt;/p&gt;

&lt;p&gt;So what &lt;em&gt;would&lt;/em&gt; be simple? What would be simple is to say that if a binding is visible, it is visible, and that&amp;rsquo;s the end of the story. In a function like &lt;code&gt;maker&lt;/code&gt; above the binding of &lt;code&gt;x&lt;/code&gt; established by &lt;code&gt;maker&lt;/code&gt; is visible to the function that it returns. Therefore &lt;em&gt;it&amp;rsquo;s visible to the function that &lt;code&gt;maker&lt;/code&gt; returns&lt;/em&gt;: without any complicated rules or weird special cases. That means the binding must have indefinite extent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indefinite extent&lt;/strong&gt; makes it easiest for people reading the code to understand it when that code may construct and return functions, and in particular it is easier to understand than dynamic extent, which makes it essentially impossible to tell in many cases whether such code is correct or not.&lt;/p&gt;

&lt;p&gt;And that&amp;rsquo;s it: lexical scope and indefinite extent, which I will call &lt;strong&gt;lexical binding&lt;/strong&gt;, is the simplest binding scheme to understand for a language which has first-class functions&lt;sup&gt;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-4-definition" name="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-4-return"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;And really &lt;em&gt;that&amp;rsquo;s it&lt;/em&gt;: that&amp;rsquo;s all you need to understand. Lexical scope and indefinite extent make reading code simple, and entirely explain the things people call &amp;lsquo;closures&amp;rsquo; which are, in fact, simply functions which obey these simple rules.&lt;/p&gt;

&lt;h2 id="examples-of-the-simple-binding-rules"&gt;Examples of the simple binding rules&lt;/h2&gt;

&lt;p&gt;One thing I have not mentioned before is that, in CL, bindings are &lt;strong&gt;mutable&lt;/strong&gt;, which is another way of saying that CL supports assignment: assignment to variables is mutation of variable bindings. So, as a trivial example:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun maximum (list)
  (let ((max (first list)))
    (dolist (e (rest list) max)
      (when (&amp;gt; e max)
        (setf max e)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is very easy to understand and does not depend on the binding rules in detail.&lt;/p&gt;

&lt;p&gt;But, well, bindings are mutable, so the rules which say they exist as long as they can be referred to also imply they can be mutated as long as they can be referred to: anything else would certainly not be simple. So here&amp;rsquo;s a classic example of this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun make-incrementor (&amp;amp;optional (value 0))
  (lambda (&amp;amp;optional (increment 1))
    (prog1 value
      (incf value increment))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((i (make-incrementor)))
    (print (funcall i))
    (print (funcall i))
    (print (funcall i -2))
    (print (funcall i))
    (print (funcall i))
    (values))

0
1
2
0
1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, the function returned by &lt;code&gt;make-incrementor&lt;/code&gt; is mutating the binding that it can still see.&lt;/p&gt;

&lt;p&gt;What happens when two functions can see the same binding?&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun make-inc-dec (&amp;amp;optional (value 0))
  (values
   (lambda ()
     (prog1 value
       (incf value)))
   (lambda ()
     (prog1 value
       (decf value)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (multiple-value-bind (inc dec) (make-inc-dec)
    (print (funcall inc))
    (print (funcall inc))
    (print (funcall dec))
    (print (funcall dec))
    (print (funcall inc))
    (values))

0
1
2
1
0&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Again, what happens is the simplest thing: you can see simply from reading the code that both functions can see the &lt;em&gt;same&lt;/em&gt; binding of &lt;code&gt;value&lt;/code&gt; and they are therefore both mutating this common binding.&lt;/p&gt;

&lt;p&gt;Here is an example which demonstrates all these features: an implementation of a simple queue as a pair of functions which can see two shared bindings:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun make-queue ()
  (let ((head '())
        (tail nil))
    (values
     (lambda (thing)
       ;; Push thing onto the queue
       (if (null head)
           ;; It's empty currently so set it up
           (setf head (list thing)
                 tail head)
         ;; not empty: just adjust the tail
         (setf (cdr tail) (list thing)
               tail (cdr tail)))
       thing)
     (lambda ()
       (cond
        ((null head)
         ;; empty
         (values nil nil))
        ((null (cdr head))
         ;; will be empty: don't actually need this case but it is
         ;; cleaner
         (values (prog1 (car head)
                   (setf head '()
                         tail nil))
                 t))
        (t
         ;; will still have content
         (values (pop head) t)))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;make-queue&lt;/code&gt; will return two functions:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;the first takes one argument which it appends to the queue;&lt;/li&gt;
 &lt;li&gt;the second takes no argument and either the next element of the queue and &lt;code&gt;t&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt; and &lt;code&gt;nil&lt;/code&gt; if the queue is empty.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;So, with this little function to drain the queue&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun drain-and-print (popper)
  (multiple-value-bind (value fullp) (funcall popper)
    (when fullp
      (print value)
      (drain-and-print popper))
    (values)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;we can see this in action&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (multiple-value-bind (pusher popper) (make-queue)
    (funcall pusher 1)
    (funcall pusher 2)
    (funcall pusher 3)
    (drain-and-print popper))

1
2
3&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="a-less-simple-kind-of-binding-which-is-sometimes-very-useful"&gt;A less-simple kind of binding which is sometimes very useful&lt;/h2&gt;

&lt;p&gt;Requiring bindings to be simple usually makes programs easy to read and understand. But it also makes it hard to do some things. One of those things is to control the &amp;lsquo;ambient state&amp;rsquo; of a program. A simple example would be the base for printing numbers. It&amp;rsquo;s quite natural to say that &amp;lsquo;in this region of the program I want numbers printed in hex&amp;rsquo;.&lt;/p&gt;

&lt;p&gt;If all we had was lexical binding then this becomes a nightmare: every function you call in the region you want to cause printing to happen in hex needs to take some extra argument which says &amp;lsquo;print in hex&amp;rsquo;. And if you then decide that, well, you&amp;rsquo;d also like some other ambient parameter, you need to provide more arguments to every function&lt;sup&gt;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-5-definition" name="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-5-return"&gt;5&lt;/a&gt;&lt;/sup&gt;. This is just horrible.&lt;/p&gt;

&lt;p&gt;You might think you can do this with global variables which you temporarily set: that is both fiddly (better make sure you set it back) and problematic in the presence of multiple threads&lt;sup&gt;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-6-definition" name="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-6-return"&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;A better approach is to allow &lt;strong&gt;dynamic bindings&lt;/strong&gt;: bindings with indefinite scope &amp;amp; dynamic extent. CL has these, and at this point history becomes unavoidable: rather than have some separate construct for dynamic bindings, CL simply says that some variable bindings, and some references to variable bindings, are to be treated as having indefinite scope and dynamic extent, and you tell the system which bindings this applies to with&lt;code&gt;special&lt;/code&gt; declarations / proclamations. CL does this because that&amp;rsquo;s very close to how various predecessor Lisps worked, and so makes porting programs from them to CL much easier. To make this less painful there is a convention that dynamically-bound variable names have &lt;code&gt;*&lt;/code&gt;stars&lt;code&gt;*&lt;/code&gt; around them, of course.&lt;/p&gt;

&lt;p&gt;Dynamic bindings are so useful that if you don&amp;rsquo;t have them you really need to invent them: I have on at least two occasions implemented a dynamic binding system in Python, for instance.&lt;/p&gt;

&lt;p&gt;However this is not an article on dynamic bindings so I will not write more about them here: perhaps I will write another article later.&lt;/p&gt;

&lt;h2 id="what-else-can-be-bound"&gt;What else can be bound?&lt;/h2&gt;

&lt;p&gt;Variable bindings are by far the most common kind. But not the only kind. Other things can be bound. Here is a partial list&lt;sup&gt;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-7-definition" name="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-7-return"&gt;7&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;strong&gt;local functions&lt;/strong&gt; have lexical scope and indefinite extent;&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;block names&lt;/strong&gt; have lexical scope and definite extent (see below);&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;tag names&lt;/strong&gt; have lexical scope and definite extent (see below);&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;catch tags&lt;/strong&gt; have indefinite scope and definite extent;&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;condition handlers&lt;/strong&gt; have indefinite scope and definite extent;&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;restarts&lt;/strong&gt; have indefinite scope and definite extent.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The two interesting cases here are block names and tag names. Both of these have lexical scope but only definite extent. As I argued above this makes it hard to know whether references to them are valid or not. Look at this, for example:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun outer (x)
  (inner (lambda (r)
           (return-from outer r))
         x))

(defun inner (r rp)
  (if rp
      r
    (funcall r #'identity)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So then &lt;code&gt;(funcall (outer nil) 1)&lt;/code&gt; will: call &lt;code&gt;inner&lt;/code&gt; with a function which wants to return from &lt;code&gt;outer&lt;/code&gt; and &lt;code&gt;nil&lt;/code&gt;, which will cause &lt;code&gt;inner&lt;/code&gt; to call that function, returning the &lt;code&gt;identity&lt;/code&gt; function, which is then called by &lt;code&gt;funcall&lt;/code&gt; with argument &lt;code&gt;1&lt;/code&gt;: the result is 1.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;(funcall (outer t) 1)&lt;/code&gt; will instead return the function which wants to return from &lt;code&gt;outer&lt;/code&gt;, which is then called by &lt;code&gt;funcall&lt;/code&gt; which is an error since it is outside the dynamic extent of the call to &lt;code&gt;outer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And there is no way that either a human reading the code &lt;em&gt;or the compiler&lt;/em&gt; can detect that this is going to happen: a very smart compiler might perhaps be able to deduce that the internal function &lt;em&gt;might&lt;/em&gt; be returned from &lt;code&gt;outer&lt;/code&gt;, but probably only because this is a rather simple case: for instance in&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun nasty (f)
  (funcall f (lambda ()
               (return-from nasty t))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;the situation is just hopeless. So this is a case where the binding rules are not as simple as you might like.&lt;/p&gt;

&lt;h2 id="what-is-simple"&gt;What is simple?&lt;/h2&gt;

&lt;p&gt;For variable bindings I think it&amp;rsquo;s easy to see that the simplest rule for a person reading the code is lexical binding. The other question is whether that is simpler &lt;em&gt;for the implementation&lt;/em&gt;. And the answer is that probably it is not: probably lexical scope and definite extent is the simplest implementationally. That certainly approximates what many old Lisps did&lt;sup&gt;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-8-definition" name="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-8-return"&gt;8&lt;/a&gt;&lt;/sup&gt;. It&amp;rsquo;s fairly easy to write a &lt;em&gt;bad&lt;/em&gt; implementation of lexical binding, simply by having all functions retain all the bindings, regardless of whether they might refer to them. A &lt;em&gt;good&lt;/em&gt; implementation requires more work. But CL&amp;rsquo;s approach here is that doing the right thing &lt;em&gt;for people&lt;/em&gt; is more important than making the implementor&amp;rsquo;s job easier. And I think that approach has worked well.&lt;/p&gt;

&lt;p&gt;On the other hand CL hasn&amp;rsquo;t done the right thing for blocks and tags: There are at least three reasons for this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementational complexity.&lt;/strong&gt; If the bindings had lexical scope and &lt;em&gt;indefinite&lt;/em&gt; extent then you would need to be able to return from a block which had already been returned from, and go to a tag from outside the extent of the form that established it. That opens an enormous can of worms both in making such an implementation work at all but also handling things like dynamic bindings, open files and so on. That&amp;rsquo;s not something the CL designers were willing to impose on implementors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complexity in the specification.&lt;/strong&gt; If CL had lexical bindings for blocks and tags then the specification of the language would need to describe what happens in all the many edge cases that arise, including cases where it is genuinely unclear what the correct thing to do is at all such as dealing with open files and so on. Nobody wanted to deal with that, I&amp;rsquo;m sure: the language specification was already seen as far too big and the effort involved would have made it bigger, later and more expensive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conceptual difficulty.&lt;/strong&gt; It might seem that making block bindings work like lexical variable bindings would make things simpler to understand. Well, that&amp;rsquo;s exactly what Scheme did with &lt;code&gt;call/cc&lt;/code&gt; and &lt;code&gt;call/cc&lt;/code&gt; can give rise to some of the most opaque code I have ever seen. It is often very &lt;em&gt;pretty&lt;/em&gt; code, but it&amp;rsquo;s not easy to understand.&lt;/p&gt;

&lt;p&gt;I think the bargain that CL has struck here is at least reasonable: to make the common case of variable bindings simple for people, and to avoid the cases where doing the right thing results in a language which is harder to understand in many cases and far harder to implement and specify.&lt;/p&gt;

&lt;p&gt;Finally, once again I think that the best way to understand how closures in CL is not to understand them: instead understand the binding rules for variables, why they are simple and what they imply.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;indefinite scope is often called &amp;lsquo;dynamic scope&amp;rsquo; although I will avoid this term as it is used by the standard to mean the combination of indefinite scope and dynamic extent.&amp;nbsp;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;Dynamic extent could perhaps be called &amp;lsquo;definite extent&amp;rsquo;, but this is not the term that the standard uses so I will avoid it.&amp;nbsp;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-3-definition" class="footnote-definition"&gt;
   &lt;p&gt;Here and below I am using the term &amp;lsquo;function&amp;rsquo; in the very loose sense that CL usually uses it: almost none of the &amp;lsquo;functions&amp;rsquo; I will talk about are actually mathematical functions: they&amp;rsquo;re what Scheme would call &amp;lsquo;procedures&amp;rsquo;.&amp;nbsp;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-4-definition" class="footnote-definition"&gt;
   &lt;p&gt;For languages which &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; have first-class functions or equivalent constructs, lexical scope and definite extent is the same as lexical scope and indefinite extent, because it is not possible to return objects which can refer to bindings from the place those bindings were created.&amp;nbsp;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-4-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-5-definition" class="footnote-definition"&gt;
   &lt;p&gt;More likely, you would end up making every function have, for instance an &lt;code&gt;ambient&lt;/code&gt; keyword argument whose value would be an alist or plist which mapped between properties of the ambient environment and values for them. All functions which might call other functions would need this extra argument, and would need to be sure to pass it down suitably.&amp;nbsp;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-5-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-6-definition" class="footnote-definition"&gt;
   &lt;p&gt;This can be worked around, but it&amp;rsquo;s not simple to do so.&amp;nbsp;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-6-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-7-definition" class="footnote-definition"&gt;
   &lt;p&gt;In other words &amp;lsquo;this is all I can think of right now, but there are probably others&amp;rsquo;.&amp;nbsp;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-7-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2023-02-22-how-to-understand-closures-in-common-lisp-footnote-8-definition" class="footnote-definition"&gt;
   &lt;p&gt;Very often old Lisps had indefinite scope and definite extent in interpreted code but lexical scope and definite extent in compiled code: yes, compiled code behaved differently to interpreted code, and yes, that sucked.&amp;nbsp;&lt;a href="#2023-02-22-how-to-understand-closures-in-common-lisp-footnote-8-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">A case-like macro for regular expressions</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2023/01/11/a-case-like-macro-for-regular-expressions/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2023-01-11-a-case-like-macro-for-regular-expressions</id>
  <published>2023-01-11T18:17:29Z</published>
  <updated>2023-01-11T18:17:29Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;I often find myself wanting a simple &lt;code&gt;case&lt;/code&gt;-like macro where the keys are regular expressions. &lt;code&gt;regex-case&lt;/code&gt; is an attempt at this.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;I use &lt;a href="https://edicl.github.io/cl-ppcre/"&gt;CL-PPCRE&lt;/a&gt; for the usual things regular expressions are useful for, and probably for some of the things they should not really be used for as well. I often find myself wanting a &lt;code&gt;case&lt;/code&gt; like macro, where the keys are regular expressions. There is a contributed package for &lt;a href="https://github.com/guicho271828/trivia"&gt;Trivia&lt;/a&gt; which will do this, but Trivia is pretty overwhelming. So I gave in and wrote &lt;code&gt;regex-case&lt;/code&gt; which does what I want.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;regex-case&lt;/code&gt; is a &lt;code&gt;case&lt;/code&gt;-like macro. It looks like&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(regex-case &amp;lt;thing&amp;gt;
  (&amp;lt;pattern&amp;gt; (...)
   &amp;lt;form&amp;gt; ...)
  ...
  (otherwise ()
   &amp;lt;form&amp;gt; ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here &lt;code&gt;&amp;lt;pattern&amp;gt;&lt;/code&gt; is a literal regular expression, either a string or in CL-PPCRE&amp;rsquo;s s-expression parse-tree syntax for them. Unlike &lt;code&gt;case&lt;/code&gt; there can only be a single pattern per clause: allowing the parse-tree syntax makes it hard to do anything else. &lt;code&gt;otherwise&lt;/code&gt; (which can also be &lt;code&gt;t&lt;/code&gt;) is optional but must be last.&lt;/p&gt;

&lt;p&gt;The second form in a clause specifies what, if any, variables to bind on a match. As an example&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(regex-case line
  ("fog\\s+(.*)\\s$" (:match m :registers (v))
    ...)
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will bind &lt;code&gt;m&lt;/code&gt; to the whole match and &lt;code&gt;v&lt;/code&gt; to the substring corresponding to the first register. You can also bind match and register positions. A nice (perhaps) thing is that you can &lt;em&gt;not&lt;/em&gt; bind some register variables:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(regex-case line
  (... (:registers (_ _ v))
   ...)
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will bind &lt;code&gt;v&lt;/code&gt; to the substring corresponding to the third register. You can use &lt;code&gt;nil&lt;/code&gt; instead of &lt;code&gt;_&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The current state of &lt;code&gt;regex-case&lt;/code&gt; is a bit preliminary: in particular I don&amp;rsquo;t like the syntax for binding thngs very much, although I can&amp;rsquo;t think of a better one. Currently therefore it&amp;rsquo;s in my collection of toys: it will probably migrate from there at some point.&lt;/p&gt;

&lt;p&gt;Currently documentation is &lt;a href="https://tfeb.github.io/tfeb-lisp-toys/#case-for-regular-expressions-regex-case"&gt;here&lt;/a&gt; and source code is &lt;a href="https://github.com/tfeb/tfeb-lisp-toys"&gt;here&lt;/a&gt;.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">The empty list</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/12/16/the-empty-list/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-12-16-the-empty-list</id>
  <published>2022-12-16T17:14:32Z</published>
  <updated>2022-12-16T17:14:32Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;My friend Zyni pointed out that someone has been getting really impressively confused and cross on reddit about empty lists, booleans and so on in Common Lisp, which led us to a discussion about what the differences between CL and Scheme really are here. Here&amp;rsquo;s a summary which we think is correct.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="a-peculiar-object-in-common-lisp2022-12-16-the-empty-list-footnote-1-definition2022-12-16-the-empty-list-footnote-1-return1"&gt;A peculiar object in Common Lisp&lt;sup&gt;&lt;a href="#2022-12-16-the-empty-list-footnote-1-definition" name="2022-12-16-the-empty-list-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/h2&gt;

&lt;p&gt;In Common Lisp there is a single special object, &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;This represents both the empty list, and the special false value, all other objects being true.&lt;/li&gt;
 &lt;li&gt;This object is a list and is the only list object which is not a cons.&lt;/li&gt;
 &lt;li&gt;As such this object is an atom, and again it is the only list object which is an atom.&lt;/li&gt;
 &lt;li&gt;You can take the &lt;code&gt;car&lt;/code&gt; and &lt;code&gt;cdr&lt;/code&gt; of this object: both of these operations return the object itself.&lt;/li&gt;
 &lt;li&gt;This object is also a symbol, and it is the only object which is both a list and a symbol.&lt;/li&gt;
 &lt;li&gt;The empty list when written as an empty list, &lt;code&gt;()&lt;/code&gt;, is self-evaluating.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Some comments.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;It is &lt;em&gt;necessary&lt;/em&gt; that there be a special empty-list object which is a list but not a cons: the things which are not necessary are that it be a symbol, and that it represent falsity.&lt;/li&gt;
 &lt;li&gt;Combining the empty list and the special false object can lead to particularly good implementations perhaps.&lt;/li&gt;
 &lt;li&gt;The implementation of this object is always going to be a bit weird.&lt;/li&gt;
 &lt;li&gt;It is clear that the empty list cannot be any kind of compound form so requiring it to be quoted &amp;mdash; requiring you to write &lt;code&gt;'()&lt;/code&gt; really &amp;mdash; serves no useful purpose. Nevertheless I (Tim) would probably rather CL did that.&lt;/li&gt;
 &lt;li&gt;Not having to quote &lt;code&gt;nil&lt;/code&gt; on the other hand is not at all strange: any symbol can be made self-evaluating simply by &lt;code&gt;(defconstant s 's)&lt;/code&gt;, for instance.&lt;/li&gt;
 &lt;li&gt;The graph of types in CL is a DAG, not a tree: it is not at all strange that there is an object whose type is both &lt;code&gt;list&lt;/code&gt; and &lt;code&gt;symbol&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;h2 id="some-entirely-mundane-things-in-common-lisp"&gt;Some entirely mundane things in Common Lisp&lt;/h2&gt;

&lt;ul&gt;
 &lt;li&gt;There is a symbol, &lt;code&gt;t&lt;/code&gt; which represents the canonical true value. Nothing is magic about this symbol in any way: it could be defined by &lt;code&gt;(defconstant t 't)&lt;/code&gt;.&lt;/li&gt;
 &lt;li&gt;There is a type, &lt;code&gt;boolean&lt;/code&gt; which could be defined by &lt;code&gt;(deftype boolean () '(member nil t))&lt;/code&gt;, except that it is required that &lt;code&gt;boolean&lt;/code&gt; be a recognisable subtype of &lt;code&gt;symbol&lt;/code&gt;. All implementations we have tried recognise &lt;code&gt;(member nil t)&lt;/code&gt; as a subtype of &lt;code&gt;symbol&lt;/code&gt;, but the standard does not require them to do so. Additionally &lt;code&gt;(type-of 't)&lt;/code&gt; must return &lt;code&gt;boolean&lt;/code&gt; we think.&lt;/li&gt;
 &lt;li&gt;There is a type, &lt;code&gt;null&lt;/code&gt;, which could be defined by &lt;code&gt;(deftype null () '(member nil))&lt;/code&gt; or &lt;code&gt;(deftype null () '(eql nil))&lt;/code&gt;, with the same caveats as above, and &lt;code&gt;(type-of nil)&lt;/code&gt; should return &lt;code&gt;null&lt;/code&gt;.&lt;/li&gt;
 &lt;li&gt;There are types named &lt;code&gt;t&lt;/code&gt; (top of the type graph) and &lt;code&gt;nil&lt;/code&gt; (bottom of type graph).&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;These mundane things are just that: they don&amp;rsquo;t require implementational magic at all.&lt;/p&gt;

&lt;h2 id="three-peculiar-objects-in-scheme"&gt;Three peculiar objects in Scheme&lt;/h2&gt;

&lt;p&gt;In Scheme there is an object, &lt;code&gt;()&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;()&lt;/code&gt; is the special object that represents the empty list.&lt;/li&gt;
 &lt;li&gt;It does not represent false.&lt;/li&gt;
 &lt;li&gt;It is not a symbol.&lt;/li&gt;
 &lt;li&gt;It is the only list object which is not a pair (cons): &lt;code&gt;list?&lt;/code&gt; is true of it but &lt;code&gt;pair?&lt;/code&gt; is false.&lt;/li&gt;
 &lt;li&gt;You can&amp;rsquo;t take the &lt;code&gt;car&lt;/code&gt; or &lt;code&gt;cdr&lt;/code&gt; of it.&lt;/li&gt;
 &lt;li&gt;It is not self-evaluatiing.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;There is another object, &lt;code&gt;#f&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;#f&lt;/code&gt; is the distinguished false value and is the only false value in Scheme, all other objects being true.&lt;/li&gt;
 &lt;li&gt;It is not a symbol or a list but satisfies the &lt;code&gt;boolean?&lt;/code&gt; predicate.&lt;/li&gt;
 &lt;li&gt;It is self-evaluating.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;There is another object, &lt;code&gt;#t&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;#t&lt;/code&gt; represents the canonical true value, but all objects other than &lt;code&gt;#f&lt;/code&gt; are true.&lt;/li&gt;
 &lt;li&gt;It is not a symbol or a list but satisfies the &lt;code&gt;boolean?&lt;/code&gt; predicate.&lt;/li&gt;
 &lt;li&gt;It is self-evaluating.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Some comments. - Scheme does not have such an elaborate type system as CL and, apart from numbers, doesn&amp;rsquo;t really have subtype relations the way CL does.&lt;/p&gt;

&lt;h2 id="a-summary"&gt;A summary&lt;/h2&gt;

&lt;p&gt;CL&amp;rsquo;s treatment of &lt;code&gt;nil&lt;/code&gt; clearly makes some people very unhappy indeed. In particular they seem to think CL is somehow inconsistent, which it clearly is not. Generally this is either because they don&amp;rsquo;t understand how it works, because it doesn&amp;rsquo;t work the way they want it to work, or (usually) both. Scheme&amp;rsquo;s treatment is often cited by these people as being better. But CL requires &lt;em&gt;precisely one&lt;/em&gt; implementationally-weird object, while Scheme requires two, or three if you count &lt;code&gt;#t&lt;/code&gt; which you probably should. Both languages have idiosyncratic evaluation rules around these objects. Additionally it&amp;rsquo;s worth understanding that things like CL&amp;rsquo;s &lt;code&gt;boolean&lt;/code&gt; type mean essentially nothing implementationally: &lt;code&gt;boolean&lt;/code&gt; is just a name for a set of symbols. The only thing preventing you from defining a type like this yourself is the requirement for &lt;code&gt;type-of&lt;/code&gt; to return the type.&lt;/p&gt;

&lt;p&gt;Is one better than the other? No: they&amp;rsquo;re just not the same. Certainly the CL approach carries more historical baggage. Equally certainly it is perfectly consistent, and changing it would break essentially all CL programs that exist.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Thanks to Zyni for most of this: I&amp;rsquo;m really writing it up just so we can remember it. We&amp;rsquo;re pretty confident about the CL part, less so about the Scheme bit.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2022-12-16-the-empty-list-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;&lt;strong&gt;peculiar&lt;/strong&gt;, &lt;em&gt;adjective&lt;/em&gt;: having eccentric or individual variations in relation to the general or predicted pattern, as in peculiar motion or velocity. &lt;em&gt;noun&lt;/em&gt;: a parish or church exempt from the jurisdiction of the ordinary or bishop in whose diocese it is placed; anything exempt from ordinary jurisdiction.&amp;nbsp;&lt;a href="#2022-12-16-the-empty-list-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Closed as duplicate considered harmful</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/12/05/closed-as-duplicate-considered-harmful/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-12-05-closed-as-duplicate-considered-harmful</id>
  <published>2022-12-05T16:10:07Z</published>
  <updated>2022-12-05T16:10:07Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;The various &lt;a href="https://stackexchange.com/"&gt;Stack Exchange&lt;/a&gt; sites, and specifically &lt;a href="https://stackoverflow.com/questions/tagged/lisp"&gt;Stack Overflow&lt;/a&gt;, seem to be some of the best places for getting reasonable answers to questions on a wide range of topics from competent people. They would be a lot better if they were not so obsessed about closing duplicates.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Closing duplicates seems like a good idea: having a single, canonical, question on a given topic with a single, canonical, answer seems like a good thing. It&amp;rsquo;s not.&lt;/p&gt;

&lt;p&gt;The reason it&amp;rsquo;s not is that it makes two false assumptions:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;that a given question has a single best answer;&lt;/li&gt;
 &lt;li&gt;that this answer does not change over time.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Neither of these assumptions is true for a large number of interesting questions.&lt;/p&gt;

&lt;p&gt;Questions can have several good answers. I have at least three introductory books on &lt;a href="https://en.m.wikipedia.org/wiki/Mathematical_analysis" title="analysis"&gt;analysis&lt;/a&gt;, and not because I didn&amp;rsquo;t find the good one on the first try: I have several because they give different perspectives &amp;mdash; different answers, in the sense of Stack Exchange &amp;mdash; to various aspects of the subject. I have several books on introductory quantum mechanics, several books on introductory general relativity, and so it goes on. It is, simply, a delusion that there exists a single most helpful answer to many questions: pretending that there is stupidly limiting.&lt;/p&gt;

&lt;p&gt;And what constitutes a good answer can change over time. If you asked, for instance, what a macro was in Lisp and what macros are good for, you would have got very different answers in 1982 than in 2022&lt;sup&gt;&lt;a href="#2022-12-05-closed-as-duplicate-considered-harmful-footnote-1-definition" name="2022-12-05-closed-as-duplicate-considered-harmful-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;. The same is true for many other subjects: human knowledge is not static.&lt;/p&gt;

&lt;p&gt;All of this is made worse as only the person asking a question can accept an answer: they may not do so at all or, worse, they may be asking in bad faith and accept wrong or misleading answers (yes, this happens in various Stack Exchanges).&lt;/p&gt;

&lt;p&gt;The true Stack Exchange believer will now explain in great detail&lt;sup&gt;&lt;a href="#2022-12-05-closed-as-duplicate-considered-harmful-footnote-2-definition" name="2022-12-05-closed-as-duplicate-considered-harmful-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt; why none of this matters: people should just spend their time adding improved answers to questions which already have accepted answers rather than to new questions which will be closed as duplicates. Because, of course, the accepted answer will not be the one almost everyone looks at, and even if they don&amp;rsquo;t care about increasing their karma on Stack Exchange, they will be very happy to write answers that, in the real world, almost nobody will ever look at.&lt;/p&gt;

&lt;p&gt;Yeah, right.&lt;/p&gt;

&lt;p&gt;This is such a shame: Stack Exchange is a good thing, but it&amp;rsquo;s seriously damaged by this unnescessary problem. The answer is not simply to allow unrestricted duplicates, but to wait for a bit and see if a question which is, or is nearly, a duplicate has attracted new and interesting answers, and to not close it as a duplicate in that case. This would not be hard to do.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2022-12-05-closed-as-duplicate-considered-harmful-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;And even in 2022 you will get answers from people who seem not to have learned anything since 1982.&amp;nbsp;&lt;a href="#2022-12-05-closed-as-duplicate-considered-harmful-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2022-12-05-closed-as-duplicate-considered-harmful-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;Please, don&amp;rsquo;t: I don&amp;rsquo;t have a Stack Exchange account any more and, even if I did, I would not be interested.&amp;nbsp;&lt;a href="#2022-12-05-closed-as-duplicate-considered-harmful-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Package-local nicknames</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/10/14/package-local-nicknames/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-10-14-package-local-nicknames</id>
  <published>2022-10-14T09:26:31Z</published>
  <updated>2022-10-14T09:26:31Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;What follows is an opinion. Do not under any circumstances read it. Other opinions are available (but wrong).&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Package-local nicknames are an abomination. They should be burned with nuclear fire, and their ashes launched into space on a trajectory which will leave the Solar System.&lt;/p&gt;

&lt;p&gt;The only reason why package-local nicknames matter is if you are writing a lot of code with lots of package-qualified names in it. If you are doing that then &lt;em&gt;you are writing code which is hard to read&lt;/em&gt;: the names in your code are longer than they need to be and the first several characters of them are package name noise (people read, broadly from left to right). Imagine me:a la:version ge:of oe:English oe:where la:people wrote like that: it&amp;rsquo;s just horrible. If you are writing code which is hard to read you are writing bad code.&lt;/p&gt;

&lt;p&gt;Instead you should do the work to construct a namespace in which the words you intend to use are directly present. This means constructing suitable packages: the files containing the package definitions are then almost the only place where package names occur, and are a minute fraction of the total code. Doing this is a good practice in itself because the package definition file is then a place which describes just what names your code needs, from where, and what names it provides. Things like conduit packages (shameless self-promotion) can help with this, which is why I wrote them: being able to say &amp;lsquo;this package exports the combination of the exports of these packages, except &amp;hellip;&amp;rsquo; or &amp;lsquo;this package exports just the following symbols from these packages&amp;rsquo; in an explicit way is very useful.&lt;/p&gt;

&lt;p&gt;If you are now rehearsing a litany of things that can go wrong with this approach in rare cases&lt;sup&gt;&lt;a href="#2022-10-14-package-local-nicknames-footnote-1-definition" name="2022-10-14-package-local-nicknames-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;, please don&amp;rsquo;t: this is not my first rodeo and, trust me, I know about these cases. Occasionally, the CL package system can make it hard or impossible to construct the namespace you need, with the key term here being being &lt;em&gt;occasionally&lt;/em&gt;: people who give up because something is occasionally hard or impossible have what Erik Naggum famously called &amp;lsquo;one-bit brains&amp;rsquo;&lt;sup&gt;&lt;a href="#2022-10-14-package-local-nicknames-footnote-2-definition" name="2022-10-14-package-local-nicknames-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;: the answer is to &lt;em&gt;get more bits for your brain&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Once you write code like this then the only place package-local nicknames can matter is, perhaps, the package definition file. And the only reason they can matter there is because people think that picking a name like &amp;lsquo;XML&amp;rsquo; or &amp;lsquo;RPC&amp;rsquo; or &amp;lsquo;SQL&amp;rsquo; for their packages is a good idea. When people in the programming section of my hollowed-out-volcano lair do this they are &amp;hellip; well, I will not say, but my sharks are well-fed and those things on spikes surrounding the crater are indeed their heads.&lt;/p&gt;

&lt;p&gt;People should use long, unique names for packages. Java, astonishingly, got this right: use domains in big-endian order (&lt;code&gt;org.tfeb.conduit-packages&lt;/code&gt;, &lt;code&gt;org.tfeb.hax.metatronic&lt;/code&gt;). Do not use short nicknames. Never use names without at least one dot, which should be reserved for implementations and perhaps KMP-style substandards. Names will now not clash. Names will be longer and require more typing, but this will not matter because the only place package names are referred to are in package definition files and in &lt;code&gt;in-package&lt;/code&gt; forms, which are a minute fraction of your code.&lt;/p&gt;

&lt;p&gt;I have no idea where or when the awful plague of using package-qualified names in code arose: it&amp;rsquo;s not something people used to do, but it seems to happen really a lot now. I think it may be because people also tend to do this in Python and other dotty languages, although, significantly, in Python you never actually need to do this if you bother, once again, to actually go to the work of constructing the namespace you want: rather than the awful&lt;/p&gt;

&lt;pre class="brush: python"&gt;&lt;code&gt;import sys

... sys.argv ...

...

sys.exit(...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;you can simply say&lt;/p&gt;

&lt;pre class="brush: python"&gt;&lt;code&gt;from sys import argv, exit

... argv ...

exit(...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and now the very top of your module lets anyone reading it know exactly what functionality you are importing and from where it comes.&lt;/p&gt;

&lt;p&gt;It may also be because the whole constructing namespaces thing is a bit hard. Yes, it is indeed a bit hard, but designing programs, of which it is a small but critical part, &lt;em&gt;is&lt;/em&gt; a bit hard.&lt;/p&gt;

&lt;p&gt;OK, enough.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;If, after reading the above, you think you should mail me about how wrong it all is and explain some detail of the CL package system to me: don&amp;rsquo;t, I do not want to hear from you. Really, I don&amp;rsquo;t.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2022-10-14-package-local-nicknames-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;in particular, if your argument is that someone has used, for instance, the name &lt;code&gt;set&lt;/code&gt; in some package to mean, for instance, a set in the sense it is used in maths, and that this clashes with &lt;code&gt;cl:set&lt;/code&gt; and perhaps some other packages, don&amp;rsquo;t. If you are writing a program and you think, &amp;lsquo;I know, I&amp;rsquo;ll use a symbol with the same name as a symbol exported from CL to mean something else&amp;rsquo; in a context where users of your code also might want to use the symbol exported by CL (which in the case of &lt;code&gt;cl:set&lt;/code&gt; is &amp;lsquo;almost never&amp;rsquo;, of course), then my shark pool is just over here: please throw yourself in.&amp;nbsp;&lt;a href="#2022-10-14-package-local-nicknames-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2022-10-14-package-local-nicknames-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;Curiously, I think that quote was about Scheme, which I am sure Erik hated. But, for instance, Racket&amp;rsquo;s module system lets you do just the things which are hard in the package system: renaming things on import, for instance.&amp;nbsp;&lt;a href="#2022-10-14-package-local-nicknames-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Bradshaw's laws</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/10/03/bradshaw-s-laws/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-10-03-bradshaw-s-laws</id>
  <published>2022-10-03T19:50:51Z</published>
  <updated>2022-10-03T19:50:51Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;There are two laws.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="the-laws"&gt;The laws&lt;/h2&gt;

&lt;ol&gt;
 &lt;li&gt;&lt;strong&gt;Bradshaw&amp;rsquo;s law.&lt;/strong&gt; All sufficiently large software systems end up being programming languages.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;Zyni&amp;rsquo;s corollary.&lt;/strong&gt; Whenever you think the point is at which the first law will apply, it will apply before that.&lt;/li&gt;&lt;/ol&gt;

&lt;h2 id="implications-of-the-laws"&gt;Implications of the laws&lt;/h2&gt;

&lt;p&gt;When building software systems you should design them as programming langages. You should do this however small you think they will be. In order to make this practical for small systems you should therefore use a language which allows seamless extension into other languages with insignificant zero-point cost.&lt;/p&gt;

&lt;p&gt;But because the laws are not widely known, most large software systems are built without understanding that what is being built is in fact a programming language. Because people don&amp;rsquo;t know they are building a programming language, don&amp;rsquo;t know how to build programming languages, and do not use languages which make the seamless construction of programming languages easy, the languages they build are usually terrible: they are hard to use, have opaque and inconsistent semantics and are almost always insecure.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Simple logging in Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/09/26/simple-logging-in-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-09-26-simple-logging-in-common-lisp</id>
  <published>2022-09-26T11:26:32Z</published>
  <updated>2022-09-26T11:26:32Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;&lt;code&gt;slog&lt;/code&gt; is a simple logging framework for Common Lisp based on the observation that conditions can represent log events.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;&lt;code&gt;slog&lt;/code&gt; is based on an two observations about the Common Lisp condition system:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;conditions do not have to represent errors, or warnings, but can just be a way of a program saying &amp;lsquo;look, something interesting happened&amp;rsquo;;&lt;/li&gt;
 &lt;li&gt;handlers can decline to handle a condition, and in particular handlers are invoked &lt;em&gt;before the stack is unwound&lt;/em&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Well, saying &amp;lsquo;look, something interesting happened&amp;rsquo; is really quite similar to what logging systems do, and &lt;code&gt;slog&lt;/code&gt; is built on this idea.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;slog&lt;/code&gt; is the &lt;em&gt;simple&lt;/em&gt; logging system: it provides a framework on which logging can be built but does not itself provide a vast category of log severities &amp;amp;c. Such a thing could be built on top of &lt;code&gt;slog&lt;/code&gt;, which aims to provide mechanism, not policy.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;slog&lt;/code&gt; provides a couple of conditions representing log entries, which are designed to be subclassed in real life. Log entries are created using a &lt;code&gt;slog&lt;/code&gt; function (this is why &lt;code&gt;slog&lt;/code&gt; is called &lt;code&gt;slog&lt;/code&gt;: &lt;code&gt;log&lt;/code&gt; is already taken) which simply signals an appropriate condition. Handlers are set up by a &lt;code&gt;logging&lt;/code&gt; form (this should really be called &lt;code&gt;slogging&lt;/code&gt; but it is not), which associates conditions with handlers. There is fairly flexible file handling for logging to files, and in particular you can refer to file names which all get associated with the approprate stream, streams get closed automagically (and you can manually close them, when they will be reopened if need be), and the underlying mechanism for writing entries is exposed by a &lt;code&gt;slog-to&lt;/code&gt; generic function which could be extended. Log entry formats can be controlled in various ways.&lt;/p&gt;

&lt;p&gt;In addition &lt;code&gt;slog&lt;/code&gt; tries to associate log entries with &amp;lsquo;precision time&amp;rsquo;, which is CL&amp;rsquo;s universal time expanded to the precision of a millisecond, or of internal time if it is less precise than a millisecond. Setting this up means that &lt;code&gt;slog&lt;/code&gt; takes a second or so to load.&lt;/p&gt;

&lt;p&gt;Once again: &lt;code&gt;slog&lt;/code&gt; is a &lt;em&gt;framework&lt;/em&gt;: it has no dealings with log severities, catagories, or anything like that. All that is meant to be provided on top of what &lt;code&gt;slog&lt;/code&gt; provides.&lt;/p&gt;

&lt;p&gt;Documentation is &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#simple-logging-slog"&gt;here&lt;/a&gt;, source code is &lt;a href="https://github.com/tfeb/tfeb-lisp-hax"&gt;here&lt;/a&gt;. It will be available from Quicklisp in due course.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Metatronic macros</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/09/26/metatronic-macros/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-09-26-metatronic-macros</id>
  <published>2022-09-26T10:54:25Z</published>
  <updated>2022-09-26T10:54:25Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Metatronic macros are a simple hack which makes it a little easier to write less unhygienic macros in Common Lisp.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Common Lisp macros require you to avoid variable name capture yourself. So, for a macro which iterates over the lines in a file, this is wrong:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro with-file-lines ((line file) &amp;amp;body forms)
  ;; wrong
  `(with-open-file (in ,file)
     (do ((,line (read-line in nil in)
                 (read-line in nil in)))
         ((eq ,line in))
       ,@forms)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&amp;rsquo;s wrong because it binds &lt;code&gt;in&lt;/code&gt; to the stream open to the file, and user code could perfectly legitimately refer to a variable of the same name.&lt;/p&gt;

&lt;p&gt;The standard approach to dealing with this is to use gensyms:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro with-file-lines ((line file) &amp;amp;body forms)
  ;; righter
  (let ((inn (gensym)))
    `(with-open-file (,inn ,file)
     (do ((,line (read-line ,inn nil ,inn)
                 (read-line ,inn nil ,inn)))
         ((eq ,line inn))
       ,@forms))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates a new symbol bound to &lt;code&gt;inn&lt;/code&gt; (&lt;code&gt;in&lt;/code&gt;&amp;rsquo;s name), and then uses it as the name of the variable bound to the stream. Code can&amp;rsquo;t then use any variable with this unique name.&lt;/p&gt;

&lt;p&gt;This works, but it&amp;rsquo;s ugly. Metatronic macros let you write the above like this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro/m with-file-lines ((line file) &amp;amp;body forms)
  ;; righter, easier
  `(with-open-file (&amp;lt;in&amp;gt; ,file)
     (do ((,line (read-line &amp;lt;in&amp;gt; nil &amp;lt;in&amp;gt;)
                 (read-line &amp;lt;in&amp;gt; nil &amp;lt;in&amp;gt;)))
         ((eq ,line &amp;lt;in&amp;gt;))
       ,@forms)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this macro all symbols which look like &lt;code&gt;&amp;lt;&lt;/code&gt;&amp;hellip;&lt;code&gt;&amp;gt;&lt;/code&gt; (in any package) are rewritten to unique names, but all references to symbols with the same original name are to the same symbol&lt;sup&gt;&lt;a href="#2022-09-26-metatronic-macros-footnote-1-definition" name="2022-09-26-metatronic-macros-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;. This makes this common case more pleasant to do: macros written using &lt;code&gt;defmacro/m&lt;/code&gt; have less noise around their expansion.&lt;/p&gt;

&lt;p&gt;Metatronic macros go to some lengths to avoid leaking the rewritten symbols. Given this silly macro&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro/m silly ()
  ''&amp;lt;silly&amp;gt;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then &lt;code&gt;(eq (silly) (silly))&lt;/code&gt; is false. Similarly given this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro/m also-silly (f)
  `(eq ,f '&amp;lt;silly&amp;gt;))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then &lt;code&gt;(also-silly '&amp;lt;silly&amp;gt;)&lt;/code&gt; will be false of course.&lt;/p&gt;

&lt;p&gt;There is &lt;code&gt;defmacro/m&lt;/code&gt;, &lt;code&gt;macrolet/m&lt;/code&gt; and &lt;code&gt;define-compiler-macro/m&lt;/code&gt;, and the implementation of metatronization is exposed if you need it.&lt;/p&gt;

&lt;p&gt;Documentation is &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#metatronic-macros"&gt;here&lt;/a&gt;, source code is &lt;a href="https://github.com/tfeb/tfeb-lisp-hax"&gt;here&lt;/a&gt;. It will be available in Quicklisp in due course.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2022-09-26-metatronic-macros-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;in fact, a symbol whose name is &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; is rewritten as a unique gensym as a special case. I am not sure if this is a good thing but it&amp;rsquo;s what happens.&amp;nbsp;&lt;a href="#2022-09-26-metatronic-macros-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Macros (from Zyni)</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/08/27/macros-from-zyni/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-08-27-macros-from-zyni</id>
  <published>2022-08-27T10:12:33Z</published>
  <updated>2022-08-27T10:12:33Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;blockquote&gt;
 &lt;p&gt;It is the business of the future to be dangerous; and it is among the merits of science that it equips the future for its duties.  &amp;mdash; Alfred Whitehead&lt;/p&gt;&lt;/blockquote&gt;
&lt;!-- more--&gt;

&lt;p&gt;Once upon a time, long ago in a world far away, Lisp had many features which other languages did not have. Automatic storage management, dynamic typing, an interactive environment, lists, symbols &amp;hellip; and macros, which allow you to seamlessly extend the language you have into the language you want and need.&lt;/p&gt;

&lt;p&gt;But that was long long ago in a world far away where giants roamed the earth, trolls lurked under every bridge and, they say, gods yet lived on certain distant mountains.&lt;/p&gt;

&lt;p&gt;Today, and in this world, many many languages have automatic storage management, are dynamically typed, have symbols, lists, interactive environments, and so and so and so. More of these languages arise from the thick, evil-smelling sludge that coats every surface each day: hundreds, if not thousands of them, like flies breeding on bad meat which must be swatted before they lay their eggs on your eyes.&lt;/p&gt;

&lt;p&gt;Lisp, today and in this world not another, has &lt;em&gt;exactly one&lt;/em&gt; feature which still distinguishes it from the endless buzz of these insect languages. That feature is seamless language extension by macros.&lt;/p&gt;

&lt;p&gt;So yes, macros are dangerous, and they are hard and they are frightening. They are dangerous and hard and frightening because all powerful magic is dangerous and hard and frightening. They are dangerous because they are a thing which has escaped here from the future and it is the business of the future to be dangerous.&lt;/p&gt;

&lt;p&gt;If macros are too dangerous, too hard and too frightening for you, &lt;em&gt;do not use Lisp&lt;/em&gt; because &lt;em&gt;macros are what Lisp is about&lt;/em&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;This originated as a comment by my friend Zyni: it is used with her permission.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Two simple pattern matchers for Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/07/21/two-simple-pattern-matchers-for-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-07-21-two-simple-pattern-matchers-for-common-lisp</id>
  <published>2022-07-21T09:17:45Z</published>
  <updated>2022-07-21T09:17:45Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;I&amp;rsquo;ve written two pattern matchers for Common Lisp:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;destructuring-match&lt;/code&gt;, or &lt;code&gt;dsm&lt;/code&gt;, is a &lt;code&gt;case&lt;/code&gt;-style construct which can match &lt;code&gt;destructuring-bind&lt;/code&gt;-style lambda lists with a couple of extensions;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;spam&lt;/code&gt;, the simple pattern matcher, does not bind variables but lets you match based on assertions about, for instance, the contents of lists.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Both &lt;code&gt;dsm&lt;/code&gt; and &lt;code&gt;spam&lt;/code&gt; strive to be simple and correct.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="simplicity"&gt;Simplicity&lt;/h2&gt;

&lt;p&gt;Both &lt;code&gt;dsm&lt;/code&gt; and &lt;code&gt;spam&lt;/code&gt; are &lt;em&gt;simple&lt;/em&gt;: they do exactly one thing, and try to do that one thing well.&lt;/p&gt;

&lt;p&gt;You could think of &lt;code&gt;dsm&lt;/code&gt; as being to some other CL pattern matchers as Unix once was to Multics: &lt;code&gt;dsm&lt;/code&gt; is the result of me looking at those other systems and thinking &amp;lsquo;please, not that&amp;rsquo;.&lt;/p&gt;

&lt;p&gt;Those systems are vast, have several levels, and are extensible: some subset of them might do what I wanted to be able to do &amp;mdash; make writing macros less unpleasant &amp;mdash; but I&amp;rsquo;m not sure&lt;sup&gt;&lt;a href="#2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-1-definition" name="2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;. They are obsessed with performance.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dsm&lt;/code&gt; does one thing, and exports a single macro. If you know how to use &lt;code&gt;destructuring-bind&lt;/code&gt; and &lt;code&gt;case&lt;/code&gt; you already know almost all there is to know about &lt;code&gt;dsm&lt;/code&gt;: it&amp;rsquo;s a &lt;code&gt;case&lt;/code&gt; construct whose cases are &lt;code&gt;destructuring-bind&lt;/code&gt; lambda lists. &lt;code&gt;dsm&lt;/code&gt; doesn&amp;rsquo;t care about performance at all, because macroexpansion performance never matters.&lt;/p&gt;

&lt;p&gt;At least one of those matchers has almost as many commits in its repo as dsm has lines of code.&lt;/p&gt;

&lt;p&gt;Like Multics was, those hairy pattern matchers are fine systems. But there was a good reason that Thompson and Ritchie wrote something very different&lt;sup&gt;&lt;a href="#2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-2-definition" name="2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h2 id="destructuring-match--dsm"&gt;&lt;code&gt;destructuring-match&lt;/code&gt; / &lt;code&gt;dsm&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;in CL &lt;code&gt;destructuring-bind&lt;/code&gt; and, mostly equivalently, macro argument lists are both a blessing and a curse. They&amp;rsquo;re a blessing because they support destructuring, so you can write, for instance&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro with-foo ((var &amp;amp;optional init) &amp;amp;body forms)
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;They&amp;rsquo;re a curse because they are so fragile: &lt;code&gt;with-foo&lt;/code&gt; can &lt;em&gt;only&lt;/em&gt; support that syntax and will fail with an ugly error message from the implementation when it is fed anything else.&lt;/p&gt;

&lt;p&gt;Writing robust macros in CL, especially macros which expect various different argument patterns, then turns into a great saga of manually checking argument patterns before using &lt;code&gt;destructuring-bind&lt;/code&gt; to actually bind things. The result of that, of course, is that very many CL macros are not robust and have terrible error reporting.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;destructuring-match&lt;/code&gt; does away with all this unpleasentness. It supports a slightly extended version of the lambda lists that &lt;code&gt;destructuring-bind&lt;/code&gt; supports, has &amp;lsquo;guard&amp;rsquo; clauses which allow additional checks, and will match a form against any number of lambda lists until one matches, with a fallback case.&lt;/p&gt;

&lt;p&gt;As an example here is a version of &lt;code&gt;with-foo&lt;/code&gt; which allows two patterns:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro with-foo (&amp;amp;body forms)
  (destructuring-match forms
    (((var &amp;amp;optional init) &amp;amp;body body)
     (:when (symbolp var))
     ...)
    ((((var &amp;amp;optional type) &amp;amp;optional init) &amp;amp;body body)
     (:when (symbolp var))
     ...)
    (otherwise
     (error ...))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The guard clauses check that &lt;code&gt;var&lt;/code&gt; is a symbol before the match succeeds, and will therefore ensure that the second match is the one chosen for &lt;code&gt;(with-foo ((x y) 1) ...)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;destructuring-match&lt;/code&gt; also supports &amp;lsquo;blank&amp;rsquo; variables: any variable whose name is &lt;code&gt;_&lt;/code&gt; (in any package) is ignored, and all such variables are distinct. So for instance&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(destructuring-match l
  ((_ _ _) ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will match if &lt;code&gt;l&lt;/code&gt; is a proper list with exactly three elements.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;destructuring-match&lt;/code&gt; it&amp;rsquo;s easy to write this macro&lt;sup&gt;&lt;a href="#2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-3-definition" name="2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro define-matching-macro (name &amp;amp;body clauses)
  (let ((&amp;lt;whole&amp;gt; (make-symbol "WHOLE"))
        (&amp;lt;junk&amp;gt; (make-symbol "JUNK")))
    (destructuring-match clauses
      ((doc . the-clauses)
       (:when (stringp doc))
       `(defmacro ,name (&amp;amp;whole ,&amp;lt;whole&amp;gt; &amp;amp;rest ,&amp;lt;junk&amp;gt;)
          ,doc
          (destructuring-match ,&amp;lt;whole&amp;gt; ,@the-clauses)))
      (the-clauses
       `(defmacro ,name (&amp;amp;whole ,&amp;lt;whole&amp;gt; &amp;amp;rest ,&amp;lt;junk&amp;gt;)
          (destructuring-match ,&amp;lt;whole&amp;gt; ,@the-clauses))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this then allows the above &lt;code&gt;with-foo&lt;/code&gt; macro to be written like this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(define-matching-macro with-foo
  ((_ (var &amp;amp;optional init) &amp;amp;body forms)
   (:when (symbolp var))
   ...)
  ((_ ((var &amp;amp;optional type) &amp;amp;optional init) &amp;amp;body forms)
   (:when (symbolp var))
   ...)
  (form
   (error "~S is bad syntax for with-foo" form)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;dsm&lt;/code&gt; was not written with performance in mind but it seems to be, typically, around a tenth to a half the speed of &lt;code&gt;destructuring-bind&lt;/code&gt; while being far more powerful of course.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dsm&lt;/code&gt; can be found &lt;a href="https://tfeb.github.io/#destructuring-match-for-common-lisp"&gt;here&lt;/a&gt;. It will probably end up in Quicklisp in due course but currently it isn&amp;rsquo;t there, and some of its dependencies are also not up to date there.&lt;/p&gt;

&lt;h2 id="spam-the-simple-pattern-matcher"&gt;&lt;code&gt;spam&lt;/code&gt;, the simple pattern matcher&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;dsm&lt;/code&gt; has a lot of cases where it needs to check what the lambda list it is parsing and compiling looks like. To do this I wrote a bunch of predicate constructors and combinators, which return predicates which will check things. So for example:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;(is 'foo)&lt;/code&gt; returns a function which checks its argument is &lt;code&gt;eql&lt;/code&gt; to &lt;code&gt;foo&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;(some-of p1 ... pn)&lt;/code&gt; returns a function of one argument which will succeed if one of the predicates which are its arguments succeeds, so &lt;code&gt;(some-of (is 'foo) (is 'bar))&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;(head-matches p1 ... pn)&lt;/code&gt; will succeed if the predicates which are its arguments succeed on the first elements of a list.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;There are several other predicate constructrors and predicate combinators, but &lt;code&gt;spam&lt;/code&gt; can use any predicate.&lt;/p&gt;

&lt;p&gt;There is then a &lt;code&gt;matches&lt;/code&gt; macro which uses these to match things, and a &lt;code&gt;matchp&lt;/code&gt; function which simply invokes a predicate.&lt;/p&gt;

&lt;p&gt;As an example, here&amp;rsquo;s part of a matcher for &lt;code&gt;&amp;amp;rest&lt;/code&gt; specifications in lambda lists.&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(matching ll
  ((head-matches (some-of (is '&amp;amp;rest) (is '&amp;amp;body))
                 (var)
                 (is '&amp;amp;key))
   ;; &amp;amp;rest x &amp;amp;key ...
   ...)
   ((head-matches (some-of (is '&amp;amp;rest) (is '&amp;amp;body))
                  (var)
                  (any))
    ;; &amp;amp;rest x with something else
    ...)
   ((list-matches (some-of (is '&amp;amp;rest) (is '&amp;amp;body))
                  (var))
    ;; &amp;amp;rest x and no more
    ...)
   (otherwise
    (error "oops")))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;spam&lt;/code&gt; is pretty useful, and code written using it is much easier to read than doing the equivalent checks manually. It is used extensively in the implementation of &lt;code&gt;dsm&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;spam&lt;/code&gt; is now one of &lt;a href="https://tfeb.github.io/#some-common-lisp-hacks"&gt;my CL hax&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;At the time of writing &lt;a href="https://github.com/guicho271828/trivia"&gt;Trivia&lt;/a&gt; supports lambda lists I think, but not destructuring-lambda lists: &lt;code&gt;(match '(1 (1)) ((lambda-list a (b)) (values a b)))&lt;/code&gt; will fail, for instance. I don&amp;rsquo;t know whether is it &lt;em&gt;meant&lt;/em&gt; to support destructuring lambda lists &amp;mdash; comments in the sources imply it is, but it clearly does not in fact.&amp;nbsp;&lt;a href="#2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;I am aware of &lt;a href="https://dreamsongs.com/WIB.html"&gt;Gabriel&amp;rsquo;s &amp;lsquo;worse is better&amp;rsquo; paper&lt;/a&gt; and its various afterthoughts. &lt;code&gt;dsm&lt;/code&gt; is not like that: it is smaller and simpler, but is not intended to be worse. &lt;code&gt;dsm&lt;/code&gt; is to these other systems perhaps as Scheme was to CL. Gabriel also talks about these two options, of course.&amp;nbsp;&lt;a href="#2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-3-definition" class="footnote-definition"&gt;
   &lt;p&gt;Note this macro is 12 lines, half of which are handling the possible docstring.&amp;nbsp;&lt;a href="#2022-07-21-two-simple-pattern-matchers-for-common-lisp-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Macroexpansion in Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/07/05/macroexpansion-in-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-07-05-macroexpansion-in-common-lisp</id>
  <published>2022-07-05T15:16:29Z</published>
  <updated>2022-07-05T15:16:29Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Yet another description of macroexpansion in Common Lisp. There is nothing particuarly new here and it partly duplicates some previous articles: I just wanted to rescue the text.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;The following description is of how macroexpansion works in Common Lisp&lt;sup&gt;&lt;a href="#2022-07-05-macroexpansion-in-common-lisp-footnote-1-definition" name="2022-07-05-macroexpansion-in-common-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;. It is slightly simplified and I have not always mentioned when it is&lt;sup&gt;&lt;a href="#2022-07-05-macroexpansion-in-common-lisp-footnote-2-definition" name="2022-07-05-macroexpansion-in-common-lisp-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;. It is at least a partial duplicate of &lt;a href="../../../../2021/11/11/the-proper-use-of-macros-in-lisp/"&gt;this previous article&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="what-macros-are"&gt;What macros are&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Macros in CL are functions, written in ordinary CL, whose argument is source code, and whose value is other source code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Source code is represented as s-expressions: symbols, conses, and so on. Macros don&amp;rsquo;t do string-rewriting.&lt;/p&gt;

&lt;p&gt;The way to think slightly more abstractly about macros is that they are &lt;em&gt;functions between languages&lt;/em&gt;: a macro is a function which takes as an argument fragments of a language which includes that macro, and returns as a value either a fragment of a language which &lt;em&gt;doesn&amp;rsquo;t&lt;/em&gt; include the macro, or a fragment of a language which includes it in some weaker way.&lt;/p&gt;

&lt;p&gt;The aim of macros is to build, on top of the language you are given, another language which is closer to the language in which you want to express your programs. CL itself is one such language, built-up using a number of standard macros on top of a substrate language.&lt;/p&gt;

&lt;p&gt;People often think of macros as &amp;lsquo;functions which do not evaluate their arguments&amp;rsquo;: that&amp;rsquo;s really not right. They are functions &amp;mdash; perfectly ordinary functions, written in CL &amp;mdash; but their argument is source code, and their value is source code.&lt;/p&gt;

&lt;h2 id="how-macroexpansion-happens"&gt;How macroexpansion happens&lt;/h2&gt;

&lt;p&gt;[This is simplified.]&lt;/p&gt;

&lt;p&gt;Given some initial compound form &lt;code&gt;(m ...)&lt;/code&gt;, macroexpansion proceeds like this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start.&lt;/strong&gt; Given a form, it should be one of&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;a compound form &lt;code&gt;(m ...)&lt;/code&gt;,&lt;/li&gt;
 &lt;li&gt;or a non-compound form.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Compound form.&lt;/strong&gt; The form is &lt;code&gt;(m ...)&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;Look at &lt;code&gt;m&lt;/code&gt;: if it has an associated macro function (found using &lt;code&gt;macro-function&lt;/code&gt;) then simply call that function on the whole form &lt;code&gt;(m ...)&lt;/code&gt;: its result is a new form&lt;sup&gt;&lt;a href="#2022-07-05-macroexpansion-in-common-lisp-footnote-3-definition" name="2022-07-05-macroexpansion-in-common-lisp-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt;. Recurse on this form from &lt;strong&gt;Start&lt;/strong&gt;.&lt;/li&gt;
 &lt;li&gt;If &lt;code&gt;m&lt;/code&gt; is not a macro, then it may be a special operator, such as &lt;code&gt;setq&lt;/code&gt; or &lt;code&gt;if&lt;/code&gt;. Consider appropriate forms in the body of this form for expansion: which forms are known by the rules of the special operator. For instance all the forms in &lt;code&gt;(if ...)&lt;/code&gt; are considered for expansion, while in &lt;code&gt;(setq &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;)&lt;/code&gt; only &lt;code&gt;&amp;lt;y&amp;gt;&lt;/code&gt; is, and so on.&lt;/li&gt;
 &lt;li&gt;If it is not a macro and not a special form, then &lt;code&gt;(m ...)&lt;/code&gt; is assumed to be a function call, with &lt;code&gt;m&lt;/code&gt; denoting a function. All the forms in the body are now considered for macro expansion. Once that is done the expansion process is complete.&lt;/li&gt;
 &lt;li&gt;As a special case of the last case, &lt;code&gt;m&lt;/code&gt; may be &lt;code&gt;(lambda (...) ...)&lt;/code&gt;, so the whole form will be &lt;code&gt;((lambda (...) ...) ...)&lt;/code&gt;. In this case the forms in the body of the &lt;code&gt;lambda&lt;/code&gt; are considered for macroexpansion; otherwise this is the same as the last case&lt;sup&gt;&lt;a href="#2022-07-05-macroexpansion-in-common-lisp-footnote-4-definition" name="2022-07-05-macroexpansion-in-common-lisp-footnote-4-return"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
 &lt;li&gt;There are no other cases.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Non-compound form.&lt;/strong&gt; There is nothing to do here.&lt;/p&gt;

&lt;p&gt;As I said, this is simplified: there are local macros for instance, and various other things. However one critical thing is that when expanding some macro form &lt;code&gt;(m ...)&lt;/code&gt;, the expansion carries on until it gets something which is not a macro form &lt;em&gt;before&lt;/em&gt; looking at whatever is in the body of the form. That&amp;rsquo;s critical: although it&amp;rsquo;s tempting to think that expansion should happen inside-out, it can&amp;rsquo;t work that way, because until the outer macro has done its work you can&amp;rsquo;t know if the things in its body even &lt;em&gt;should&lt;/em&gt; be candidates for macro expansion. There&amp;rsquo;s an example of this below.&lt;/p&gt;

&lt;h2 id="macros-the-hard-way"&gt;Macros the hard way&lt;/h2&gt;

&lt;p&gt;OK, I said that macros were just functions, and I meant that. Let&amp;rsquo;s write a macro &lt;code&gt;with-debugging&lt;/code&gt; which is like &lt;code&gt;progn&lt;/code&gt; but it will perhaps print what it is doing.&lt;/p&gt;

&lt;p&gt;So let&amp;rsquo;s write the macro function:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defvar *debugging* t)

(defun expand-with-debugging (form environment)
  (declare (ignore environment))        ;I'm not mentioning environments
  `(progn
     ,@(loop for thing in (rest form)
             collect `(when *debugging*
                        (format *debug-io* "~&amp;amp;~S~%" ',thing))
             collect thing)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And we can test it:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (expand-with-debugging '(with-debugging (cons 1 2) 4) nil)
(progn
  (when *debugging* (format *debug-io* "~&amp;amp;~S~%" '(cons 1 2)))
  (cons 1 2)
  (when *debugging* (format *debug-io* "~&amp;amp;~S~%" '4))
  4)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now we can install it as the macro function for &lt;code&gt;with-debugging&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(setf (macro-function 'with-debugging) #'expand-with-debugging)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (with-debugging
   (cons 1 2)
   4)
(cons 1 2)
4
4&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; (setf *debugging* nil)
nil

&amp;gt; (with-debugging
   (cons 1 2)
   4)
4&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;OK, here&amp;rsquo;s another macro done this way, and purpose of this one is to show you why macroexpansion has to happen outside in. Let&amp;rsquo;s say we want to be able to denote functions by &lt;code&gt;(fun (arg ...) form ...)&lt;/code&gt;, but we&amp;rsquo;d like to be able to debug the body with &lt;code&gt;with-debugging&lt;/code&gt;. We can do that:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun expand-fun (form environment)
  (declare (ignore environment))        ;still not mentioning environments
  `(function (lambda ,(second form)
               ;; Not dealing with declarations
               (with-debugging ,@(cddr form)))))

(setf (macro-function 'fun) #'expand-fun)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((*debugging* t))
    (funcall (fun (a) (+ a a)) 1))
(+ a a)
2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can see why the macro expander has to work the way it does: the first form in the body of &lt;code&gt;fun&lt;/code&gt; should not be macroexpanded at all, and the remaining forms are going to get wrapped in a macro which isn&amp;rsquo;t there in the source at all. So macroexpansion has to go outside in, as described above.&lt;/p&gt;

&lt;h2 id="a-better-way"&gt;A better way&lt;/h2&gt;

&lt;p&gt;Well, you could write macros like that. Probably once they were written like that. But it&amp;rsquo;s a pain, because you almost never care about the first element of the form &amp;mdash; the macros own name &amp;mdash; and you have to manually take the rest of the form apart yourself. And also you need to deal with questions about making sure macros are defined at compile time and so on.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s what &lt;code&gt;defmacro&lt;/code&gt; does. It is itself a macro, and its expansion will involve setting the &lt;code&gt;macro-function&lt;/code&gt; of the macro to some appropriate thing. So using &lt;code&gt;defmacro&lt;/code&gt; I can write the &lt;code&gt;fun&lt;/code&gt; macro:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro fun ((&amp;amp;rest args) &amp;amp;body forms)
  ;; still not dealing with declarations
  `(function (lambda (,@args) (with-debugging ,@forms))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is easier to understand of course. But all it is is a (fairly elaborate!) wrapper around what I did above.&lt;/p&gt;

&lt;h2 id="watching-the-detectives"&gt;Watching the detectives&lt;/h2&gt;

&lt;p&gt;Using &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#tracing-macroexpansion-trace-macroexpand"&gt;&lt;code&gt;trace-macroexpand&lt;/code&gt;&lt;/a&gt; you can watch macroexpansion happen.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (needs (:org.tfeb.hax.trace-macroexpand :compile t :use t))
; Loading [...]
((:org.tfeb.hax.trace-macroexpand t))

&amp;gt; (trace-macroexpand t)
nil

&amp;gt; (trace-macro fun with-debugging)
&amp;gt; (setf *trace-macroexpand-print-length* nil
        *trace-macroexpand-print-level* nil)
nil

&amp;gt; (trace-macro fun with-debugging)
(fun with-debugging)

&amp;gt; (setf *debugging* nil)                
nil

&amp;gt; (funcall (fun (a) a) 1)
(fun (a) a)
 -&amp;gt; #'(lambda (a) (with-debugging a))
(with-debugging a)
 -&amp;gt; (progn (when *debugging* (format *debug-io* "~&amp;amp;~S~%" 'a)) a)
(with-debugging a)
 -&amp;gt; (progn (when *debugging* (format *debug-io* "~&amp;amp;~S~%" 'a)) a)
1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that &lt;code&gt;with-debugging&lt;/code&gt; is expanded twice: this is an artifact of the implementation: there&amp;rsquo;s no promise that macros only get expanded once in interpreted code.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2022-07-05-macroexpansion-in-common-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;This was once going to be a Stack Overflow answer, and I didn&amp;rsquo;t want to throw it away.&amp;nbsp;&lt;a href="#2022-07-05-macroexpansion-in-common-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2022-07-05-macroexpansion-in-common-lisp-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;And of course I might just be wrong about some details.&amp;nbsp;&lt;a href="#2022-07-05-macroexpansion-in-common-lisp-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2022-07-05-macroexpansion-in-common-lisp-footnote-3-definition" class="footnote-definition"&gt;
   &lt;p&gt;I am not talking about the environment objects which get passed to macro functions.&amp;nbsp;&lt;a href="#2022-07-05-macroexpansion-in-common-lisp-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2022-07-05-macroexpansion-in-common-lisp-footnote-4-definition" class="footnote-definition"&gt;
   &lt;p&gt;Another way of thinking about &lt;code&gt;((lambda (...) ...) ...)&lt;/code&gt; is that is is the same as &lt;code&gt;(funcall (function (lambda (...) ...)) ...)&lt;/code&gt; and, since &lt;code&gt;function&lt;/code&gt; is a special operator, its rules apply, and include expanding the forms in the body of the &lt;code&gt;(lambda (...) ...)&lt;/code&gt; form (and of course &lt;code&gt;lambda&lt;/code&gt; is itself a macro, so &lt;code&gt;(lambda (...) ...)&lt;/code&gt; expands to &lt;code&gt;(function (lambda (...) ...)))&lt;/code&gt; and then the rules for &lt;code&gt;function&lt;/code&gt; apply again). I am old enough to remember adding the macro for &lt;code&gt;lambda&lt;/code&gt; to various antique CLs.&amp;nbsp;&lt;a href="#2022-07-05-macroexpansion-in-common-lisp-footnote-4-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Avoiding circularity: a simple example</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/03/23/avoiding-circularity-a-simple-example/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-03-23-avoiding-circularity-a-simple-example</id>
  <published>2022-03-23T17:54:40Z</published>
  <updated>2022-03-23T17:54:40Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Here&amp;rsquo;s a simple example of dealing with a naturally circular function definition.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Common Lisp has a predicate called &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_everyc.htm"&gt;&lt;code&gt;some&lt;/code&gt;&lt;/a&gt;. Here is what looks like a natural definition of a slightly more limited version of this predicate, which only works on lists, in Racket:&lt;/p&gt;

&lt;pre class="brush: racket"&gt;&lt;code&gt;(define (some? predicate . lists)
  ;; Just avoid the spread/nospread problem
  (some*? predicate lists))

(define (some*? predicate lists)
  (cond
    [(null? lists)
     ;; if there are no elements the predicate is not true
     #f]
    [(some? null? lists)
     ;; if any of the lists is empty we've failed
     #f]
    [(apply predicate (map first lists))
     ;; The predicate is true on the first elements
     #t]
    [else
     (some*? predicate (map rest lists))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, that looks neat, right? Except it is very obviously doomed because &lt;code&gt;some*?&lt;/code&gt; falls immediately into an infinite recursion.&lt;/p&gt;

&lt;p&gt;Well, the trick to avoid this is to check whether the predicate is &lt;code&gt;null?&lt;/code&gt; and handle that case explicitly:&lt;/p&gt;

&lt;pre class="brush: racket"&gt;&lt;code&gt;(define (some*? predicate lists)
  (cond
    [(null? lists)
     ;; 
     (error 'some? "need at least one list")]
    [(eq? predicate null?)
     ;; Catch the circularity and defang it
     (match lists
       [(list (? list? l))
        (cond
          [(null? l)
           #f]
          [(null? (first l))
           #t]
          [else
           (some? null? (rest l))])]
       [_ (error 'some? "~S bogus for null?" lists)])]
    [(some? null? lists)
     ;; if any of the lists is empty we've failed
     #f]
    [(apply predicate (map first lists))
     ;; The predicate is true on the first elements
     #t]
    [else
     (some*? predicate (map rest lists))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this now works fine.&lt;/p&gt;

&lt;p&gt;Of course this is a rather inefficient version of such a predicate, but it&amp;rsquo;s nice. Well, I think it is.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Note: a previous version of this had an extremely broken version of &lt;code&gt;some*?&lt;/code&gt; which worked, by coincidence, sometimes.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Two understandable deficiencies in Common Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2022/03/22/two-understandable-deficiencies-in-common-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2022-03-22-two-understandable-deficiencies-in-common-lisp</id>
  <published>2022-03-22T09:58:28Z</published>
  <updated>2022-03-22T09:58:28Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Common Lisp is, I think, a remarkably pleasant language, despite what some people like to say. Here are two small deficiencies, both of which are understandable in terms of the history of CL, and both of which ultimately hurt naïve programmers working in CL.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="the-default-floating-point-type-is-single-float"&gt;The default floating-point type is &lt;code&gt;single-float&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;There are two things that make this true:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/v_rd_def.htm"&gt;&lt;code&gt;*read-default-float-format*&lt;/code&gt;&lt;/a&gt; is initially &lt;code&gt;single-float&lt;/code&gt;, which means that, unless it is changed, &lt;code&gt;1.0&lt;/code&gt; reads as &lt;code&gt;1.0f0&lt;/code&gt;, a single float&lt;sup&gt;&lt;a href="#2022-03-22-two-understandable-deficiencies-in-common-lisp-footnote-1-definition" name="2022-03-22-two-understandable-deficiencies-in-common-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;;&lt;/li&gt;
 &lt;li&gt;The &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_float.htm"&gt;&lt;code&gt;float&lt;/code&gt;&lt;/a&gt; function will convert to a single float unless it is given a prototype which is not a single float: &lt;code&gt;(float 1)&lt;/code&gt; is &lt;code&gt;1.0f0&lt;/code&gt;, while to get a double float you would need &lt;code&gt;(float 1 1.0d0)&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;In addition things like &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_w_std_.htm"&gt;&lt;code&gt;with-standard-io-syntax&lt;/code&gt;&lt;/a&gt; bind &lt;code&gt;*read-default-float-format*&lt;/code&gt; to &lt;code&gt;single-float&lt;/code&gt;, so you have to do a little more work to make doubles the default.&lt;/p&gt;

&lt;p&gt;I think there are probably several historical reasons why this default was chosen:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;a long time ago memory was very expensive and single floats take, usually, half the memory of double floats, thus pushing people towards single floats;&lt;/li&gt;
 &lt;li&gt;a long time ago, perhaps, on some machines, single float operations were significantly faster than double float operations even before possible float consing was taken into account;&lt;/li&gt;
 &lt;li&gt;Lisp hardware companies with significant influence on the standard, notably Symbolics, made hardware which allowed single (32 bit) floats to be immediate objects, while double floats were not, and had simple-minded compilers which were not capable of optimizing double float operations, thus making double float arithmetic extremely slow compared to single float arithmetic, and these companies wanted their machines to seem fast (they never, really, were) for naïve users;&lt;/li&gt;
 &lt;li&gt;it was not clear that implementations would choose &lt;code&gt;single-float&lt;/code&gt; to mean &amp;lsquo;single precision IEEE 754 float&amp;rsquo; and &lt;code&gt;double-float&lt;/code&gt; to mean &amp;lsquo;double precision IEEE 754 float&amp;rsquo;, for instance it&amp;rsquo;s perfectly legal to have the &lt;code&gt;short-float&lt;/code&gt; type mean single precision IEEE 754 and all of the &lt;code&gt;single-float&lt;/code&gt;, &lt;code&gt;double-float&lt;/code&gt; and &lt;code&gt;long-float&lt;/code&gt; types mean double precision IEEE 754;&lt;/li&gt;
 &lt;li&gt;it wasn&amp;rsquo;t even even clear that &lt;a href="https://en.wikipedia.org/wiki/IEEE_754-1985"&gt;IEEE 754&lt;/a&gt; would come to dominate how machines implement floating-point: VAXes didn&amp;rsquo;t, and other machines of interest at the time also did not.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;So there are good historical reasons for this. However all implementations I&amp;rsquo;m aware of now translate &lt;code&gt;short-float&lt;/code&gt; to mean &lt;code&gt;single-float&lt;/code&gt;, &lt;code&gt;single-float&lt;/code&gt; to mean IEEE 754 single precision, &lt;code&gt;double-float&lt;/code&gt; to mean IEEE 754 double precision and &lt;code&gt;long-float&lt;/code&gt; to be the same as &lt;code&gt;double-float&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So what is the problem with the default float type being &lt;code&gt;single-float&lt;/code&gt; in the modern world? The answer is&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (log (/ 1 single-float-epsilon) 10)
7.22472&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In other words, single precision IEEE 754 arithmetic has about 7 significant figures of precision. For many purposes, and &lt;em&gt;especially&lt;/em&gt; for naïvely-written code that&amp;rsquo;s at best marginal and at worst less than that. On the other hand&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (log (/ 1 double-float-epsilon) 10)
15.954589770191001D0&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which is almost 16 significant figures of precision, more than twice that of single precision.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s why the default should have been double precision: it makes naïve code more likely to work, and people who are writing non-naïve code can use single precision if they need it.&lt;/p&gt;

&lt;h2 id="the-cl-user-package-is-defined-in-an-implementation-dependent-way"&gt;The &lt;code&gt;CL-USER&lt;/code&gt; package is defined in an implementation-dependent way&lt;/h2&gt;

&lt;p&gt;From &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/11_abb.htm"&gt;the spec&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
 &lt;p&gt;The &lt;code&gt;COMMON-LISP-USER&lt;/code&gt; package is the current package when a Common Lisp system starts up. This package uses the &lt;code&gt;COMMON-LISP&lt;/code&gt; package. The &lt;code&gt;COMMON-LISP-USER&lt;/code&gt; package has the nickname &lt;code&gt;CL-USER&lt;/code&gt;. &lt;em&gt;The &lt;code&gt;COMMON-LISP-USER&lt;/code&gt; package can have additional symbols interned within it; it can use other implementation-defined packages.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;(My emphasis.)&lt;/p&gt;

&lt;p&gt;What this means is that when you start a CL environment, the current package may have all sorts of implementation-dependent symbols visible in it. You can see why this happened: if you&amp;rsquo;re implementing Super-Whizz-Bang CL which has all sorts of magic extra features, you want at least some of those features to be immediately available to users, rather than requiring them to pore over boring manuals to find them.&lt;/p&gt;

&lt;p&gt;But for users, and especially for naïve users, it&amp;rsquo;s a terrible choice: naïve users don&amp;rsquo;t know about packages so they write their programs in &lt;code&gt;CL-USER&lt;/code&gt;. And they also don&amp;rsquo;t really know which symbols available in &lt;code&gt;CL-USER&lt;/code&gt; come from &lt;code&gt;CL&lt;/code&gt; and are thus standard parts of the language, and which come from one of Super-Whizz-Bang CL&amp;rsquo;s implementation packages, and are &lt;em&gt;not&lt;/em&gt; standard parts of the language. So their programs turn into a mess where the portable parts are not distinct from the non-portable parts. The way the &lt;code&gt;CL-USER&lt;/code&gt; package is defined thus makes it harder for to write programs whose non-portable parts are well-isolated, and ultimately hurts the language.&lt;/p&gt;

&lt;p&gt;This is a direct conflict between implementors and users: implementors both want their extra features immediately available so their implementation is shinier and want to encourage users to use these extra features in a way which makes it hard to move their programs to other implementations; users, when they think about it, generally don&amp;rsquo;t want this second thing, at least.&lt;/p&gt;

&lt;p&gt;Instead, the language should have defined &lt;code&gt;CL-USER&lt;/code&gt; as a package which &lt;em&gt;only&lt;/em&gt; used &lt;code&gt;CL&lt;/code&gt;, and perhaps have defined another standard package, perhaps &lt;code&gt;IMPL-USER&lt;/code&gt;, which was defined the way &lt;code&gt;CL-USER&lt;/code&gt; is today.&lt;/p&gt;

&lt;h2 id="can-these-be-fixed"&gt;Can these be fixed?&lt;/h2&gt;

&lt;p&gt;While both of these problems could be fixed without changing the standard, I don&amp;rsquo;t think either can &lt;em&gt;realistically&lt;/em&gt; be fixed.&lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;single-float&lt;/code&gt; problem there is nothing to stop implementations simply defining &lt;code&gt;short-float&lt;/code&gt; to mean IEEE 754 single precision and all the other types to mean IEEE 754 double precision. But all the existing code which assumes otherwise will then probably break in exciting ways. So this is unlikely to happen I expect.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;CL-USER&lt;/code&gt; problem could be fixed if implementations agree to define &lt;code&gt;CL-USER&lt;/code&gt; to use only &lt;code&gt;CL&lt;/code&gt; as it is allowed to do, and perhaps to define an &lt;code&gt;IMPL-USER&lt;/code&gt; package as above. Of course that will make implementations slightly less convenient to use, so the chances of it happening would be small, even if implementors actually talked to each other in any useful way which I suspect they no longer do. Worse than that, this change will break many programs written by naïve users which live in &lt;code&gt;CL-USER&lt;/code&gt;, and there are almost certainly lots of those.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;A moment of convenience, a lifetime of regret, as the old saying goes.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2022-03-22-two-understandable-deficiencies-in-common-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;An earlier version of this article had single floats written as, for instance &lt;code&gt;1.0s0&lt;/code&gt;: that&amp;rsquo;s wrong, those are &lt;em&gt;short&lt;/em&gt; floats, single floats are &lt;code&gt;1.0f0&lt;/code&gt; for instance. These are almost certainly the same type on any current implementation (and I think on any implementation I have ever used, hence the mistake) but they don&amp;rsquo;t have to be. Thanks to Prem Nirved for finding this stupidity.&amp;nbsp;&lt;a href="#2022-03-22-two-understandable-deficiencies-in-common-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">The endless droning: corrections and clarifications</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2021/11/25/the-endless-droning-corrections-and-clarifications/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2021-11-25-the-endless-droning-corrections-and-clarifications</id>
  <published>2021-11-25T13:05:57Z</published>
  <updated>2021-11-25T13:05:57Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;It seems that &lt;a href="https://www.tfeb.org/fragments/2021/11/22/the-endless-droning"&gt;my article&lt;/a&gt; about the existence in the Lisp community of rather noisy people who seem to enjoy complaining rather than fixing things has atracted some interest. Some things in it were unclear, and some other things seem to have been misinterpreted: here are some corrections and clarifications.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;First of all some people pointed out, correctly, that LispWorks is expensive if you live in a low-income country. That&amp;rsquo;s true: I should have been clearer that I believe the phenonenon I am describing is exclusively a rich-world one. I may be incorrect but I have never heard anyone from a non-rich-world country doing this kind of destructuve whining.&lt;/p&gt;

&lt;p&gt;It may also have appeared that I am claiming that &lt;em&gt;all&lt;/em&gt; Lisp people do this: I&amp;rsquo;m not. I think the number of people is very small, and that it has always been small. But they are very noisy and even a small number of noisy people can be very destructive.&lt;/p&gt;

&lt;p&gt;Some people seem to have interpreted what I wrote as saying that the current situation was fine and that Emacs / SLIME / SLY was in fact the best possible answer. Given that my second sentence was&lt;/p&gt;

&lt;blockquote&gt;
 &lt;p&gt;[Better IDEs] would obviously be desirable.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;this is a curious misreading. Just in case I need to make the point any more strongly: I don&amp;rsquo;t think that Emacs is some kind of be-all and end-all: better IDEs would be very good. But I also don&amp;rsquo;t think Emacs is this insurmountable barrier that people pretend it is, and I also very definitely think that some small number of people are claiming it is &lt;em&gt;because they want to lose&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I should point out that this claim that it is not an insurmountable barrier comes from some experience: I have taught people Common Lisp, for money, and I&amp;rsquo;ve done so based on at least three environments:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;LispWorks;&lt;/li&gt;
 &lt;li&gt;Something based around Emacs and a CL running under it;&lt;/li&gt;
 &lt;li&gt;Genera.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;None of those environments presented any significant barrier. I think that LW was probably the most liked but none of them got in the way or put people off.&lt;/p&gt;

&lt;p&gt;In summary: I don&amp;rsquo;t think that the current situation is ideal, and if you read what I wrote as saying that you need to read more carefully. I &lt;em&gt;do&lt;/em&gt; think that the current situation is not going to deter anyone seriously interested and is very far from the largest barrier to becoming good at Lisp. I &lt;em&gt;do&lt;/em&gt; think that, if you want to do something to make the situation better then you should do it, not hang around on reddit complaining about how awful it is, but that there are a small number of noisy people who do exactly that because, for them, &lt;em&gt;no&lt;/em&gt; situation would be ideal because what they want is to &lt;em&gt;avoid&lt;/em&gt; being able to get useful work done. Those people, unsurprisingly, often become extremely upset when you confront them with this awkward truth about themselves. They are also extremely destructive influences on any discussion around Lisp. (Equivalents of these noisy people exist in other areas, of course.) That&amp;rsquo;s one of the reasons I no longer participate in the forums where these people tend to exist.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;(Thanks to an ex-colleague for pointing out that I should perhaps post this.)&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">The endless droning</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2021/11/22/the-endless-droning/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2021-11-22-the-endless-droning</id>
  <published>2021-11-22T12:36:25Z</published>
  <updated>2021-11-22T12:36:25Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Someone &lt;a href="https://www.reddit.com/r/lisp/comments/qz0a3j/why_there_is_no_new_modern_common_lisp_ide/"&gt;asked about better Lisp IDEs on reddit&lt;/a&gt;. Such things would obviously be desirable. But the comments are entirely full the usual sad endless droning from people who need there always to be something preventing them from doing what they pretend to want to do, and are happy to invent such barriers where none really exist. comp.lang.lisp lives on in spirit if not in fact.&lt;/p&gt;

&lt;p&gt;[The rest of this article is a lot ruder than the above and I&amp;rsquo;ve intentionally censored it from the various feeds. See also &lt;a href="https://www.tfeb.org/fragments/2021/11/25/the-endless-droning-corrections-and-clarifications"&gt;corrections and clarifications&lt;/a&gt;.]&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;First of all it is nice to see people dismissing LispWorks because it&amp;rsquo;s &amp;lsquo;too expensive&amp;rsquo;. LW actually &lt;em&gt;has&lt;/em&gt; an IDE and it actually &lt;em&gt;does&lt;/em&gt; provide an editor which (while an Emacs inside) can pretend to be a native mac or windows editor. And it&amp;rsquo;s portable: you can develop on Windows and then build and deploy on Linux and that just works, and has done for at least two decades. But it&amp;rsquo;s &amp;lsquo;too expensive&amp;rsquo;: a new license for LW might cost the equivalent of a few days of employing a programmer, and the support on that license (which gets you upgrades for ever) might be a day or so. If that&amp;rsquo;s &amp;lsquo;too expensive&amp;rsquo; then your costing is so fucked you might as well give up now and become a beggar. (The announcement of the Haskell IDE which triggered the post is for a commercial one, by the way, so let&amp;rsquo;s not have any &amp;lsquo;oh, but it&amp;rsquo;s not ideologically pure&amp;rsquo; noise, thanks.)&lt;/p&gt;

&lt;p&gt;And then we get the endless &amp;lsquo;things were better on &amp;langle;&lt;em&gt;ancient technology of your choice&lt;/em&gt;&amp;rangle;&amp;rsquo;. Here&amp;rsquo;s the thing: I used both Symbolics and Interlisp-D based systems, extensively. They weren&amp;rsquo;t better than the LW IDE. They had one or two neat features that the LW IDE doesn&amp;rsquo;t because it&amp;rsquo;s hard to do on modern hardware, but they were not better. In the case of Interlisp-D systems it took a couple of weeks of practice before you could even use the thing for more than ten minutes without spending most of the time wondering what some front panel code meant (it always meant &amp;lsquo;I have crashed for reasons I cannot explain and you have lost your work and must now reload the sysout and that will take half an hour&amp;rsquo;) and how to restart it. That was &amp;hellip; harder than learning Emacs. Those ancient systems might have been better than Emacs/SLIME &amp;hellip; but they might not, I am not sure. But always, always there is the endless mindless droning from people mourning some distant lost golden age: well, I was &lt;em&gt;there&lt;/em&gt; and that golden age never existed.&lt;/p&gt;

&lt;p&gt;And then there&amp;rsquo;s the &amp;lsquo;but the new programmers find Emacs hard&amp;rsquo;. Seriously? Because people starting to learn Lisp are learning a language whose key idea is that it is a programming language &lt;em&gt;in which you write programming languages&lt;/em&gt;. Lisp makes doing far more possible than other languages, but nothing is ever going to make it easy because designing programming languages turns out to be hard. Lisp is a language all of whose interesting features are intellectually difficult ideas. If you are put off Lisp by having to learn some different keys to press, &lt;em&gt;give up now&lt;/em&gt; and learn Python or some other intellectually undemanding language instead, because Emacs is not remotely the hardest thing you are going to have do deal with. This is like people doing maths degrees complaining about the squiggly Greek characters: if that&amp;rsquo;s putting you off maths, &lt;em&gt;don&amp;rsquo;t do maths&lt;/em&gt;. OK, ζ and ξ are kind of fiddly to write, but understanding what a Banach space is actually &lt;em&gt;is&lt;/em&gt; hard. And, by the way, at some point you &lt;em&gt;are&lt;/em&gt; going to have to learn LaTeX, and if you think Emacs is hard, you have a whole other think coming.&lt;/p&gt;

&lt;p&gt;Oh, and by the way, I&amp;rsquo;ve worked somewhere where large numbers of people from non-programming backgrounds wrote vast masses of Python. How did they do it? They used Emacs: some of them probably used vi or vim. But they were actual scientists so they know what hard things are, and knew that learning Emacs was not one of those things.&lt;/p&gt;

&lt;p&gt;And finally, there&amp;rsquo;s a long diatribe from someone listing all the steps they had to go through to get a CL IDE set up on a machine. This same person claims to have run teams of Lisp programmers. Well, there&amp;rsquo;s this idea called &lt;em&gt;programming&lt;/em&gt;: if you have a long laborious set of tasks to do more than once &lt;em&gt;you write a program to do that for you&lt;/em&gt;. And yes, I have done just that.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;All of these people &lt;em&gt;want to lose&lt;/em&gt;: they need there always to be something in the way that prevents them getting whatever it is they pretend to want to do done. If such a barrier is removed &lt;em&gt;they will build a new one&lt;/em&gt;: I know this because I have done just that and watched them build their new barrier so they could avoid actually doing anything and keep complaining. These barriers &lt;em&gt;do not exist&lt;/em&gt;: if you want a cross-platform IDE for Lisp &lt;a href="http://www.lispworks.com/"&gt;&lt;em&gt;that IDE exists&lt;/em&gt;&lt;/a&gt;. If you don&amp;rsquo;t want to use a commercial product, Emacs and SLIME/SLY are free, and fine. And yes there is a learning curve which is somewhat steep, but &lt;em&gt;intellectually difficult things have steep learning curves&lt;/em&gt;: if you&amp;rsquo;re going to become a productive mathematician you are going to go through four years of very steep learning curve indeed, and if you&amp;rsquo;re going to become a productive Lisp programmer you&amp;rsquo;re going to go through a learning curve perhaps a tenth or less as hard as that, of which Emacs is one tiny part. If you&amp;rsquo;re not up to that, &lt;em&gt;don&amp;rsquo;t write Lisp&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And if what you enjoy doing is whining in public about how things are always in your way then &lt;em&gt;fuck off&lt;/em&gt;.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">The proper use of macros in Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2021/11/11/the-proper-use-of-macros-in-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2021-11-11-the-proper-use-of-macros-in-lisp</id>
  <published>2021-11-11T14:32:11Z</published>
  <updated>2021-11-11T14:32:11Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;People learning Lisp often try to learn how to write macros by taking an existing function they have written and turning it into a macro. This is a mistake: macros and functions serve different purposes and it is almost never useful to turn functions into macros, or macros into functions.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Let&amp;rsquo;s say you are learning Common Lisp&lt;sup&gt;&lt;a href="#2021-11-11-the-proper-use-of-macros-in-lisp-footnote-1-definition" name="2021-11-11-the-proper-use-of-macros-in-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;, and you have written a fairly obvious factorial function based on the natural mathematical definition: if \(n \in \mathbb{N}\), then&lt;/p&gt;

&lt;p&gt;\[
n! = 
\begin{cases}
 1 &amp;amp;n \le 1\\
 n \times (n - 1)! &amp;amp;n &amp;gt; 1
\end{cases}
\]&lt;/p&gt;

&lt;p&gt;So this gives you a fairly obvious recursive definition of &lt;code&gt;factorial&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun factorial (n)
  (if (&amp;lt;= n 1)
      1
    (* n (factorial (1- n )))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And so, you think you want to learn about macros so can you write &lt;code&gt;factorial&lt;/code&gt; as a macro? And you might end up with something like this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro factorial (n)
  `(if (&amp;lt;= ,n 1)
      1
    (* ,n (factorial ,(1- n )))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this superficially seems as if it works:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (factorial 10)
3628800&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But it doesn&amp;rsquo;t, in fact, work:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (let ((x 3))
    (factorial x))

Error: In 1- of (x) arguments should be of type number.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Why doesn&amp;rsquo;t this work and can it be fixed so it does? If it can&amp;rsquo;t what has gone wrong and how are macros meant to work and what are they useful for?&lt;/p&gt;

&lt;p&gt;It can&amp;rsquo;t be fixed so that it works. trying to rewrite functions as macros is a bad idea, and if you want to learn what is interesting about macros you should not start there.&lt;/p&gt;

&lt;p&gt;To understand why this is true you need to understand what macros actually &lt;em&gt;are&lt;/em&gt; in Lisp.&lt;/p&gt;

&lt;h2 id="what-macros-are-a-first-look"&gt;What macros are: a first look&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A macro is a function whose domain and range is &lt;em&gt;syntax&lt;/em&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Macros &lt;em&gt;are&lt;/em&gt; functions (quite explicitly so in CL: you can get at the function of a macro with &lt;code&gt;macro-function&lt;/code&gt;, and this is something you can happily call the way you would call any other function), but they are functions whose domain and range is &lt;em&gt;syntax&lt;/em&gt;. A macro is a function whose argument is a language whose syntax includes the macro and whose value, when called on an instance of that language, is a language whose syntax &lt;em&gt;doesn&amp;rsquo;t&lt;/em&gt; include the macro. It may work recursively: its value may be a language which includes the same macro but in some simpler way, such that the process will terminate at some point.&lt;/p&gt;

&lt;p&gt;So the job of macros is to provide a family of extended languages built on some core Lisp which has no remaining macros, only functions and function application, special operators &amp;amp; special forms involving them and literals. One of those languages is the language we call Common Lisp, but the macros written by people serve to extend this language into a multitude of variants.&lt;/p&gt;

&lt;p&gt;As an example of this I often write in a language which is like CL, but is extended by the presence of a number of extra constructs, one of which is called ITERATE (but it predates the well-known one and is not at all the same):&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(iterate next ((x 1))
 (if (&amp;lt; x 10)
     (next (1+ x))
   x)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;is equivalent to&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(labels ((next (x)
          (if (&amp;lt; x 10)
              (next (1+ x))
            x)))
 (next 1))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once upon a time when I first wrote &lt;code&gt;iterate&lt;/code&gt;, it used to manually optimize the recursive calls to jumps in some cases, because the Symbolics I wrote it on didn&amp;rsquo;t have tail-call elimination. That&amp;rsquo;s a non-problem in LispWorks&lt;sup&gt;&lt;a href="#2021-11-11-the-proper-use-of-macros-in-lisp-footnote-2-definition" name="2021-11-11-the-proper-use-of-macros-in-lisp-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;. Anyone familiar with Scheme will recognise &lt;code&gt;iterate&lt;/code&gt; as named &lt;code&gt;let&lt;/code&gt;, which is where it came from (once, I think, it was known as &lt;code&gt;nlet&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;iterate&lt;/code&gt; is implemented by a function which maps from the language which includes it to a language which doesn&amp;rsquo;t include it, by mapping the syntax as above.&lt;/p&gt;

&lt;p&gt;So compare this with a factorial function: factorial is a function whose domain is natural numbers and whose range is also natural numbers, and it has an obvious recursive definition. Well, natural numbers are part of the syntax of Lisp, but they&amp;rsquo;re a tiny part of it. So implementing factorial as a macro is, really, a hopeless task. What should&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(factorial (+ x y (f z)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Actually do when considered as a mapping between languages? Assuming you are using the recursive definition of the factorial function then the answer is it can&amp;rsquo;t map to anything useful at all: a function which implements that recursive definition simply has to be called at run time. The very best you could do would seem to be this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun fact (n)
 (if (&amp;lt; n 3)
     n
   (* n (fact (1- n)))))

(defmacro factorial (expression)
 `(fact ,expression))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that&amp;rsquo;s not a useful macro (but see below).&lt;/p&gt;

&lt;p&gt;So the answer is, again, that macros are functions which map between &lt;em&gt;languages&lt;/em&gt; and they are useful where you want a new &lt;em&gt;language&lt;/em&gt;: not just the same language with extra functions in it, but a language with new control constructs or something like that. If you are writing functions whose range is something which is not the syntax of a language built on Common Lisp, &lt;em&gt;don&amp;rsquo;t write macros&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id="what-macros-are-a-second-look"&gt;What macros are: a second look&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Macroexpansion is compilation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A function whose domain is one language and whose range is another is a &lt;em&gt;compiler&lt;/em&gt; for the language of the domain, especially when that language is somehow richer than the language of the range, which is the case for macros.&lt;/p&gt;

&lt;p&gt;But it&amp;rsquo;s a simplification to say that &lt;em&gt;macros&lt;/em&gt; are this function: they&amp;rsquo;re not, they&amp;rsquo;re only part of it. The actual function which maps between the two languages is made up of macros &lt;em&gt;and the macroexpander provided by CL itself&lt;/em&gt;. The macroexpander is what arranges for the functions defined by macros to be called in the right places, and also it is the thing which arranges for various recursive macros to actually make up a recurscive function. So it&amp;rsquo;s important to understand that the macroexpander is a critical part of the process: macros on their own only provide part of it.&lt;/p&gt;

&lt;h2 id="an-example-two-versions-of-a-recursive-macro"&gt;An example: two versions of a recursive macro&lt;/h2&gt;

&lt;p&gt;People often say that you should not write recursive macros, but this prohibition on recursive macros is pretty specious: they&amp;rsquo;re just fine. Consider a language which only has &lt;code&gt;lambda&lt;/code&gt; and doesn&amp;rsquo;t have &lt;code&gt;let&lt;/code&gt;. Well, we can write a simple version of &lt;code&gt;let&lt;/code&gt;, which I&amp;rsquo;ll call &lt;code&gt;bind&lt;/code&gt; as a macro: a function which takes this new language and turns it into the more basic one. Here&amp;rsquo;s that macro:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro bind ((&amp;amp;rest bindings) &amp;amp;body forms)
 `((lambda ,(mapcar #'first bindings) ,@forms)
   ,@(mapcar #'second bindings)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (bind ((x 1) (y 2))
    (+ x y))              
(bind ((x 1) (y 2)) (+ x y))
 -&amp;gt; ((lambda (x y) (+ x y)) 1 2)
3&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(These example expansions come via use of my &lt;a href="https://tfeb.github.io/tfeb-lisp-hax/#tracing-macroexpansion-trace-macroexpand"&gt;trace-macroexpand package&lt;/a&gt;, available in a good Lisp near you: see appendix for configuration).&lt;/p&gt;

&lt;p&gt;So now we have a language with a binding form which is more convenient than &lt;code&gt;lambda&lt;/code&gt;. But maybe we want to be able to bind sequentially? Well, we can write a &lt;code&gt;let*&lt;/code&gt; version, called &lt;code&gt;bind*&lt;/code&gt;, which looks like this&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro bind* ((&amp;amp;rest bindings) &amp;amp;body forms)
 (if (null (rest bindings))
     `(bind ,bindings ,@forms)
   `(bind (,(first bindings))
      (bind* ,(rest bindings) ,@forms))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And you can see how this works: it checks if there&amp;rsquo;s just one binding in which case it&amp;rsquo;s just &lt;code&gt;bind&lt;/code&gt;, and if there&amp;rsquo;s more than one it peels off the first and then expands into a &lt;code&gt;bind*&lt;/code&gt; form for the rest. And you can see this working (here both &lt;code&gt;bind&lt;/code&gt; and &lt;code&gt;bind*&lt;/code&gt; are being traced):&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;&amp;gt; (bind* ((x 1) (y (+ x 2)))
    (+ x y))
(bind* ((x 1) (y (+ x 2))) (+ x y))
 -&amp;gt; (bind ((x 1)) (bind* ((y (+ x 2))) (+ x y)))
(bind ((x 1)) (bind* ((y (+ x 2))) (+ x y)))
 -&amp;gt; ((lambda (x) (bind* ((y (+ x 2))) (+ x y))) 1)
(bind* ((y (+ x 2))) (+ x y))
 -&amp;gt; (bind ((y (+ x 2))) (+ x y))
(bind ((y (+ x 2))) (+ x y))
 -&amp;gt; ((lambda (y) (+ x y)) (+ x 2))
(bind* ((y (+ x 2))) (+ x y))
 -&amp;gt; (bind ((y (+ x 2))) (+ x y))
(bind ((y (+ x 2))) (+ x y))
 -&amp;gt; ((lambda (y) (+ x y)) (+ x 2))
4&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see that, in this implementation, which is LW again, some of the forms are expanded more than once: that&amp;rsquo;s not uncommon in interpreted code: since macros should generally be functions (so, not have side-effects) it does not matter that they may be expanded multiple times. Compilation will expand macros and then compile the result, so all the overhead of macroexpansion happend ahead of run-time:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt; (defun foo (x)
   (bind* ((y (1+ x)) (z (1+ y)))
     (+ y z)))
foo

&amp;gt; (compile *)
(bind* ((y (1+ x)) (z (1+ y))) (+ y z))
 -&amp;gt; (bind ((y (1+ x))) (bind* ((z (1+ y))) (+ y z)))
(bind ((y (1+ x))) (bind* ((z (1+ y))) (+ y z)))
 -&amp;gt; ((lambda (y) (bind* ((z (1+ y))) (+ y z))) (1+ x))
(bind* ((z (1+ y))) (+ y z))
 -&amp;gt; (bind ((z (1+ y))) (+ y z))
(bind ((z (1+ y))) (+ y z))
 -&amp;gt; ((lambda (z) (+ y z)) (1+ y))
foo
nil
nil

&amp;gt; (foo 3)
9&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There&amp;rsquo;s nothing wrong with macros like this, which expand into simpler versions of themselves. You just have to make sure that the recursive expansion process is producing successively simpler bits of syntax and has a well-defined termination condition.&lt;/p&gt;

&lt;p&gt;Macros like this are often called &amp;lsquo;recursive&amp;rsquo; but they&amp;rsquo;re actually not: the function associated with &lt;code&gt;bind*&lt;/code&gt; does not call itself. What &lt;em&gt;is&lt;/em&gt; recursive is the function implicitly defined by the combination of the macro function and the macroexpander: the &lt;code&gt;bind*&lt;/code&gt; function simply expands into a bit of syntax which it knows will cause the macroexpander to call it again.&lt;/p&gt;

&lt;p&gt;It is possible to write &lt;code&gt;bind*&lt;/code&gt; such that the macro function &lt;em&gt;itself&lt;/em&gt; is recursive:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro bind* ((&amp;amp;rest bindings) &amp;amp;body forms)
  (labels ((expand-bind (btail)
             (if (null (rest btail))
                 `(bind ,btail
                    ,@forms)
               `(bind (,(first btail))
                  ,(expand-bind (rest btail))))))
    (expand-bind bindings)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now compiling &lt;code&gt;foo&lt;/code&gt; again results in this output from tracing macroexpansion:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(bind* ((y (1+ x)) (z (1+ y))) (+ y z))
 -&amp;gt; (bind ((y (1+ x))) (bind ((z (1+ y))) (+ y z)))
(bind ((y (1+ x))) (bind ((z (1+ y))) (+ y z)))
 -&amp;gt; ((lambda (y) (bind ((z (1+ y))) (+ y z))) (1+ x))
(bind ((z (1+ y))) (+ y z))
 -&amp;gt; ((lambda (z) (+ y z)) (1+ y))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see that now all the recursion happens within the macro function for &lt;code&gt;bind*&lt;/code&gt; itself: the macroexpander calls &lt;code&gt;bind*&lt;/code&gt;&amp;rsquo;s macro function just once.&lt;/p&gt;

&lt;p&gt;While it&amp;rsquo;s possible to write macros like this second version of &lt;code&gt;bind*&lt;/code&gt;, it is normally easier to write the first version and to allow the combination of the macroexpander and the macro function to implement the recursive expansion.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id="two-historical-uses-for-macros"&gt;Two historical uses for macros&lt;/h2&gt;

&lt;p&gt;There are two uses for macros &amp;mdash; both now historical &amp;mdash; where they &lt;em&gt;were&lt;/em&gt; used where functions would be more natural.&lt;/p&gt;

&lt;p&gt;The first of these is &lt;em&gt;function inlining&lt;/em&gt;, where you want to avoid the overhead of calling a small function many times. This overhead was a lot on computers made of cardboard, as all computers were, and also if the stack got too deep the cardboard would tear and this was bad. It makes no real sense to inline a recursive function such as the above &lt;code&gt;factorial&lt;/code&gt;: how would the inlining process terminate? But you could rewrite a factorial function to be explicitly iterative:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun factorial (n)
 (do* ((k 1 (1+ k))
       (f k (* f k)))
      ((&amp;gt;= k n) f)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now, if you have very many calls to &lt;code&gt;factorial&lt;/code&gt;, you wanted to optimise the function call overhead away, &lt;em&gt;and it was 1975&lt;/em&gt;, you might write this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro factorial (n)
 `(let ((nv ,n))
    (do* ((k 1 (1+ k))
          (f k (* f k)))
         ((&amp;gt;= k nv) f))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this has the effect of replacing &lt;code&gt;(factorial n)&lt;/code&gt; by an expression which will compute the factorial of &lt;code&gt;n&lt;/code&gt;. The cost of that is that &lt;code&gt;(funcall #'factorial n)&lt;/code&gt; is not going to work, and &lt;code&gt;(funcall (macro-function 'factorial) ...)&lt;/code&gt; is never what you want.&lt;/p&gt;

&lt;p&gt;Well, that&amp;rsquo;s what you did in 1975, because Lisp compilers were made out of the things people found down the sides of sofas. Now it&amp;rsquo;s no longer 1975 and you just tell the compiler that you want it to inline the function, please:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(declaim (inline factorial))
(defun factorial (n) ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and it will do that for you. So this use of macros is now purely historicl.&lt;/p&gt;

&lt;p&gt;The second reason for macros where you really want functions is computing things at compile time. Let&amp;rsquo;s say you have lots of expressions like &lt;code&gt;(factorial 32)&lt;/code&gt; in your code. Well, you could do this:&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defmacro factorial (expression)
 (typecase expression
   ((integer 0)
    (factorial/fn expression))
   (number
    (error "factorial of non-natural literal ~S" expression))
   (t
    `(factorial/fn ,expression))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So the &lt;code&gt;factorial&lt;/code&gt; macro checks to see if its argument is a literal natural number and will compute the factorial of it at macroexpansion time (so, at compile time or just before compile time). So a function like&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun foo ()
 (factorial 32))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will now compile to simply return &lt;code&gt;263130836933693530167218012160000000&lt;/code&gt;. And, even better, there&amp;rsquo;s some compile-time error checking: code which is, say, &lt;code&gt;(factorial 12.3)&lt;/code&gt; will cause a compile-time error.&lt;/p&gt;

&lt;p&gt;Well, again, this is what you would do if it was 1975. It&amp;rsquo;s not 1975 any more, and CL has a special tool for dealing with just this problem: compiler macros.&lt;/p&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(defun factorial (n)
 (do* ((k 1 (1+ k))
       (f k (* f k)))
      ((&amp;gt;= k n) f)))

(define-compiler-macro factorial (&amp;amp;whole form n)
 (typecase n
   ((integer 0)
    (factorial n))
   (number
    (error "literal number is not a natural: ~S" n))
   (t form)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now &lt;code&gt;factorial&lt;/code&gt; is a function and works the way you expect &amp;mdash; &lt;code&gt;(funcall #'factoial ...)&lt;/code&gt; will work fine. But the compiler knows that if it comes across &lt;code&gt;(factorial ...)&lt;/code&gt; then it should give the compiler macro for &lt;code&gt;factorial&lt;/code&gt; a chance to say what this expression should actually be. And the compiler macro does an explicit check for the argument being a literal natural number, and if it is computes the factorial at compile time, and the same check for a literal number which is not a natural, and finally just says &amp;rsquo;I don&amp;rsquo;t know, call the function&amp;rsquo;. Note that the compiler macro itself calls &lt;code&gt;factorial&lt;/code&gt;, but since the argument isn&amp;rsquo;t a literal there&amp;rsquo;s no recursive doom.&lt;/p&gt;

&lt;p&gt;So this takes care of the other antique use of macros where you would expect functions. And of course you can combine this with inlining and it will all work fine: you can write functions which will handle special cases via compiler macros and will otherwise be inlined.&lt;/p&gt;

&lt;p&gt;That leaves macros serving the purpose they are actually useful for: building languages.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id="appendix-setting-up-trace-macroexpand"&gt;Appendix: setting up &lt;code&gt;trace-macroexpand&lt;/code&gt;&lt;/h2&gt;

&lt;pre class="brush: lisp"&gt;&lt;code&gt;(use-package :org.tfeb.hax.trace-macroexpand)

;;; Don't restrict print length or level when tracing
(setf *trace-macroexpand-print-level* nil
      *trace-macroexpand-print-length* nil)

;;; Enable tracing
(trace-macroexpand)

;;; Trace the macros you want to look at ...
(trace-macro ...)

;;; ... and ntrace them
(untrace-macro ...)&lt;/code&gt;&lt;/pre&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2021-11-11-the-proper-use-of-macros-in-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;All the examples in this article are in Common Lisp except where otherwise specified. Other Lisps have similar considerations, although macros in Scheme are not explicitly functions in the way they are in CL.&amp;nbsp;&lt;a href="#2021-11-11-the-proper-use-of-macros-in-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2021-11-11-the-proper-use-of-macros-in-lisp-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;This article originated as a message on the &lt;code&gt;lisp-hug&lt;/code&gt; mailing list for &lt;a href="http://www.lispworks.com/"&gt;LispWorks&lt;/a&gt; users. References to &amp;lsquo;LW&amp;rsquo; mean LispWorks, although everything here should apply to any modern CL. (In terms of tail call elimination I would define a CL which does not eliminate tail self-calls in almost all cases under reasonable optimization settings as pre-modern: I don&amp;rsquo;t use such implementations.)&amp;nbsp;&lt;a href="#2021-11-11-the-proper-use-of-macros-in-lisp-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">The best Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2021/11/03/the-best-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2021-11-03-the-best-lisp</id>
  <published>2021-11-03T12:03:44Z</published>
  <updated>2021-11-03T12:03:44Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;People sometimes ask &lt;a href="https://www.reddit.com/r/lisp/comments/qlcza4/best_lisp_dialect/"&gt;which is the best Lisp dialect&lt;/a&gt;? That&amp;rsquo;s a category error, and here&amp;rsquo;s why.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;Programming in Lisp &amp;mdash; any Lisp &amp;mdash; is about &lt;em&gt;building languages&lt;/em&gt;: in Lisp the way you solve a problem is by building a language &amp;mdash; a jargon, or a dialect if you like &amp;mdash; to talk about the problem and then solving the problem in that language. Lisps are, quite explicitly, language-building languages.&lt;/p&gt;

&lt;p&gt;This is, in fact, how people solve large problems in &lt;em&gt;all&lt;/em&gt; programming languages: &lt;a href="https://en.wikipedia.org/wiki/Greenspun's_tenth_rule" title="Greenspun's tenth rule"&gt;Greenspun&amp;rsquo;s tenth rule&lt;/a&gt; isn&amp;rsquo;t really a statement about Common Lisp, it&amp;rsquo;s a statement that all sufficiently large software systems end up having some hacked-together, informally-specified, half-working &lt;em&gt;language&lt;/em&gt; in which the problem is actually solved. Often people won&amp;rsquo;t understand that the thing they&amp;rsquo;ve built is in fact a language, but that&amp;rsquo;s what it is. Everyone who has worked on large-scale software will have come across these things: often they are very horrible, and involve much use of language-in-a-string&lt;sup&gt;&lt;a href="#2021-11-03-the-best-lisp-footnote-1-definition" name="2021-11-03-the-best-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;The Lisp difference is two things: when you start solving a problem in Lisp, you &lt;em&gt;know&lt;/em&gt;, quite explicitly, that this is what you are going to do; and the language has wonderful tools which let you incrementally build a series of lightweight languages, ending up with one or more languages in which to solve the problem.&lt;/p&gt;

&lt;p&gt;So, after that preface, why is this question the wrong one to ask? Well, if you are going to program in Lisp you are going to be building languages, and you want those languages not to be awful. Lisp makes it it far easier to build languages which are not awful, but it doesn&amp;rsquo;t prevent you doing so if you want to. And again, anyone who has dealt with enough languages built on Lisps will have come across some which are, in fact, awful.&lt;/p&gt;

&lt;p&gt;If you are going to build languages then you need to understand how languages work &amp;mdash; what makes a language habitable to its human users (the computer does not care with very few exceptions). That means you will need to be a &lt;em&gt;linguist&lt;/em&gt;. So the question then is: how do you become a linguist? Well, we know the answer to that, because there are lots of linguists and lots of courses on linguistics. You might say that, well, those people study &lt;em&gt;natural&lt;/em&gt; languages, but that&amp;rsquo;s irrelevant: natural languages have been under evolutionary pressure for a very long time and they&amp;rsquo;re really &lt;em&gt;good&lt;/em&gt; for what they&amp;rsquo;re designed for (which is not the same as what programming languages are designed for, but the users &amp;mdash; humans &amp;mdash; are the same).&lt;/p&gt;

&lt;p&gt;So, do you become a linguist by learning French? Or German? Or Latin? Or Cuzco Quechua? No, you don&amp;rsquo;t. You become a linguist by learning enough about enough languages that you can understand how languages work. A linguist isn&amp;rsquo;t someone who speaks French really well: they&amp;rsquo;re someone who understands that French is a Romance language, that German isn&amp;rsquo;t but has many Romance loan words, that English is closer to German than it is French but got a vast injection of Norman French, which in turn wasn&amp;rsquo;t that close to modern French, that Swiss German has cross-serial dependencies but Hochdeutsch does not and what that means, and so on. A linguist is someone who understands things about the &lt;em&gt;structure&lt;/em&gt; of languages: what do you see, what do you never see, how do different languages do equivalent things? And so on.&lt;/p&gt;

&lt;p&gt;The way you become a linguist is not by picking a language and learning it: it&amp;rsquo;s by looking at lots of languages enough to understand how they work.&lt;/p&gt;

&lt;p&gt;If you want to learn to program in Lisp, you will need to become a linguist. The very best way to ensure you fail at that is to pick a &amp;lsquo;best&amp;rsquo; Lisp and learn that. There is no best Lisp, and in order to program well in &lt;em&gt;any&lt;/em&gt; Lisp you must be exposed to as many Lisps and as many other languages as possible.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;If you think there&amp;rsquo;s a distinction between a &amp;lsquo;dialect&amp;rsquo;, a &amp;lsquo;jargon&amp;rsquo; and a &amp;lsquo;language&amp;rsquo; then I have news for you: there is. A language is a dialect with a standards committee. (This is stolen from a quote due to Max Weinrich that all linguists know:&lt;/p&gt;

&lt;blockquote&gt;
 &lt;p&gt;אַ שפּראַך איז אַ דיאַלעקט מיט אַן אַרמיי און פֿלאָט&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;a shprakh iz a dyalekt mit an armey un flot.)&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2021-11-03-the-best-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;&amp;lsquo;Language-in-a-string&amp;rsquo; is where a programming language has another programming language embedded in strings in the outer language. Sometimes programs in that inner programming language will be made up by string concatenation in the outer language. Sometimes that inner language will, in turn, have languages embedded in its strings. It&amp;rsquo;s a terrible, terrible thing.&amp;nbsp;&lt;a href="#2021-11-03-the-best-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Generic interfaces in Racket</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2021/01/08/generic-interfaces-in-racket/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2021-01-08-generic-interfaces-in-racket</id>
  <published>2021-01-08T18:25:59Z</published>
  <updated>2021-01-08T18:25:59Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Or: things you do to distract yourself from watching an attempted fascist coup.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;A thing that exists in many languages with a notion of a sequence of objects is a function variously known as &lt;code&gt;fold&lt;/code&gt; or &lt;code&gt;reduce&lt;/code&gt;: this takes another function of two arguments, some initial value, and walks along the sequence successively reducing it using the function. So, for instance:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;&lt;code&gt;(fold + 0 '(1 2 3))&lt;/code&gt; turns into &lt;code&gt;(fold + (+ 0 1) '(2 3))&lt;/code&gt; which turns into &amp;hellip;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;(fold + 1 '(2 3))&lt;/code&gt; turns into &lt;code&gt;(fold + (+ 1 2) '(3))&lt;/code&gt; which turns into &amp;hellip;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;(fold + 3 '(3))&lt;/code&gt; turns into &lt;code&gt;(fold + (+ 3 3) '())&lt;/code&gt; which turns into &amp;hellip;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;6&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;It&amp;rsquo;s pretty easy to write a version of &lt;code&gt;fold&lt;/code&gt; for lists:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (fold op initial l)
  (if (null? l)
      initial
      (fold op (op initial (first l)) (rest l))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Racket calls this (or a more careful version of this) &lt;code&gt;foldl&lt;/code&gt;: there is also &lt;code&gt;foldr&lt;/code&gt; which works from the other end of the list and is more expensive as a result.&lt;/p&gt;

&lt;p&gt;Well, one thing you might want to do is have a version of &lt;code&gt;fold&lt;/code&gt; which works on &lt;em&gt;trees&lt;/em&gt; rather than just lists. One definition of a tree is:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;it&amp;rsquo;s a collection of nodes;&lt;/li&gt;
 &lt;li&gt;nodes have values;&lt;/li&gt;
 &lt;li&gt;nodes have zero or more unique children, which are nodes.&lt;/li&gt;
 &lt;li&gt;no node is the descendant of more than one node;&lt;/li&gt;
 &lt;li&gt;there is exactly one root node which is the descendant of no other nodes.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;A variant of this (which will matter below) is that the children of a node are either nodes or any other object, and there is some way of knowing if something is a node or not&lt;sup&gt;&lt;a href="#2021-01-08-generic-interfaces-in-racket-footnote-1-definition" name="2021-01-08-generic-interfaces-in-racket-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;You can obviously represent trees as conses, with the value of a cons being its car, and the children being its cdr. Whatever builds the tree needs to make sure that (3), (4) and (5) are true, or you get a more general graph structure.&lt;/p&gt;

&lt;p&gt;But you might want to have other sorts of trees, and you&amp;rsquo;d want the fold function not to care about what sort of tree it was processing: just that it was processing a tree. Indeed, it would be nice if it was possible to provide special implementations for, for instance, binary trees where rather than iterating over some sequence of children you&amp;rsquo;d know there were exactly two.&lt;/p&gt;

&lt;p&gt;So, I wondered if there was a nice way of expressing this in Racket and it turns out there mostly is. Racket has a notion of &lt;a href="https://docs.racket-lang.org/reference/struct-generics.html"&gt;generic interfaces&lt;/a&gt; which are really intended as a way for different &lt;a href="https://docs.racket-lang.org/reference/structures.html"&gt;structure types&lt;/a&gt; to provide common interfaces, I think. But it turns out they can be (ab?)used to do this, as well.&lt;/p&gt;

&lt;p&gt;Generic interfaces are not provided by &lt;code&gt;racket&lt;/code&gt; but by &lt;code&gt;racket/generic&lt;/code&gt;: everything below assumed &lt;code&gt;(require racket/generic)&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="a-generic-treelike-interface"&gt;A generic &lt;code&gt;treelike&lt;/code&gt; interface&lt;/h2&gt;

&lt;p&gt;A treelike object supports two operations:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;node-value&lt;/code&gt; returns the value of a node;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;node-children&lt;/code&gt; returns a list of the node&amp;rsquo;s children.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The second of these is a bit nasty: it would be better perhaps to either provide an interface for mapping over a node&amp;rsquo;s children, or to return some general, possibly lazy, sequence of children. But this is just playing, so I don&amp;rsquo;t mind.&lt;/p&gt;

&lt;p&gt;Here is a definition of a generic &lt;code&gt;treelike&lt;/code&gt; interface, which includes default methods for lists:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-generics treelike
  ;; treelike objects have values and children
  (node-value treelike)
  (node-children treelike)
  #:fast-defaults
  (((λ (t)
      (and (cons? t) (list? t)))
    ;; non-null proper lists are trees: their value is their car;
    ;; their children are their cdr.
    (define node-value car)
    (define node-children cdr))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;This uses &lt;code&gt;#:fast-defaults&lt;/code&gt; instead of &lt;code&gt;#:defaults&lt;/code&gt;, which means that the dispatch to objects which satisfy &lt;code&gt;list?&lt;/code&gt; happens. This is fine in this case: lists are never going to be confused with any other tree type.&lt;/li&gt;
 &lt;li&gt;This relies on Racket&amp;rsquo;s (and Scheme&amp;rsquo;s?) &lt;code&gt;list?&lt;/code&gt; predicate returning true only for proper lists rather than CL&amp;rsquo;s cheap &lt;code&gt;listp&lt;/code&gt; which just returns true for anything which is either &lt;code&gt;nil&lt;/code&gt; or a cons.&lt;/li&gt;
 &lt;li&gt;There are lots of other options to &lt;code&gt;define-generics&lt;/code&gt; which I&amp;rsquo;m not using and many of which I don&amp;rsquo;t understand.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;With this definition:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (treelike? '())
#f
&amp;gt; (treelike? '(1 2 3))
#t
&amp;gt; (treelike? '(1 2 . 3))
#f
&amp;gt; (node-children '(1 2 3))
'(2 3)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, OK.&lt;/p&gt;

&lt;h2 id="a-treelike-binary-tree"&gt;A &lt;code&gt;treelike&lt;/code&gt; binary tree&lt;/h2&gt;

&lt;p&gt;We could then define a &lt;code&gt;binary-tree&lt;/code&gt; type which implements this generic interface:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(struct binary-tree (value left right)
  #:transparent
  #:methods gen:treelike
  ((define (node-value bt)
     (binary-tree-value bt))
   (define (node-children bt)
     (list (binary-tree-left bt)
           (binary-tree-right bt)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;#:methods gen:treelike&lt;/code&gt; tells the structure we&amp;rsquo;re defining the methods needed for this thing to be a &lt;code&gt;treelike&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;And now we can check things:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (treelike? (binary-tree 1 2 3))
#t
&amp;gt; (node-value (binary-tree 1 2 3))
1
&amp;gt; (node-children (binary-tree 1 2 3))
'(2 3)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;OK.&lt;/p&gt;

&lt;h2 id="two-attempts-at-a-generic-foldable-interface"&gt;Two attempts at a generic &lt;code&gt;foldable&lt;/code&gt; interface&lt;/h2&gt;

&lt;p&gt;So now I want to define another interface for things which can be folded. And the first thing I tried is this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-generics foldable
  ;; broken
  (fold operation initial foldable)
  #:defaults
  ((treelike?
    (define (fold op initial treelike)
      (let ([current (op initial (node-value treelike))]
            [children (node-children treelike)])
        (if (null? children)
            current
            (fold op (fold op current (first children))
                  (rest children))))))
   ((const true)
    (define (fold op initial any)
      (op initial any)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So this tries to define a &lt;code&gt;fold&lt;/code&gt; generic function, which has two implementations: one for &lt;code&gt;treelike&lt;/code&gt; objects and one for &lt;em&gt;all other objects&lt;/em&gt;. So this means that &lt;em&gt;all&lt;/em&gt; objects are foldable, and, for instance &lt;code&gt;(fold + 0 1)&lt;/code&gt; simply turns into &lt;code&gt;(+ 0 1)&lt;/code&gt;. This is a bit odd but it simplifies the implementation of the interface for &lt;code&gt;treelike&lt;/code&gt; objects on the assumption that the children of nodes may not themselves be nodes (see above).&lt;/p&gt;

&lt;p&gt;There is another complexity: if the list of a &lt;code&gt;treelike&lt;/code&gt; node&amp;rsquo;s children isn&amp;rsquo;t null, then it&amp;rsquo;s a &lt;code&gt;treelike&lt;/code&gt;, so it can safely be recursed over rather than explicitly iterated over. This is a slightly questionable pun I think, but, well, I am a slightly questionable programmer.&lt;/p&gt;

&lt;p&gt;And this &amp;hellip; doesn&amp;rsquo;t work:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (fold + 0 '(1 2 3))
; node-value: contract violation:
; expected: treelike?
; given: 2
; argument position: 1st&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It took me a long time to understand this, and the answer is that the definitions of &lt;code&gt;fold&lt;/code&gt; inside the &lt;code&gt;define-generic&lt;/code&gt; form &lt;em&gt;aren&amp;rsquo;t adding methods to a generic function&lt;/em&gt;: what they are doing is defining a little local function, &lt;code&gt;fold&lt;/code&gt; which &lt;em&gt;then&lt;/em&gt; gets glued into the generic function. So references to &lt;code&gt;fold&lt;/code&gt; in the definition refer to the little local function. It is exactly as if you had done this, in fact:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-generics foldable
  ;; this is why it's broken
  (fold operation initial foldable)
  #:defaults
  ((treelike?
    (define fold
      (letrec ([fold (λ (op initial treelike)
                       (let ([current (op initial (node-value treelike))]
                             [children (node-children treelike)])
                         (if (null? children)
                             current
                             (fold op (fold op current (first children))
                                   (rest children)))))])
        fold)))
   ((const true)
    (define (fold op initial any)
      (op initial any)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And you can see why this can&amp;rsquo;t work: the &lt;code&gt;fold&lt;/code&gt; bound by the &lt;code&gt;letrec&lt;/code&gt; calls itself rather than going through the generic dispatch.&lt;/p&gt;

&lt;p&gt;The way to fix this is to use the magic &lt;code&gt;define/generic&lt;/code&gt; form to get a copy of the generic function, and then call &lt;em&gt;that&lt;/em&gt;. This is syntactically horrid, but you can see why it is needed given the above. So a working version of this interface purports to be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-generics foldable
  ;; not broken
  (fold operation initial foldable)
  #:defaults
  ((treelike?
    (define/generic fold/g fold)
    (define (fold op initial treelike)
      (let ([current (op initial (node-value treelike))]
            [children (node-children treelike)])
        (if (null? children)
            current
            (fold op (fold/g op current (first children))
                  (rest children))))))
   ((const true)
    (define (fold op initial any)
      (op initial any)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And indeed it is not broken:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (fold + 0 '(1 2 3))
6&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and with some tracing added:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (fold + 0 '(1 2 3))
fold/treelike + 0 (1 2 3)
fold/any + 1 2
fold/treelike + 3 (3)
6&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="adding-a-special-case-to-fold-for-the-binary-tree"&gt;Adding a special case to &lt;code&gt;fold&lt;/code&gt; for the binary tree&lt;/h2&gt;

&lt;p&gt;So now, finally, we can add a special case to &lt;code&gt;fold&lt;/code&gt; to the binary tree defined above, rather than needlessly consing a list of children. We will need the same explicit-generic-function hack as before as the children of a binary tree may not be binary trees.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(struct binary-tree (value left right)
  #:transparent
  #:methods gen:treelike
  ((define (node-value bt)
     (binary-tree-value bt))
   (define (node-children bt)
     (list (binary-tree-left bt)
           (binary-tree-right bt))))
  #:methods gen:foldable
  ((define/generic fold/g fold)
   (define (fold op initial bt)
     (fold/g op
             (fold/g op (op initial (binary-tree-value bt))
                     (binary-tree-left bt))
             (binary-tree-right bt)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (fold + 0 (binary-tree 1
                         (binary-tree 2 3 4)
                         (binary-tree 5 6 7)))
28&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and with some tracing&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (fold + 0 (binary-tree 1
                         (binary-tree 2 3 4)
                         (binary-tree 5 6 7)))
fold/bt + 0 #(struct:binary-tree 1 #(struct:binary-tree 2 3 4) #(struct:binary-tree 5 6 7))
fold/bt + 1 #(struct:binary-tree 2 3 4)
fold/any + 3 3
fold/any + 6 4
fold/bt + 10 #(struct:binary-tree 5 6 7)
fold/any + 15 6
fold/any + 21 7
28&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="missing-clos"&gt;Missing CLOS&lt;/h2&gt;

&lt;p&gt;In some ways this makes me miss CLOS: the explicit-generic-function hack is very annoying, single dispatch is annoying, not being able to define predicate-based methods separately from the &lt;code&gt;define-generics&lt;/code&gt; form is annoying. But on the other hand predicate-based dispatch is pretty cool.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2021-01-08-generic-interfaces-in-racket-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;Perhaps these should be called &amp;lsquo;sloppy trees&amp;rsquo; or something.&amp;nbsp;&lt;a href="#2021-01-08-generic-interfaces-in-racket-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">The U combinator</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2020/03/09/the-u-combinator/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2020-03-09-the-u-combinator</id>
  <published>2020-03-09T17:45:22Z</published>
  <updated>2020-03-09T17:45:22Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;The U combinator allows you to define recursive functions and I think it is simpler to understand than the Y combinator.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;It&amp;rsquo;s not obvious how things like &lt;code&gt;letrec&lt;/code&gt; get defined in Scheme, without using secret assignment. In fact I think they &lt;em&gt;are&lt;/em&gt; defined using secret assignment:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(letrec ([f (λ (...) ... (f ...) ...)])
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;turns into&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(let ([f ...])
  (set! f (λ (...) ... (f ...) ...))
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But it&amp;rsquo;s interesting to see how you can define recursive functions without relying on assignment, including mutually-recursive collections of functions. One way is using the U combinator.&lt;/p&gt;

&lt;p&gt;I suspect that there is lots of information about this out there, but it&amp;rsquo;s seriously hard to search for anything which looks like &amp;rsquo;*-combinator&amp;rsquo; now (even now I am starting a set of companies called &amp;lsquo;integration by parts&amp;rsquo;, &amp;lsquo;the quotient rule&amp;rsquo; &amp;amp;c).&lt;/p&gt;

&lt;p&gt;You can famously do this with the Y combinator, but I didn&amp;rsquo;t want to do that because Y is something I find I can understand for a few hours at a time and then I have to work it all out again. But it turns out that you can use something much simpler: the U combinator. It seems to be even harder to search for this than Y, but here is a quote about it:&lt;/p&gt;

&lt;blockquote&gt;
 &lt;p&gt;In the theory of programming languages, the U combinator, \(U\), is the mathematical function that applies its argument to its argument; that is \(U(f) = f(f)\), or equivalently, \(U = \lambda f \cdot f(f)\).&lt;/p&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;
 &lt;p&gt;Self-application permits the simulation of recursion in the λ-calculus, which means that the U combinator enables universal computation. (The U combinator is actually more primitive than the more well-known fixed-point Y combinator.)&lt;/p&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;
 &lt;p&gt;The expression \(U(U)\) is the smallest non-terminating program.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;(Text mildly edited from &lt;a href="http://www.ucombinator.org/"&gt;here&lt;/a&gt;, which unfortunately is not a site all about the U combinator other than this quote.)&lt;/p&gt;

&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt;

&lt;p&gt;All of the following code samples are in &lt;a href="https://racket-lang.org/"&gt;Racket&lt;/a&gt;. The macros are certainly Racket-specific and some of the other code probably is as well. To make the macros work you will need &lt;code&gt;syntax-parse&lt;/code&gt; via:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require (for-syntax syntax/parse))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However note that my use of &lt;code&gt;syntax-parse&lt;/code&gt; is naïve in the extreme: I&amp;rsquo;m really just an unfrozen CL caveman pretending to understand Racket&amp;rsquo;s macro system.&lt;/p&gt;

&lt;p&gt;Also note I have not ruthlessly turned everything into λ: Rather than &lt;code&gt;((λ (...) ...) ...)&lt;/code&gt; there is &lt;code&gt;(let ([... ...] ...) ...)&lt;/code&gt; in this code; there is use of multiple values including &lt;code&gt;let-values&lt;/code&gt;; there is &lt;code&gt;(define (f ...) ...)&lt;/code&gt; rather than &lt;code&gt;(define f (λ (...) ...))&lt;/code&gt; and so on.&lt;/p&gt;

&lt;h2 id="two-versions-of-u"&gt;Two versions of U&lt;/h2&gt;

&lt;p&gt;The first version of U is the obvious one:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (U f)
  (f f))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But this will run into some problems with an applicative-order language, which Racket is by default. To avoid that we can make the assumption that &lt;code&gt;(f f)&lt;/code&gt; is going to be a function, and wrap that form in another function to delay its evaluation until it&amp;rsquo;s needed: this is the standard trick that you have to do for Y in an applicative-order language as well. I&amp;rsquo;m only going to use the applicative-order U when I have to, so I&amp;rsquo;ll give it a different name:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (U/ao f)
  (λ args (apply (f f) args)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note also that I&amp;rsquo;m allowing more than one argument rather than doing the pure-λ-calculus thing.&lt;/p&gt;

&lt;h2 id="using-u-to-construct-a-recursive-functions"&gt;Using U to construct a recursive functions&lt;/h2&gt;

&lt;p&gt;To do this we do a similar trick that you do with Y: write a function which, if given a function as argument which deals with the recursive cases, will return a recursive function. And obviously I&amp;rsquo;ll use the Fibonacci function as the canonical recursive function.&lt;/p&gt;

&lt;p&gt;So, consider this thing:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define fibber
  (λ (f)
    (λ (n)
      (if (&amp;lt;= n 2)
          1
          (+ ((U f) (- n 1))
             ((U f) (- n 2)))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a function which, given another function, &lt;code&gt;U&lt;/code&gt; of which computes smaller Fibonacci numbers, will return a function which will compute the Fibonacci number for &lt;code&gt;n&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In other words, &lt;em&gt;&lt;code&gt;U&lt;/code&gt; of this function is the Fibonacci function&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;And we can test this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (define fibonacci (U fibber))
&amp;gt; (fibonacci 10)
55&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So that&amp;rsquo;s very nice.&lt;/p&gt;

&lt;h2 id="wrapping-u-in-a-macro"&gt;Wrapping U in a macro&lt;/h2&gt;

&lt;p&gt;So, to hide all this the first thing to do is to remove the explicit calls to &lt;code&gt;U&lt;/code&gt; in the recursion. We can lift them out of the inner function completely:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define fibber/broken
  (λ (f)
    (let ([fib (U f)])
      (λ (n)
        (if (&amp;lt;= n 2)
            1
            (+ (fib (- n 1))
               (fib (- n 2))))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Don&amp;rsquo;t try to compute &lt;code&gt;U&lt;/code&gt; of this&lt;/em&gt;: it will recurse endlessly because &lt;code&gt;(U fibber/broken)&lt;/code&gt; -&amp;gt; &lt;code&gt;(fibber/broken fibber/broken)&lt;/code&gt; and this involves computing &lt;code&gt;(U fibber/broken)&lt;/code&gt;, and we&amp;rsquo;re doomed.&lt;/p&gt;

&lt;p&gt;Instead we can use &lt;code&gt;U/ao&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define fibber
  (λ (f)
    (let ([fib (U/ao f)])
      (λ (n)
        (if (&amp;lt;= n 2)
            1
            (+ (fib (- n 1))
               (fib (- n 2))))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this is all fine &lt;code&gt;((U fibber) 10)&lt;/code&gt; is &lt;code&gt;55&lt;/code&gt; (and terminates!).&lt;/p&gt;

&lt;p&gt;Purists can then turn &lt;code&gt;let&lt;/code&gt; into &lt;code&gt;λ&lt;/code&gt; in the usual way:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define fibber
  (λ (f)
    ((λ (fib)
       (λ (n)
         (if (&amp;lt;= n 2)
             1
             (+ (fib (- n 1))
                (fib (- n 2))))))
     (U/ao f))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this is really all you need to be able to write the macro:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax (with-recursive-binding stx)
  (syntax-parse stx
    [(_ (name:id value:expr) form ...+)
     #'(let ([name (U (λ (f)
                        (let ([name (U/ao f)])
                          value)))])
         form ...)]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or, for the pure of heart:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax (with-recursive-binding stx)
  (syntax-parse stx
    [(_ (name:id value:expr) form ...+)
     #'((λ (name)
          form ...)
        (U (λ (f)
             ((λ (name)
                value)
              (U/ao f)))))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this works fine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(with-recursive-binding (fib (λ (n)
                               (if (&amp;lt;= n 2)
                                   1
                                   (+ (fib (- n 1))
                                      (fib (- n 2))))))
  (fib 10))&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="a-caveat-on-bindings"&gt;A caveat on bindings&lt;/h2&gt;

&lt;p&gt;One fairly obvious thing here is that there are &lt;em&gt;two&lt;/em&gt; bindings constructed by this macro: the outer one, and an inner one of the same name. And these are not bound to the same function in the sense of &lt;code&gt;eq?&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(with-recursive-binding (ts (λ (it)
                              (eq? ts it)))
  (ts ts))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;is &lt;code&gt;#f&lt;/code&gt;. This matters only in a language where bindings can be mutated: a language with assignment in other words. Both the outer and inner bindings, unless they have been mutated, are to functions which are identical &lt;em&gt;as functions&lt;/em&gt;: they compute the same values for all values of their arguments. In fact, it&amp;rsquo;s hard to see what purpose &lt;code&gt;eq?&lt;/code&gt; would serve in a language without assignment.&lt;/p&gt;

&lt;p&gt;This caveat will apply below as well.&lt;/p&gt;

&lt;h2 id="two-versions-of-u-for-many-functions"&gt;Two versions of U for many functions&lt;/h2&gt;

&lt;p&gt;The obvious generalization of U, U*, to many functions is that \(U^*(f_1, \ldots, f_n)\) is the tuple \((f_1(f_1, \ldots, f_n), f_2(f_1, \ldots, f_n), \ldots)\). And a nice way of expressing that in Racket is to use multiple values:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (U* . fs)
  (apply values (map (λ (f)
                       (apply f fs))
                     fs)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And we need the applicative-order one as well:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (U*/ao . fs)
  (apply values (map (λ (f)
                       (λ args (apply (apply f fs) args)))
                     fs)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that U* is a true generalization of U: &lt;code&gt;(U f)&lt;/code&gt; and &lt;code&gt;(U* f)&lt;/code&gt; are the same.&lt;/p&gt;

&lt;h2 id="using-u-to-construct-mutually-recursive-functions"&gt;Using U* to construct mutually-recursive functions&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;ll work with a trivial pair of functions:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;an object is a &lt;em&gt;numeric tree&lt;/em&gt; if it is a cons and its car and cdr are numeric objects;&lt;/li&gt;
 &lt;li&gt;an objct is a &lt;em&gt;numeric object&lt;/em&gt; if it is a number, or if it is a numeric tree.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;So we can define &amp;lsquo;maker&amp;rsquo; functions (with an &amp;rsquo;-er&amp;rsquo; convention: a function which makes an &lt;em&gt;x&lt;/em&gt; is an &lt;em&gt;x&lt;/em&gt;er, or, if &lt;em&gt;x&lt;/em&gt; has hyphens in it, an &lt;em&gt;x&lt;/em&gt;-er) which will make suitable functions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define numeric-tree-er
  (λ (nter noer)
    (λ (o)
      (let-values ([(nt? no?) (U* nter noer)])
        (and (cons? o)
             (no? (car o))
             (no? (cdr o)))))))

(define numeric-object-er
  (λ (nter noer)
    (λ (o)
      (let-values ([(nt? no?) (U* nter noer)])
        (cond
          [(number? o) #t]
          [(cons? o) (nt? o)]
          [else #f])))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that for both of these I&amp;rsquo;ve raised the call to &lt;code&gt;U*&lt;/code&gt; a little, simply to make the call to the appropriate value of &lt;code&gt;U*&lt;/code&gt; less opaque.&lt;/p&gt;

&lt;p&gt;And this works:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-values (numeric-tree? numeric-object?)
  (U* numeric-tree-er numeric-object-er))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (numeric-tree? 1)
#f
&amp;gt; (numeric-object? 1)
#t
&amp;gt; (numeric-tree? '(1 . 2))
#t
&amp;gt; (numeric-tree? '(1 2 . (3 4)))
#f&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="wrapping-u-in-a-macro"&gt;Wrapping U* in a macro&lt;/h2&gt;

&lt;p&gt;The same problem as previously happens when we raise the inner call to &lt;code&gt;U*&lt;/code&gt; with the same result: we need to use &lt;code&gt;U*/ao&lt;/code&gt;. In addition the macro becomes significantly more hairy and I&amp;rsquo;m moderately surprised that I got it right so easily. It&amp;rsquo;s not conceptually hard: it&amp;rsquo;s just not obvious to me that the pattern-matching works.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax (with-recursive-bindings stx)
  (syntax-parse stx
    [(_ ((name:id value:expr) ...) form ...+)
     #:fail-when (check-duplicate-identifier (syntax-&amp;gt;list #'(name ...)))
     "duplicate variable name"
     (with-syntax ([(argname ...) (generate-temporaries #'(name ...))])
       #'(let-values
             ([(name ...) (U* (λ (argname ...)
                                (let-values ([(name ...)
                                              (U*/ao argname ...)])
                                  value)) ...)])
           form ...))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now, in a shower of sparks, we can write:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(with-recursive-bindings ((numeric-tree?
                           (λ (o)
                             (and (cons? o)
                                  (numeric-object? (car o))
                                  (numeric-object? (cdr o)))))
                          (numeric-object?
                           (λ (o)
                             (cond [(number? o) #t]
                                   [(cons? o) (numeric-tree? o)]
                                   [else #f]))))
  (numeric-tree? '(1 2 3 (4 (5 . 6) . 7) . 8)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and get &lt;code&gt;#t&lt;/code&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;As I said, I am sure there are well-known better ways to do this, but I thought this was interesting enough not to lose. This originated as an answer to &lt;a href="https://stackoverflow.com/questions/60460322/implement-a-self-reference-pointer-in-a-pure-functional-language-elm-haskell"&gt;this Stack Overflow question&lt;/a&gt;.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Function calling conventions and bindings</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2019/01/04/function-calling-conventions-and-bindings/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2019-01-04-function-calling-conventions-and-bindings</id>
  <published>2019-01-04T10:19:36Z</published>
  <updated>2019-01-04T10:19:36Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;An attempt to describe three well-known function calling conventions in terms of bindings.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;A little while ago I wrote an &lt;a href="../../../../2018/12/11/call-by-value-in-scheme-and-lisp"&gt;article on bindings&lt;/a&gt; which, in turn, was based on my answer to &lt;a href="https://stackoverflow.com/questions/53694761/pass-by-value-confusion-in-scheme"&gt;this Stack Overflow question&lt;/a&gt;. I have since written another answer to &lt;a href="https://stackoverflow.com/questions/54018077/in-common-lisp-when-are-objects-referenced-and-when-are-they-directly-accessed"&gt;a more recent question&lt;/a&gt; and I thought it would be worth summarising part of that to describe how three famous function calling conventions can be described in terms of bindings&lt;sup&gt;&lt;a href="#2019-01-04-function-calling-conventions-and-bindings-footnote-1-definition" name="2019-01-04-function-calling-conventions-and-bindings-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h2 id="bindings-in-brief"&gt;Bindings in brief&lt;/h2&gt;

&lt;p&gt;A &lt;em&gt;binding&lt;/em&gt; is an association between a name (a variable) and a value, where the value can be any object the language can talk about. In most Lisps (and other languages) bindings are not first-class: the language can not talk about bindings directly, and in particular bindings can not be values. Bindings are, or may be, &lt;em&gt;mutable&lt;/em&gt;: their values (but not their names) can be changed by assignment. Many bindings can share the same value. Bindings have scope (where they are accessible) and extent (how long they are accessible for) and there are rules about that.&lt;/p&gt;

&lt;h2 id="call-by-value"&gt;Call by value&lt;/h2&gt;

&lt;p&gt;In call by value the &lt;em&gt;value&lt;/em&gt; of a binding is passed to a procedure. This means that the procedure can not mutate the binding itself. If the value is a mutable object it can be altered by the procedure, but the binding can not be.&lt;/p&gt;

&lt;p&gt;Call by value is the convention used by all Lisps I know of. Here is a function which demonstrates that call by value can not mutate bindings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun pbv (&amp;amp;optional (fn #'identity))
  ;; If FN returns then the first value of this function will be T
  (let ((c (cons 0 0)))                 ;first binding
    (let ((cc c))                       ;second binding, shares value with first
      (funcall fn c)                    ;FN gets the *value* of C
      (values (eq c cc) c))))           ;C and CC still refer to the same object&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="call-by-reference"&gt;Call by reference&lt;/h2&gt;

&lt;p&gt;In call by reference, procedures get &lt;em&gt;the bindings themselves&lt;/em&gt; as arguments. If a procedure modifies the binding by assignment, then it is modified in the calling procedure as well.&lt;/p&gt;

&lt;p&gt;Lisp does not use call by reference: Fortran does, or can, use a calling mechanism which is equivalent to call by reference&lt;sup&gt;&lt;a href="#2019-01-04-function-calling-conventions-and-bindings-footnote-2-definition" name="2019-01-04-function-calling-conventions-and-bindings-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;It is possible to implement what is essentially call by reference in Lisp (here Common Lisp, but any Lisp with lexical scope, indefinite extent &amp;amp; macros can do this) using some macrology:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defmacro capture-binding (var)
  ;; Construct an object which captures a binding
  `(lambda (&amp;amp;optional (new-val nil new-val-p))
     (when new-val-p
       (setf ,var new-val))
     ,var))

(declaim (inline captured-binding-value
                 (setf captured-binding-value)))

(defun captured-binding-value (cb)
  ;; value of a captured binding
  (funcall cb))

(defun (setf captured-binding-value) (new cb)
  ;; change the value of a captured binding
  (funcall cb new))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now, given&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun mutate-binding (b v)
  (setf (captured-binding-value b) v))

(defun sort-of-call-by-reference ()
  (let ((c (cons 1 1)))
    (let ((cc c))
      (mutate-binding (capture-binding cc) 3)
      (values c cc))))

&amp;gt; (sort-of-call-by-reference)
(1 . 1)
3&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The trick here is that the procedure created by the &lt;code&gt;capture-binding&lt;/code&gt; macro has access to the binding being captured, and can mutate it.&lt;/p&gt;

&lt;h2 id="call-by-name"&gt;Call by name&lt;/h2&gt;

&lt;p&gt;Call by name is the same as call by value, except the value of a binding is only computed at the point it is needed. Call by name is a form of delayed evaluation or normal-order evaluation strategy.&lt;/p&gt;

&lt;p&gt;Lisp (at least Common Lisp: Lisps which have normal-order evaluation strategies exist) does not have call by name, but again it can be emulated with some macrology:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defmacro delay (form)
  ;; simple-minded DELAY.  FORM is assumed to return a single value,
  ;; and will be evaluated no more than once.
  (let ((fpn (make-symbol "FORCEDP"))
        (vn (make-symbol "VALUE")))
    `(let ((,fpn nil) ,vn)
       (lambda ()
         (unless ,fpn
           (setf ,fpn t
                 ,vn ,form))
         ,vn))))

(declaim (inline force))

(defun force (thunk)
  ;; forcd a thunk
  (funcall thunk))

(defmacro funcall/delayed (fn &amp;amp;rest args)
  ;; call a function with a bunch of delayed arguments
  `(funcall ,fn ,@(mapcar (lambda (a)
                            `(delay ,a))
                          args)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun return-first-thunk-value (t1 t2)
  (declare (ignorable t2))
  (force t1))

(defun surprisingly-quick ()
  (funcall/delayed #'return-first-thunk-value
                   (cons 1 2)
                   (loop repeat 1000000
                         collect
                         (loop repeat 1000000
                               collect
                               (loop repeat 1000000
                                     collect 1)))))

&amp;gt; (time (surprisingly-quick))
Timing the evaluation of (surprisingly-quick)

User time    =        0.000
System time  =        0.000
Elapsed time =        0.001
Allocation   = 224 bytes
3 Page faults
(1 . 2)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The second argument to &lt;code&gt;return-first-thunk-value&lt;/code&gt; was never forced, and so the function completes in reasonable time.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2019-01-04-function-calling-conventions-and-bindings-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;This, in turn, is distantly descended from &lt;a href="https://www.xach.com/naggum/articles/3229347076995853@naggum.net.html"&gt;a post on &lt;code&gt;comp.lang.lisp&lt;/code&gt; by Erik Naggum&lt;/a&gt;.&amp;nbsp;&lt;a href="#2019-01-04-function-calling-conventions-and-bindings-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2019-01-04-function-calling-conventions-and-bindings-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;I think Fortran is allowed to implement its &amp;lsquo;by reference&amp;rsquo; calls by copying any modified bindings back to the bindings in the parent procedure, and this is largely equivalent, at least for single-threaded code.&amp;nbsp;&lt;a href="#2019-01-04-function-calling-conventions-and-bindings-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Call by value in Scheme and Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2018/12/11/call-by-value-in-scheme-and-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2018-12-11-call-by-value-in-scheme-and-lisp</id>
  <published>2018-12-11T10:50:28Z</published>
  <updated>2018-12-11T10:50:28Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;I find the best way to think about this is to think in terms of &lt;em&gt;bindings&lt;/em&gt;, rather than environments or frames, which are simply containers for bindings.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="bindings"&gt;Bindings&lt;/h2&gt;

&lt;p&gt;A binding is an association between a &lt;em&gt;name&lt;/em&gt; and a &lt;em&gt;value&lt;/em&gt;. The name is often called a &amp;lsquo;variable&amp;rsquo; and the value is, well, the value of the variable. The value of a binding can be any object that the language can talk about at all. Bindings, however, are behind-the-scenes things (sometimes this is called &amp;lsquo;not being first-class objects&amp;rsquo;): they&amp;rsquo;re not things that can be represented in the language but rather things that you can use as part of the model of how the language works. So &lt;em&gt;the value of a binding can&amp;rsquo;t be a binding&lt;/em&gt;, because bindings are not first-class: the language can&amp;rsquo;t talk about bindings.&lt;/p&gt;

&lt;p&gt;There are some rules about bindings:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;there are forms which create them, of which the most important two are &lt;code&gt;lambda&lt;/code&gt; and &lt;code&gt;define&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;bindings are not first-class &amp;mdash; the language can not represent bindings as values;&lt;/li&gt;
 &lt;li&gt;bindings are, or may be, &lt;em&gt;mutable&lt;/em&gt; &amp;mdash; you can change the value of a binding once it exists &amp;mdash; and the form that does this is &lt;code&gt;set!&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;there is no operator which destroys a binding;&lt;/li&gt;
 &lt;li&gt;bindings have &lt;em&gt;lexical scope&lt;/em&gt; &amp;mdash; the bindings available to a bit of code are the ones you can see by looking at it, not ones you have to guess by running the code and which may depend on the dynamic state of the system;&lt;/li&gt;
 &lt;li&gt;only one binding for a given name is ever accessible from a given bit of code &amp;mdash; if more than one is lexically visible then the innermost one shadows any outer ones;&lt;/li&gt;
 &lt;li&gt;bindings have &lt;em&gt;indefinite extent&lt;/em&gt; &amp;mdash; if a binding is ever available to a bit of code, it is always available to it.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Obviously these rules need to be elaborated significantly (especially with regards to global bindings &amp;amp; forward-referenced bindings) and mare formal, but these are enough to understand what happens. In particular I don&amp;rsquo;t really think you need to spend a lot of time worrying about environments: the environment of a bit of code is just the set of bindings accessible to it, so rather than worry about the environment just worry about the bindings.&lt;/p&gt;

&lt;h2 id="call-by-value"&gt;Call by value&lt;/h2&gt;

&lt;p&gt;So, what &amp;lsquo;call by value&amp;rsquo; means is that when you call a procedure with an argument which is a variable (a binding) what is passed to it is the &lt;em&gt;value&lt;/em&gt; of the variable binding, not the binding itself. The procedure then creates a &lt;em&gt;new&lt;/em&gt; binding with the same value. Two things follow from that:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;the original binding can not be altered by the procedure &amp;mdash; this follows because the procedure only has the value of it, not the binding itself, and bindings are not first-class so you can&amp;rsquo;t cheat by passing the binding itself as the value;&lt;/li&gt;
 &lt;li&gt;if the value is itself a mutable object (arrays &amp;amp; conses are example of objects which usually are mutable, numbers are examples of objects which are not) then the procedure can mutate that object.&lt;/li&gt;&lt;/ul&gt;

&lt;h2 id="examples-of-the-rules-about-bindings"&gt;Examples of the rules about bindings&lt;/h2&gt;

&lt;p&gt;So, here are some examples of these rules.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (silly x)
  (set! x (+ x 1))
  x)

(define (call-something fn val)
  (fn val)
  val))

&amp;gt; (call-something silly 10)
10&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, here we are creating two top-level bindings, for &lt;code&gt;silly&lt;/code&gt; and &lt;code&gt;call-something&lt;/code&gt;, both of which have values which are procedures. The value of &lt;code&gt;silly&lt;/code&gt; is a procedure which, when called:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;creates a new binding whose name is &lt;code&gt;x&lt;/code&gt; and whose value is the argument to &lt;code&gt;silly&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;mutates this binding so its value is incremented by one;&lt;/li&gt;
 &lt;li&gt;returns the value of this binding, which is one more than the value it was called with.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;The value of &lt;code&gt;call-something&lt;/code&gt; is a procedure which, when called:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;creates two bindings, one named &lt;code&gt;fn&lt;/code&gt; and one named &lt;code&gt;val&lt;/code&gt;;&lt;/li&gt;
 &lt;li&gt;calls the value of the &lt;code&gt;fn&lt;/code&gt; binding with the value of the &lt;code&gt;val&lt;/code&gt; binding;&lt;/li&gt;
 &lt;li&gt;returns the value of the &lt;code&gt;val&lt;/code&gt; binding.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Note that &lt;em&gt;whatever&lt;/em&gt; the call to &lt;code&gt;fn&lt;/code&gt; does, it can not mutate the binding of &lt;code&gt;val&lt;/code&gt;, because it has no access to it. So what you can &lt;em&gt;know&lt;/em&gt;, by looking at the definition of &lt;code&gt;call-something&lt;/code&gt; is that, if it returns at all (it may not return if the call to &lt;code&gt;fn&lt;/code&gt; does not return), it will return the value of its second argument. This guarantee is what &amp;lsquo;call by value&amp;rsquo; means: a language (such as Fortran) which supports other call mechanisms can&amp;rsquo;t always promise this.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (outer x)
  (define (inner x)
    (+ x 1))
  (inner (+ x 1)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here there are four bindings: &lt;code&gt;outer&lt;/code&gt; is a top-level binding whose value is a procedure which, when it is called, creates a binding for &lt;code&gt;x&lt;/code&gt; whose value is its argument. It then creates another binding called &lt;code&gt;inner&lt;/code&gt; whose value is another procedure, which, when it is called, creates a &lt;em&gt;new&lt;/em&gt; binding for &lt;code&gt;x&lt;/code&gt; to &lt;em&gt;its&lt;/em&gt; argument, and then returns the value of that binding plus one. &lt;code&gt;outer&lt;/code&gt; then calls this inner procedure with the value of its binding for &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The important thing here is that, in &lt;code&gt;inner&lt;/code&gt;, there are two bindings for &lt;code&gt;x&lt;/code&gt; which are potentially lexically visible, but the closest one &amp;mdash; the one established by &lt;code&gt;inner&lt;/code&gt; &amp;mdash; wins, because only one binding for a given name can ever be accessible at one time.&lt;/p&gt;

&lt;p&gt;Here is the previous code (this would not be equivalent if &lt;code&gt;inner&lt;/code&gt; was recursive) expressed with explicit &lt;code&gt;lambda&lt;/code&gt;s:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define outer
  (λ (x)
    ((λ (inner)
       (inner (+ x 1)))
     (λ (x)
       (+ x 1)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally an example of mutating bindings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (make-counter val)
  (λ ()
    (let ((current val))
      (set! val (+ val 1))
      current)))

&amp;gt; (define counter (make-counter 0))
&amp;gt; (counter)
0
&amp;gt; (counter)
1
&amp;gt; (counter)
2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, here, &lt;code&gt;make-counter&lt;/code&gt; (is the name of a binding whose value is a procedure which, when called,) establishes a new binding for &lt;code&gt;val&lt;/code&gt; and then returns a procedure it has created. This procedure makes a new binding called &lt;code&gt;current&lt;/code&gt; which catches the current value of &lt;code&gt;val&lt;/code&gt;, &lt;em&gt;mutates&lt;/em&gt; the binding for &lt;code&gt;val&lt;/code&gt; to add one to it, and returns the value of &lt;code&gt;current&lt;/code&gt;. This code exercises the &amp;lsquo;if you can ever see a binding, you can always see it&amp;rsquo; rule: the binding for &lt;code&gt;val&lt;/code&gt; created by the call to &lt;code&gt;make-counter&lt;/code&gt; is visible to the procedure it returns for as long as that procedure exists (and that procedure exists at least as long as there is a binding for it), and it also mutates a binding with &lt;code&gt;set!&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="why-not-environments"&gt;Why not environments?&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://mitpress.mit.edu/sites/default/files/sicp/index.html"&gt;SICP&lt;/a&gt;, in &lt;a href="https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-19.html#%_chap_3"&gt;chapter 3&lt;/a&gt;, introduces the &amp;lsquo;environment model&amp;rsquo;, where at any point there is an environment, consisting of a sequence of frames, each frame containing bindings. Obviously this is a fine model, but it introduces three kinds of thing &amp;mdash; the enviromnent, the frames in the environment and the bindings in the frame &amp;mdash; two of which are utterly intangible. At least for a binding you can get hold of it in some way: you can see it being created in the code and you can see references to it. So I prefer not to think in terms of these two extra sorts of thing which you can never get any kind of handle on.&lt;/p&gt;

&lt;p&gt;However this is a choice which makes no difference in practice: thinking purely in terms of bindings helps me, thinking in terms of environments, frames &amp;amp; bindings may well help other people more.&lt;/p&gt;

&lt;h2 id="shorthands"&gt;Shorthands&lt;/h2&gt;

&lt;p&gt;In what follows I am going to use a shorthand for talking about bindings, especially top-level ones:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&amp;rsquo;&lt;code&gt;x&lt;/code&gt; is a procedure which &amp;hellip;&amp;rsquo; means &amp;rsquo;&lt;code&gt;x&lt;/code&gt; is the name of a binding whose value is a procedure which, when called, &amp;hellip;&amp;rsquo;;&lt;/li&gt;
 &lt;li&gt;&amp;rsquo;&lt;code&gt;y&lt;/code&gt; is &amp;hellip;&amp;rsquo; means &amp;rsquo;&lt;code&gt;y&lt;/code&gt; is the name of a binding the value of which is &amp;hellip;&amp;rsquo;;&lt;/li&gt;
 &lt;li&gt;&amp;rsquo;&lt;code&gt;x&lt;/code&gt; is called with &lt;code&gt;y&lt;/code&gt;&amp;rsquo; means &amp;lsquo;the value of the binding named by &lt;code&gt;x&lt;/code&gt; is called with the value of the binding named by &lt;code&gt;y&lt;/code&gt;&amp;rsquo;;&lt;/li&gt;
 &lt;li&gt;&amp;rsquo;&amp;hellip; binds &lt;code&gt;x&lt;/code&gt; to &amp;hellip;&amp;rsquo; means &amp;rsquo;&amp;hellip; creates a binding whose name is &lt;code&gt;x&lt;/code&gt; and whose value is &amp;hellip;&amp;rsquo;;&lt;/li&gt;
 &lt;li&gt;&amp;rsquo;&lt;code&gt;x&lt;/code&gt;&amp;rsquo; means &amp;lsquo;the value of &lt;code&gt;x&lt;/code&gt;&amp;rsquo;;&lt;/li&gt;
 &lt;li&gt;and so on.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Describing bindings like this is common, as the fully-explicit way is just painful: I&amp;rsquo;ve tried (but probably failed in places) to be fully explicit above.&lt;/p&gt;

&lt;h2 id="the-answer"&gt;The answer&lt;/h2&gt;

&lt;p&gt;And finally, after this long preamble, here&amp;rsquo;s the answer to the question you asked&lt;sup&gt;&lt;a href="#2018-12-11-call-by-value-in-scheme-and-lisp-footnote-1-definition" name="2018-12-11-call-by-value-in-scheme-and-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (make-withdraw balance)
  (λ (amount)
    (if (&amp;gt;= balance amount)
        (begin (set! balance (- balance amount))
               balance)
        "Insufficient funds")))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;make-withdraw&lt;/code&gt; binds &lt;code&gt;balance&lt;/code&gt; to its argument and returns a procedure it makes. This procedure, when called:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;binds &lt;code&gt;amount&lt;/code&gt; to its argument;&lt;/li&gt;
 &lt;li&gt;compares &lt;code&gt;amount&lt;/code&gt; with &lt;code&gt;balance&lt;/code&gt; (which it can still see because it could see it when it was created);&lt;/li&gt;
 &lt;li&gt;if there&amp;rsquo;s enough money then it mutates the &lt;code&gt;balance&lt;/code&gt; binding, decrementing its value by the value of the &lt;code&gt;amount&lt;/code&gt; binding, and returns the new value;&lt;/li&gt;
 &lt;li&gt;if there&amp;rsquo;s not enough money it returns &lt;code&gt;"Insuficient funds"&lt;/code&gt; (but does &lt;em&gt;not&lt;/em&gt; mutate the &lt;code&gt;balance&lt;/code&gt; binding, so you can try again with a smaller amount: a real bank would probably suck some money out of the &lt;code&gt;balance&lt;/code&gt; binding at this point as a fine).&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Now&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define x (make-withdraw 100))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;creates a binding for &lt;code&gt;x&lt;/code&gt; whose value is one of the procedures described above: in that procedure &lt;code&gt;balance&lt;/code&gt; is initially &lt;code&gt;100&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (f y) (y 25))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;f&lt;/code&gt; is a procedure (is the name of a binding whose value is a procedure, which, when called) which binds &lt;code&gt;y&lt;/code&gt; to its argument and then calls it with an argument of &lt;code&gt;25&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(f x)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, &lt;code&gt;f&lt;/code&gt; is called with &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt; being (bound to) the procedure constructed above. In &lt;code&gt;f&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt; is bound to this procedure (not to a copy of it, to it), and this procedure is then called with an argument of &lt;code&gt;25&lt;/code&gt;. This procedure then behaves as described above, and the results are as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (f x)
75
&amp;gt; (f x)
50
&amp;gt; (f x)
25
&amp;gt; (f x)
0
&amp;gt; (f x)
"Insufficient funds"&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;no first-class objects are copied anywhere in this process: there is no &amp;lsquo;copy&amp;rsquo; of a procedure created;&lt;/li&gt;
 &lt;li&gt;no first-class objects are mutated anywhere in this process;&lt;/li&gt;
 &lt;li&gt;bindings are created (and later become inacessible and so can be destroyed) in this process;&lt;/li&gt;
 &lt;li&gt;one binding is mutated repeatedly in this process (once for each call);&lt;/li&gt;
 &lt;li&gt;I have not anywhere needed to mention &amp;lsquo;environments&amp;rsquo;, which are just the set of bindings visible from a certain point in the code and I think not a very useful concept.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;I hope this makes some kind of sense.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id="a-more-elaborate-version-of-the-above-code"&gt;A more elaborate version of the above code&lt;/h2&gt;

&lt;p&gt;Something you might want to be able to do is to back out a transaction on your account. One way to do that is to return, as well as the new balance, a procedure which undoes the last transaction. Here is a procedure which does that (this code is in &lt;a href="http://racket-lang.org/"&gt;Racket&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (make-withdraw/backout
         balance
         (insufficient-funds "Insufficient funds"))
  (λ (amount)
    (if (&amp;gt;= balance amount)
        (let ((last-balance balance))
          (set! balance (- balance amount))
              (values balance
                      (λ ()
                       (set! balance last-balance)
                       balance)))
            (values
             insufficient-funds
             (λ () balance)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When you make an account with this procedure, then calling it returns two values: the first is the new balance, or the value of &lt;code&gt;insufficient-funds&lt;/code&gt; (defaultly &lt;code&gt;"Insufficient funds"&lt;/code&gt;), the second is a procedure which will undo the transaction you just did. Note that it undoes it by explicitly putting back the old balance, because you can&amp;rsquo;t necessarily rely on &lt;code&gt;(= (- (+ x y) y) x)&lt;/code&gt; being true in the presence of floating-point arithmetic I think. If you understand how this works then you probably understand bindings.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2018-12-11-call-by-value-in-scheme-and-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;This originated as an answer to &lt;a href="https://stackoverflow.com/questions/53694761/pass-by-value-confusion-in-scheme"&gt;this Stack Overflow question&lt;/a&gt;.&amp;nbsp;&lt;a href="#2018-12-11-call-by-value-in-scheme-and-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Dynamic scope and macros</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2017/01/26/dynamic-scope-and-macros/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2017-01-26-dynamic-scope-and-macros</id>
  <published>2017-01-26T13:56:36Z</published>
  <updated>2017-01-26T13:56:36Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;I&amp;rsquo;ve recently been writing some &lt;a href="https://en.wikipedia.org/wiki/Emacs_Lisp"&gt;Emacs Lisp&lt;/a&gt; code to do some massaging of files. Quite apart from having forgotten how primitive elisp is, I hadn&amp;rsquo;t realised before how hostile dynamic scope was for macros in particular.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;A very common pattern for macros is &lt;code&gt;call-with-*&lt;/code&gt; / &lt;code&gt;with-*&lt;/code&gt;, in which there is a functional level which is wrapped by a more syntacticlly-friendly macro level. For instance, in Common Lisp you can map over lists with &lt;code&gt;mapcar&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(mapcar
 (lambda (e)
   ...)
 ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;but you might want to map over them with a syntax like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(mapping (e ...)
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, it&amp;rsquo;s easy to implement this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defmacro mapping ((e l) &amp;amp;body forms)
  `(mapcar (lambda (,e) ,@forms) ,l))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Even with CL&amp;rsquo;s unhygienic macro system &amp;amp; without a mass of gensymmery such a macro is safe.&lt;/p&gt;

&lt;p&gt;A good example where CL exposes one side of a pattern like this is &lt;code&gt;with-open-file&lt;/code&gt;: you can easily see how to implement this in terms of a function:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun call/open-file (fn filespec &amp;amp;rest keys
                          &amp;amp;key &amp;amp;allow-other-keys)
  (let ((s nil))
    (unwind-protect
        (progn
          (setf s (apply #'open filespec keys))
          (funcall fn s))
      (when s (close s)))))

(defmacro with-open-file* ((sn filespecn &amp;amp;rest keysn 
                               &amp;amp;key &amp;amp;allow-other-keys)
                           &amp;amp;body forms)
  `(call/open-file (lambda (,sn) ,@forms)
                   ,filespecn ,@keysn))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(This is probably not completely robust code: it&amp;rsquo;s just meant to get the idea across.)&lt;/p&gt;

&lt;p&gt;Scheme exposes the other side of this pattern with &lt;code&gt;call/cc&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax-rule (with-cc (c) form ...)
  (call/cc (λ (c) form ...)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(&lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/misc..rkt)._define-syntax-rule))" style="color: inherit"&gt;define-syntax-rule&lt;/a&gt;&lt;/code&gt; may be specific to Racket but, again, this is just meant to get the idea across.)&lt;/p&gt;

&lt;p&gt;Well, now think about something like the above &lt;code&gt;call/open-file&lt;/code&gt; / &lt;code&gt;with-open-file*&lt;/code&gt; in a Lisp dialect with dynamic scope. In particular, what does this do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(let ((s t))
  (with-open-file* (h ...)
    (when s ...)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This expands to&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(let ((s t))
  (call/open-file (lambda (h) (when s ...))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But &lt;em&gt;&lt;code&gt;call/open-file&lt;/code&gt; binds &lt;code&gt;s&lt;/code&gt;&lt;/em&gt;: so the binding of &lt;code&gt;s&lt;/code&gt; in the called function is &lt;em&gt;different&lt;/em&gt; than the outer binding, and nothing works.&lt;/p&gt;

&lt;p&gt;Well, of course, this is something that happens pervasively with dynamically-scoped languages: every binding above you (or below you, depending on your viewpoint) matters, and can infect your namespace. But it&amp;rsquo;s particularly toxic for macros, because macros very often interpose bits of code into your code, and that code can include bindings which are dynamically, but not lexically, visible, even in the expansion of the macro. Dynamic scope enormously increases the hygiene problems of a macro system.&lt;/p&gt;

&lt;p&gt;Dynamic scope is really useful as an option, and systems written in languages which don&amp;rsquo;t have it generally have to reinvent it, usually badly. But it&amp;rsquo;s just toxic and horrible as the &lt;em&gt;only&lt;/em&gt; option. I can&amp;rsquo;t understand any more how I managed to use lisps with dynamic scope at all: perhaps I never wrote macros or just expected things to behave in a mysterious and strange way occasionally. Fortunately, even elisp &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html#Lexical-Binding"&gt;now has the option of being lexically scoped&lt;/a&gt;.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Python instead of Lisp</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2016/06/09/python-instead-of-lisp/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2016-06-09-python-instead-of-lisp</id>
  <published>2016-06-09T18:43:40Z</published>
  <updated>2016-06-09T18:43:40Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Lots of people, even &lt;a href="http://norvig.com/python-lisp.html"&gt;famous Lisp hackers&lt;/a&gt;, like to claim that &amp;lsquo;Python can be seen as a dialect of Lisp with &amp;ldquo;traditional&amp;rdquo; syntax&amp;rsquo;.&lt;/p&gt;

&lt;p&gt;Being famous does not make them right.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;h2 id="python-is-nothing-like-lisp"&gt;Python is &lt;em&gt;nothing like&lt;/em&gt; Lisp&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Expression language.&lt;/strong&gt; Lisp is an expression language: everything in the language is an expression and has a value, and there is no distinction between expressions and statements, because there are no statements. Python is not: it has expressions, such as &lt;code&gt;2+3&lt;/code&gt;, &lt;code&gt;lambda x: x*2&lt;/code&gt; and statements such as &lt;code&gt;x = 3&lt;/code&gt;. If expressions and statements are different things then writing macros and any kind of general-purpose &lt;code&gt;lambda&lt;/code&gt; becomes very difficult.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conses.&lt;/strong&gt; Lisp has conses, Python does not. Conses are not everything&lt;sup&gt;&lt;a href="#2016-06-09-python-instead-of-lisp-footnote-1-definition" name="2016-06-09-python-instead-of-lisp-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;, but unless you have them you can&amp;rsquo;t implement them reasonably, and they are extremely useful data structures for many purposes. In particular for conses to be useful you need two things:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;a good syntax for them and for lists built from them;&lt;/li&gt;
 &lt;li&gt;good performance &amp;mdash; conses should be extremely cheap, so you can&amp;rsquo;t implement them as a special case of some heavyweight data structure such as a Python list, because there is an enormous header.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;This means that conses need to be wired into the language: you can&amp;rsquo;t take a language without conses and add them, because even if you can get the first (you can&amp;rsquo;t in Python) you can&amp;rsquo;t get the second.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symbols.&lt;/strong&gt; Lisp has symbols, Python does not. You can use strings, and this works sometimes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lambda.&lt;/strong&gt; Lisp has lambda, Python has an extremely limited version. Not being an expression language (see above) and the lack of scoping and block constructs in Python cripples its lambda.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source code available as a low-commitment data structure.&lt;/strong&gt; Lisp has this, Python does not. &amp;lsquo;Low-commitment&amp;rsquo; means that it is available before it has been decided what it means, but after it has been turned from a stream of characters into something more interesting. This matters because it makes macros possible: macros which work by transforming streams of characters are doomed to the sort of unspeakable horror of which &lt;a href="http://jinja.pocoo.org/"&gt;Jinja2&lt;/a&gt; is a good example, while macros which work after it has been decided what the code means then can&amp;rsquo;t make their &lt;em&gt;own&lt;/em&gt; decision about what it means, which is half the point of macros.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scoping.&lt;/strong&gt; Lisp has a multiplicity of scoping constructs and all modern Lisps have lexical scope, with some (Scheme) extending this to control constructs. Binding and assignment are irreparably confused in Python: scope does not work properly and this can never be fixed. A language which requires a &lt;code&gt;global&lt;/code&gt; declaration is not going to be fixed by adding &lt;code&gt;nonlocal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Macros.&lt;/strong&gt; Lisp has them, Python doesn&amp;rsquo;t. Since macros are &lt;em&gt;the point&lt;/em&gt; of Lisp, it is really hard to see how the above quote makes any kind of sense.&lt;/p&gt;

&lt;p&gt;There is a terrible truth about the percieved arrogance of Lisp hackers that it has taken me a long time to understand. The arrogance is justified: Lisp is, in fact, a better programming language.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2016-06-09-python-instead-of-lisp-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;In particular conses are not a useful universal data structure in the way that, perhaps, early Lisp people thought they were.&amp;nbsp;&lt;a href="#2016-06-09-python-instead-of-lisp-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Macros in Racket, part three: checking boolean operators</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2015/12/12/macros-in-racket-part-three/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2015-12-12-macros-in-racket-part-three</id>
  <published>2015-12-12T10:59:54Z</published>
  <updated>2015-12-12T10:59:54Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;I wanted to see if I could write a mildly complicated macro in &lt;a href="http://racket-lang.org/"&gt;Racket&lt;/a&gt; without becoming too confused. I can, although I am not sure it is terribly idiomatic.&lt;/p&gt;

&lt;p&gt;This is the third part of a series on writing macros in Racket for someone used to Common Lisp, although it is mostly independent of the previous parts. The previous parts are &lt;a href="../../../../2015/01/13/macros-in-racket-part-one/"&gt;part one&lt;/a&gt; &amp;amp; &lt;a href="../../../../2015/01/28/macros-in-racket-part-two"&gt;part two&lt;/a&gt;.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;One of the nice things about Lisp-family languages is that you can write your own control constructs, and it&amp;rsquo;s essentially easy to do so: if &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/when_unless.html#(form._((lib._racket/private/letstx-scheme..rkt)._when))" style="color: inherit"&gt;when&lt;/a&gt;&lt;/code&gt; did not exist then you could write it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax-rule (when test form ...)
  (and test
       (begin form ...)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This kind of extensibility is one of the wonders of Lisp and Scheme: it&amp;rsquo;s tempting to say that it makes them better than programming languages which can&amp;rsquo;t do this but that&amp;rsquo;s not correct: it makes them &lt;em&gt;incomparable&lt;/em&gt; to such languages: Lisp&lt;sup&gt;&lt;a href="#2015-12-12-macros-in-racket-part-three-footnote-1-definition" name="2015-12-12-macros-in-racket-part-three-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt; programs can reason about &lt;em&gt;themselves&lt;/em&gt; and often do&lt;sup&gt;&lt;a href="#2015-12-12-macros-in-racket-part-three-footnote-2-definition" name="2015-12-12-macros-in-racket-part-three-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;. Everything about Lisp really leads to this ability.&lt;/p&gt;

&lt;p&gt;When I taught (Common) Lisp to people one of the things I would try to get across was this ability of macros to extend the control constructs in the language: people often thought of macros as a way of essentially inlining code&lt;sup&gt;&lt;a href="#2015-12-12-macros-in-racket-part-three-footnote-3-definition" name="2015-12-12-macros-in-racket-part-three-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt;, but that&amp;rsquo;s not what they&amp;rsquo;re actually good for. If you can add control constructs to your language, then you can make a &lt;em&gt;new language&lt;/em&gt;, and &lt;em&gt;that&amp;rsquo;s&lt;/em&gt; what Lisp macros are about, and therefore what &lt;em&gt;Lisp&lt;/em&gt; is about.&lt;/p&gt;

&lt;p&gt;A good way to get this across to people is to pretend that Lisp doesn&amp;rsquo;t have some control construct, and write it as a macro. This is easier than inventing new control constructs both because it doesn&amp;rsquo;t require thinking of a domain where they might be useful and because the existing control constructs have clear semantics. Reimplementing existing control constructs also demonstrates how the language is already built up from a more primitive language by macros and how the approach to solving problems in Lisp is to &lt;em&gt;design and implement a language&lt;/em&gt; in which to talk about the problem, where that language is seamlessly built on the underlying Lisp, and can inherit all of its power and flexibiliy, &lt;em&gt;including the ability to extend the language&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;An advantage of reimplementing existing control constructs for teaching Lisp is that you can compare the new construct to the existing one, and with some small constraints you can do this exhaustively, so you can know whether you have actually implemented it right. This is, obviously, not possible in general, but if the operator has trivial syntax (so not &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket/private/letstx-scheme..rkt)._cond))" style="color: inherit"&gt;cond&lt;/a&gt;&lt;/code&gt;) and if you limit the arguments of the operator to booleans then you can enumerate all the possible arguments in the obvious way, and so long as it returns a result for all combinations of arguments (does not fail to halt in other words) and is deterministic then there are only two things you need to check:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;does the operator produce the same result for all combinations of arguments (\(2^n\) possibilities for \(n\) arguments) as the existing one?&lt;/li&gt;
 &lt;li&gt;does the operator evaluate its arguments the same number of times as the existing one for all these combinations?&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;So, for instance, &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/if.html#(form._((quote._~23~25kernel)._if))" style="color: inherit"&gt;if&lt;/a&gt;&lt;/code&gt; takes three arguments (in Racket) and should evaluate the first exactly once, and the others at most once, as well as returning the correct value.&lt;/p&gt;

&lt;p&gt;Obviously such a check is not a full check of the operator &amp;mdash; it does not tell you what it does with non-boolean arguments for instance. But I was interested in writing the check largely because it&amp;rsquo;s clearly a reasonably hairy macro which I know how to write in CL and wanted to see if I could write in Racket (I&amp;rsquo;m not very likely to teach people Lisp again).&lt;/p&gt;

&lt;h2 id="what-the-macro-needs-to-do"&gt;What the macro needs to do&lt;/h2&gt;

&lt;p&gt;The idea is that to compare two boolean operators &lt;code&gt;o1&lt;/code&gt; and &lt;code&gt;o2&lt;/code&gt; which take &lt;code&gt;n&lt;/code&gt; arguments you need to generate code which looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(for/and ([c (expt 2 n)])
  (let ([a1 (bitwise-bit-set? c 0)] ...)
    (let ([o1c1 0] ...)
      (let ([o2c1 0] ...)
        (and (eq? (o1 (begin (set! o1c1 (+ o1c1 1)) a1) ...)
                  (o2 (begin (set! o2c1 (+ o2c1 1)) a1) ...))
             (= o1c1 o2c1) ...)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So &lt;code&gt;a1&lt;/code&gt; is the first argument, &lt;code&gt;o1c1&lt;/code&gt; counts how many times &lt;code&gt;o1&lt;/code&gt; evaluates it, and &lt;code&gt;o2c1&lt;/code&gt; counts how many times &lt;code&gt;o2&lt;/code&gt; evaluates it, and so on. I decided to compare the operators with &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/Equality.html#(def._((quote._~23~25kernel)._eq~3f))" style="color: inherit"&gt;eq?&lt;/a&gt;&lt;/code&gt; rather than &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/Equality.html#(def._((quote._~23~25kernel)._eqv~3f))" style="color: inherit"&gt;eqv?&lt;/a&gt;&lt;/code&gt; for no very good reason except that it works for operators whose results are booleans, which is what I was interested in. I should almost certainly use &lt;code&gt;eqv?&lt;/code&gt; I think &amp;mdash; certainly the &lt;code&gt;-equivalent&lt;/code&gt; in the name would imply that &amp;mdash; but I&amp;rsquo;m not.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s clear that a loop like that checks all of the \(2^n\) possibilities for the arguments, where each argument can be either &lt;code&gt;#f&lt;/code&gt; or &lt;code&gt;#t&lt;/code&gt; only. So this does an exhaustive check of all the possibilities, and provided &lt;code&gt;o1&lt;/code&gt; and &lt;code&gt;o2&lt;/code&gt; are deterministic and halt on all their arguments it will tell you whether they are equivalent.&lt;/p&gt;

&lt;p&gt;And finally, this must be written as a macro, because the operators it is testing are themselves not generally functions: in particular things like &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/if.html#(form._((quote._~23~25kernel)._if))" style="color: inherit"&gt;if&lt;/a&gt;&lt;/code&gt; and &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket/private/letstx-scheme..rkt)._or))" style="color: inherit"&gt;or&lt;/a&gt;&lt;/code&gt; are obviously themselves not functions.&lt;/p&gt;

&lt;h2 id="things-i-did-not-know-how-to-do"&gt;Things I did not know how to do&lt;/h2&gt;

&lt;p&gt;The big thing I didn&amp;rsquo;t know how to do here was to make up new identifiers: all the counters need to be created, and possibly also the argument names. In CL you&amp;rsquo;d do this with &lt;code&gt;make-symbol&lt;/code&gt; or &lt;code&gt;gensym&lt;/code&gt; or something like that. Assuming I want to use &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._syntax-case))" style="color: inherit"&gt;syntax-case&lt;/a&gt;&lt;/code&gt; rather than writing a CL-style construct-the-form-with-backquote-and-use-&lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" style="color: inherit"&gt;datum-&amp;gt;syntax&lt;/a&gt;&lt;/code&gt; macro (which I very much do want to do) then there are two problems:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;constructing the names of the counters;&lt;/li&gt;
 &lt;li&gt;making them available as pattern variables.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Well, (2) is easy: you can use nested &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._syntax-case))" style="color: inherit"&gt;syntax-case&lt;/a&gt;&lt;/code&gt;s, or equivalently but much more prettily, &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._with-syntax))" style="color: inherit"&gt;with-syntax&lt;/a&gt;&lt;/code&gt; to bind the pattern variables. And it turns out that &lt;code&gt;with-syntax&lt;/code&gt; is willing to do a lot of work on your behalf: if you give it something which is not a syntax object it will massage it into one for you. So, in particular, this works:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(with-syntax ([(o1c ...) (list ...)])
  ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It takes the list it is given, turns it into a syntax object (with &lt;code&gt;datum-&amp;gt;syntax&lt;/code&gt; I suppose) and then does the matching. So you can be really lazy here: all you need to invent is a list of identifier syntax objects, and &lt;code&gt;with-syntax&lt;/code&gt; will do the rest, making the program a lot less noisy. This is a really neat feature, although it might lead you to get confused about what is, and what is not, a syntax object I suppose. Anyway, I used it ruthlessly.&lt;/p&gt;

&lt;p&gt;So this leaves (1). You could obviously do this with something like &lt;code&gt;(datum-&amp;gt;syntax ctx (string-&amp;gt;symbol (format ...)))&lt;/code&gt;, but Racket provides a nice shorthand for that in the form of &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket/syntax..rkt)._format-id))" style="color: inherit"&gt;format-id&lt;/a&gt;&lt;/code&gt;: &lt;code&gt;(format-id ctx "~a-count" v)&lt;/code&gt; will construct an identifier syntax object from &lt;code&gt;v&lt;/code&gt; using &lt;code&gt;ctx&lt;/code&gt; as lexical context. And it will do the appropriate magic if &lt;code&gt;v&lt;/code&gt; is an identifier syntax object: extract the symbol from it and use it as the argument to &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._format))" style="color: inherit"&gt;format&lt;/a&gt;&lt;/code&gt; in the appropriate way.&lt;/p&gt;

&lt;p&gt;So it looks pretty straightforward to construct lists of identifiers and bind them to pattern variables. The final thing that confuses me is what lexical context to use for the identifiers. The macro should be hygenic, which means they &lt;em&gt;can&amp;rsquo;t&lt;/em&gt; have the context of the syntax object it is working on, but I think can have more-or-less any other context where they have no existing meaning: I just invented an object for them, which I think is safe, although I am a bit confused about this.&lt;/p&gt;

&lt;h2 id="what-users-see"&gt;What users see&lt;/h2&gt;

&lt;p&gt;I spent a really long time stuck on what the syntax of the macro should be: this is entirely stupid because it just does not matter that much. The reason I got stuck is that it &lt;em&gt;would&lt;/em&gt; matter if this was a real library and I am constitutionally incapable of writing things without worrying about that kind of thing. Eventually I decided that it would be best if the user provided the argument names as a list, because they generally make sense to users and because I didn&amp;rsquo;t want to get into something which looked as if you could pass it an integer when in fact what it needs is a &lt;em&gt;literal&lt;/em&gt; integer. So I decided on a syntax like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(boolean-operators-equivalent? o1 o2 (a1 ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, for instance:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(boolean-operators-equivalent? if my-if (test then else))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I still don&amp;rsquo;t really like this; but I&amp;rsquo;m just playing so, well, it will do.&lt;/p&gt;

&lt;h2 id="additional-cleverness"&gt;Additional cleverness&lt;/h2&gt;

&lt;p&gt;I wanted to report syntax errors in a reasonable way: apparently the proper way to do this is using &lt;code&gt;&lt;a href="http://docs.racket-lang.org/syntax/Parsing_Syntax.html#(form._((lib._syntax/parse..rkt)._syntax-parse))" style="color: inherit"&gt;syntax-parse&lt;/a&gt;&lt;/code&gt; but I am not ready to understand that yet, so I used &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket/syntax..rkt)._wrong-syntax))" style="color: inherit"&gt;wrong-syntax&lt;/a&gt;&lt;/code&gt; and the &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket/syntax..rkt)._current-syntax-context))" style="color: inherit"&gt;current-syntax-context&lt;/a&gt;&lt;/code&gt; parameter to get reasonable-looking errors.&lt;/p&gt;

&lt;p&gt;I thought it would be nice to be able to report failures of equivalence, so there is a parameter which controls that and the expansion of the macro includes a check for the parameter and prints the failed cases if it&amp;rsquo;s true. All this happens at run time (phase 0) of course.&lt;/p&gt;

&lt;h2 id="the-macro-itself"&gt;The macro itself&lt;/h2&gt;

&lt;p&gt;So, finally, here it is.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require (for-syntax (only-in racket/syntax format-id
                              current-syntax-context wrong-syntax)))

(define boe-report-failure? (make-parameter #f))

(define-syntax (boolean-operators-equivalent? stx)
  ;; Given the names of two boolean operators and a list of argument
  ;; names, expand to a form which tests that they are equivalent, by
  ;; evaluating the with arguments bound to all the combinations of #t
  ;; and #f, and also checking that they evaluate the same arguments
  ;; in each case.
  ;;
  (parameterize ([current-syntax-context stx])
    (syntax-case stx ()
      [(_ o1 o2 (v ...))
       (let* ([vars (syntax-&amp;gt;list #'(v ...))]
              [nvars (length vars)])
         ;; This check could be a guard, but we need the bindings
         ;; anyway, so.
         (for ([var vars])
           (unless (identifier? var)
             (wrong-syntax var "not an identifier")))
         ;; vars is now a list of identifiers, and nvars is how many
         ;; there are.  We need to construct syntax for check
         ;; variables for each var and and operator, as well as
         ;; construct 2^n and a list of bit numbers.]  This is being
         ;; fairly fast and loose: it turns out that various things
         ;; get automagically converted into syntax objects, and I
         ;; have not cared about the context for numbers (what is
         ;; it?).  In general I am a bit confused about what the
         ;; context should be here, but it clearly should *not* be
         ;; stx.
         ;;
         (with-syntax ([(o1c ...) (for/list ([v vars])
                                    (format-id #'boe "~a-1-eval-count" v))]
                       [(o2c ...) (for/list ([v vars])
                                    (format-id #'boe "~a-2-eval-count" v))]
                       [2^n (expt 2 nvars)]
                       [(b ...) (for/list ([i nvars]) i)])
           ;; And now just write the pattern we want.  '...' is pretty
           ;; clever, it turns out
           #'(for/and ([c 2^n])
               (let ([v (bitwise-bit-set? c b)] ...)
                 (let ([o1c 0] ...)
                   (let ([o2c 0] ...)
                     (or (and (eq? (o1 (begin (set! o1c (+ o1c 1)) v) ...)
                                   (o2 (begin (set! o2c (+ o2c 1)) v) ...))
                              (= o1c o2c) ...)
                         (begin
                           (when (boe-report-failure?)
                             (eprintf "Not equivalent:~% ~a~% ~a~%"
                                      (list 'o1 `(,v ,o1c) ...)
                                      (list 'o2 `(,v ,o2c) ...)))
                           #f))))))))]
      [else
       (wrong-syntax #'else "expecting o1 o2 (a1 ...)")])))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To my astonishment, this worked pretty much first time (it did not initially have the &lt;code&gt;wrong-syntax&lt;/code&gt; stuff, but this was easy compared to the rest of it):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (define-syntax-rule (if/broken test then else)
    (or (and test then) else))
&amp;gt; (boe-report-failure? #t)
&amp;gt; (boolean-operators-equivalent? if if/broken (test then else))
Not equivalent:
 (if (#t 1) (#f 1) (#f 0))
 (if/broken (#t 1) (#f 1) (#f 1))
#f&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The macro, complete with some tests and other infrastructure can be found &lt;a href="https://gist.github.com/tfeb/3d535a2fc755e4ee5dfb"&gt;here&lt;/a&gt;&lt;sup&gt;&lt;a href="#2015-12-12-macros-in-racket-part-three-footnote-4-definition" name="2015-12-12-macros-in-racket-part-three-footnote-4-return"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h2 id="notes-and-queries"&gt;Notes and queries&lt;/h2&gt;

&lt;p&gt;I still don&amp;rsquo;t know whether this is really idiomatic Racket, although I am reasonably happy that I understand what is going on. There are a couple of things I am not sure about:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;is the context for the count variables right? I think it is, but I am not sure;&lt;/li&gt;
 &lt;li&gt;the macro relies heavily on Racket&amp;rsquo;s extremely smart behaviour with &lt;code&gt;...&lt;/code&gt; &amp;mdash; I am still unclear just &lt;em&gt;how&lt;/em&gt; smart this is and whether I am relying on things which are not actually specified to happen;&lt;/li&gt;
 &lt;li&gt;similarly it relies on &lt;code&gt;with-syntax&lt;/code&gt; being willing to convert things to syntax objects for you, which I am not sure is safe.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;However, even with these worries, I think it&amp;rsquo;s pretty clear that Racket macros are significantly nicer than CL macros, if also significantly more opaque.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class="footnotes"&gt;
 &lt;ol&gt;
  &lt;li id="2015-12-12-macros-in-racket-part-three-footnote-1-definition" class="footnote-definition"&gt;
   &lt;p&gt;I am going to use &amp;lsquo;Lisp&amp;rsquo; to mean &amp;lsquo;Lisp-family&amp;rsquo; from now on. This is not meant to denigrate Scheme &amp;mdash; this post is about Racket, after all &amp;mdash; I just need a term which is not too clumsy.&amp;nbsp;&lt;a href="#2015-12-12-macros-in-racket-part-three-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2015-12-12-macros-in-racket-part-three-footnote-2-definition" class="footnote-definition"&gt;
   &lt;p&gt;Of course, programs in other languages often do end up reasoning about themselves: people end up writing little languages all the time. But you only have to look at most examples of this sort of thing to realise how far ahead Lisp is: I&amp;rsquo;m currently having to deal with a system whose configuration files are in a mutant version of Windows ini file syntax, with a preprocessor which is entirely unaware of that syntax, and an entire other language which lives &lt;em&gt;in strings in the base language&lt;/em&gt;. The preprocessor does not know about the string syntax so it pokes down into this inner language as well. I&amp;rsquo;d like to say that &lt;a href="https://en.wikipedia.org/wiki/Greenspun's_tenth_rule"&gt;Greenspun&amp;rsquo;s tenth law&lt;/a&gt; applies, but that would imply a level of sophistication entirely missing in this horrible thing: all I want to do is leave this job and never think about it again.&amp;nbsp;&lt;a href="#2015-12-12-macros-in-racket-part-three-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2015-12-12-macros-in-racket-part-three-footnote-3-definition" class="footnote-definition"&gt;
   &lt;p&gt;Macros were often used to inline code in the days of primitive compilers of course, but that&amp;rsquo;s a long time ago now.&amp;nbsp;&lt;a href="#2015-12-12-macros-in-racket-part-three-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li id="2015-12-12-macros-in-racket-part-three-footnote-4-definition" class="footnote-definition"&gt;
   &lt;p&gt;I may move it somewhere more permanent in due course, so bookmark this at your peril.&amp;nbsp;&lt;a href="#2015-12-12-macros-in-racket-part-three-footnote-4-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content></entry>
 <entry>
  <title type="text">Greenspunning</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2015/10/08/greenspunning/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2015-10-08-greenspunning</id>
  <published>2015-10-08T15:16:56Z</published>
  <updated>2015-10-08T15:16:56Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Three approaches to solving problems on computers.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;When faced with a computational problem there are three common approaches:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;write a program to solve the problem;&lt;/li&gt;
 &lt;li&gt;write a tool to solve the problem and other problems of the same kind;&lt;/li&gt;
 &lt;li&gt;write a programming language in which you can then write tools which solve problems of the same, and other, kinds.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Most people start by doing the first. Bradshaw&amp;rsquo;s corollory to &lt;a href="https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule"&gt;Greenspun&amp;rsquo;s tenth law&lt;/a&gt; states:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;for problems of size \(s \ge s_1\), then, regardless of the initial approach, the final result is as if the third approach had been taken, even if this is not understood by the people solving the problem;&lt;/li&gt;
 &lt;li&gt;there is a problem size \(s_0\) above which it is most efficient to take the third approach from the beginning;&lt;/li&gt;
 &lt;li&gt;\(s_0 \lt s_1\).&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;What this means is that, if you have a sufficiently large problem (\(s \ge s_1\)) to solve then, whatever your intentions, you will inevitably end up creating a programming language as part of the solution. And there is a range of problems smaller than this (\(s \in (s_0, s_1)\)) for which the &lt;em&gt;quickest&lt;/em&gt; way to solve the problem is to design and implement a programming language.&lt;/p&gt;

&lt;p&gt;So, when approaching a problem, it is important to understand the values of \(s_0\) &amp;amp; \(s_1\) and how they compare to \(s\). These values are hard to discover: a good trick is to start with a platform which makes \(s_0\) very small and always take the third approach.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Rumours of my death</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2015/02/01/rumours-of-my-death/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2015-02-01-rumours-of-my-death</id>
  <published>2015-02-01T20:54:34Z</published>
  <updated>2015-02-01T20:54:34Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;When I first used Lisp, the common refrain was that Lisp was dead.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;There was a single free implementation of CL (which required you to physically sign a license of some kind and return it, in exchange for a tape) which was deficient in many respects. The two or three commercial implementations cost about a year&amp;rsquo;s salary each. Enormous effort had been spent on implementations which ran on special hardware. One variant of these cost more than your house: the other rather less, but turned out to have been implemented by the fey &amp;mdash; you seriously did not want to spend too much time with it if you did not want problems involving having your firstborn somehow changed into a strange and somehow &lt;em&gt;absent&lt;/em&gt; creature.&lt;/p&gt;

&lt;p&gt;(And there was a terrible, unspeakable truth about even the expensive hardware: the people who implemented it didn&amp;rsquo;t understand computer performance very well with the result you would expect. The systems were faster than a VAX, but &lt;em&gt;everything&lt;/em&gt; was faster than a VAX, including some PDP&amp;ndash;11s. A Sun 3/260 ate them alive, and you could buy several of those for the cost of a house, with bundled licenses.)&lt;/p&gt;

&lt;p&gt;Performance was pretty grim: of course nothing was fast on machines that, on a good day, could execute a few million instructions a second, but Lisp implementations were problematic at best. You spent a lot of time turning recursive code into iterative code by hand and writing macros (no inlining) to get performance to be reasonable and worrying about the primitive garbage collectors.&lt;/p&gt;

&lt;p&gt;There was no standard: existing implementations differed in basic details like error handling (not in the aluminium book) and a standard object system was a distant dream. The news from the standards committee was ominous: the special-hardware people were exerting pressure and there were serious worries that the object system would not be efficiently implementable on stock hardware. The language was going to be huge.&lt;/p&gt;

&lt;p&gt;Standard or semi-standard libraries were not really thought of.&lt;/p&gt;

&lt;p&gt;Everyone knew Lisp was dead: the coming thing was, perhaps, Scheme &amp;mdash; tail-call elimination &lt;em&gt;in the language&lt;/em&gt;, a small language (yet MIT Scheme somehow had a bigger footprint than the CLs we used) &amp;mdash; or C++ or some functional language whose name no-one now remembers. But Lisp was dead: no question about it.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Fast forward.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;I have two high-quality CL implementations on my machine and one Scheme-derived system, also of very high quality, which created this blog: I have long ago stopped counting the number of good-quality free implementations. One of the implementations I use is commercial: the annual support is about 10% of my monthly rent. I can run dozens of instances of each without the machine noticing, and I could happily run a full CL development system on a system less powerful and smaller than my phone. Performance is a solved problem: yes, highly-optimised code is, perhaps, slower than optimised C or Fortran but since almost all performance problems are design problems no-one older than about 19 cares any more. CL has an advanced, performant and standard object system and, in effect, a standard metaobject system as well. The library problem has been solved by Quicklisp and a large number of good-quality standard libraries. I am still using code I wrote over twenty-five years ago with essentially no modification: meanwhile the Python code I wrote ten years ago is long rendered obsolete by gratuitous changes in the language (the Perl code I wrote at the same time is doing fine, however).&lt;/p&gt;

&lt;p&gt;And yet still the cry goes up: Lisp is dead; Lisp is dead.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Macros in Racket, part two</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2015/01/28/macros-in-racket-part-two/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2015-01-28-macros-in-racket-part-two</id>
  <published>2015-01-28T19:31:18Z</published>
  <updated>2015-01-28T19:31:18Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;The second part of my notes on writing macros in Racket.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;This is the second part of at least three: the first part is &lt;a href="../../../../2015/01/13/macros-in-racket-part-one/"&gt;here&lt;/a&gt;, and the third part is &lt;a href="../../../../2015/12/12/macros-in-racket-part-three/"&gt;here&lt;/a&gt;. This won&amp;rsquo;t make much sense unless you&amp;rsquo;ve read that. As before I make no claims to be an expert in Racket&amp;rsquo;s macro system although I am familiar with Lisp macros in general: this is just some more notes I wrote while learning it.&lt;/p&gt;

&lt;h2 id="the-unwashed-lisp-hackers-version-of-collecting"&gt;The unwashed Lisp hacker&amp;rsquo;s version of &lt;code&gt;collecting&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;So, we can write &lt;code&gt;clet&lt;/code&gt;: can we write &lt;code&gt;collecting&lt;/code&gt;? Yes, we can:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require (for-syntax racket/list))

(define-syntax (collecting stx)
  (datum-&amp;gt;syntax
   (quote-syntax collecting)
   `(let ([r '()])
      (define (,(datum-&amp;gt;syntax stx 'collect) it)
        (set! r (cons it r)) it)
      ,@(rest (syntax-&amp;gt;list stx))
      (reverse r))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This works because, in the internal definition of &lt;code&gt;collect&lt;/code&gt;, we&amp;rsquo;ve intentionally given it a name which uses the context of the syntax object we&amp;rsquo;re transforming, not the context of the macro. It&amp;rsquo;s easy to confirm that this works the way you would expect, and in particular that it&amp;rsquo;s safe in both directions: for instance&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (let ((reverse (λ (x) x)))
    (collecting (collect 1) (collect 2)))
'(1 2)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;shows that the binding of &lt;code&gt;reverse&lt;/code&gt; when the macro is called has not &amp;lsquo;infected&amp;rsquo; the macro definition.&lt;/p&gt;

&lt;p&gt;It seems as if that should be all you need: so long as you are careful about which context you choose, and you make sure that the &amp;lsquo;default&amp;rsquo; context is the one from the macro not from where it is used. In fact it isn&amp;rsquo;t, quite: see &lt;a href="#macro-composition"&gt;below&lt;/a&gt;. However even if it were, it&amp;rsquo;s clearly a pain to write macros this way.&lt;/p&gt;

&lt;h2 id="pattern-matching"&gt;Pattern matching&lt;/h2&gt;

&lt;p&gt;Pretty much all macros do two things:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;deconstruct their arguments in some more-or-less complicated way, but almost always in a way which is significantly more complicated than anything that needs to be done for the arguments of a function;&lt;/li&gt;
 &lt;li&gt;construct a form which is the result of the macro and which, again, may be complicated.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;The beauty of traditional Lisp macros is that since the arguments and results of the macro were just what the reader spat out &amp;mdash; lists and symbols and so on &amp;mdash; and since Lisp was kind of good at doing things to these structures as it was designed for that, and finally since the whole power of the language was available in the macro, this was not horrible even without special tools, although it was not particularly pleasant for complicated macros.&lt;/p&gt;

&lt;p&gt;Hygienic macros make this much less pleasant because the objects that need to be deconstructed and constructed are now opaque syntax objects, and there is additional worrying about context to do. The answer to this is to provide special tools which do the boring bits for you: this makes everything simpler, at the cost of making it still more opaque what is actually happening. In almost all cases that&amp;rsquo;s a tradeoff worth making. Pattern matching is also a fashionable thing amongst the young and hip, of course.&lt;/p&gt;

&lt;p&gt;The way this is done in Racket is via &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._syntax-case))" style="color: inherit"&gt;syntax-case&lt;/a&gt;&lt;/code&gt;, its slightly simpler friend &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._syntax-rules))" style="color: inherit"&gt;syntax-rules&lt;/a&gt;&lt;/code&gt;, and by &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._syntax))" style="color: inherit"&gt;syntax&lt;/a&gt;&lt;/code&gt; and variants on it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._syntax-case))" style="color: inherit"&gt;syntax-case&lt;/a&gt;&lt;/code&gt; takes a bit of syntax and matches it against patterns, binding matches, which can then be used in &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._syntax))" style="color: inherit"&gt;syntax&lt;/a&gt;&lt;/code&gt; forms lexically within it to return syntax objects, whose context is that of the &lt;code&gt;syntax-case&lt;/code&gt; form (so hygienic). There is syntactic sugar for &lt;code&gt;syntax&lt;/code&gt;: &lt;code&gt;(syntax ...)&lt;/code&gt; can be written &lt;code&gt;#'...&lt;/code&gt; in the same way that &lt;code&gt;(quote ...)&lt;/code&gt; can be written &lt;code&gt;'...&lt;/code&gt;. There is also &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/qqstx..rkt)._quasisyntax))" style="color: inherit"&gt;quasisyntax&lt;/a&gt;&lt;/code&gt; which works the same way as &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/quasiquote.html#(form._((lib._racket/private/letstx-scheme..rkt)._quasiquote))" style="color: inherit"&gt;quasiquote&lt;/a&gt;&lt;/code&gt;, except that the various unquoting things are preceeded with &lt;code&gt;#&lt;/code&gt;. &lt;code&gt;quasisyntax&lt;/code&gt;, unsurprisingly also has syntactic sugar coating: &lt;code&gt;(quasisyntax ...)&lt;/code&gt; can be written &lt;code&gt;#`...&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m not going to describe the patterns in any detail, largely because I only understand the simple cases. However the simple cases are relatively easy to understand and pleasant to use.&lt;/p&gt;

&lt;p&gt;Once a case has matched in &lt;code&gt;syntax-case&lt;/code&gt; the corresponding expression is evaluated, and its value is the value of the form. Generally that wants to be a bit of syntax.&lt;/p&gt;

&lt;p&gt;The first important thing to understand is that &lt;code&gt;syntax&lt;/code&gt; is not &lt;code&gt;quote&lt;/code&gt;-for-syntax: it interpolates things which matched in a lexically surrounding &lt;code&gt;syntax-case&lt;/code&gt;, if there is one (if there isn&amp;rsquo;t, then I think it &lt;em&gt;is&lt;/em&gt; &lt;code&gt;quote&lt;/code&gt;-for-syntax).&lt;/p&gt;

&lt;p&gt;The second important thing to understand is that &lt;code&gt;syntax-case&lt;/code&gt; and &lt;code&gt;syntax&lt;/code&gt; turn Racket into a sort of bodged Lisp&amp;ndash;2: the things matched by &lt;code&gt;syntax-case&lt;/code&gt; can be used &lt;em&gt;only&lt;/em&gt; in &lt;code&gt;syntax&lt;/code&gt; forms. But it&amp;rsquo;s not actually a separate namespace, because if you refer to them outwith such a form you get a compile-time error. I don&amp;rsquo;t know why this is &amp;mdash; perhaps to avoid accidentally naming matches outside a &lt;code&gt;syntax&lt;/code&gt; form &amp;mdash; but it is certainly annoying.&lt;/p&gt;

&lt;p&gt;So, here are some examples.&lt;/p&gt;

&lt;p&gt;A simple &lt;code&gt;while&lt;/code&gt; form:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax (while stx)
  (syntax-case stx ()
    [(_ test body ...)
     #'(let loop ()
         (when test
           body ...
           (loop)))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A simple implementation of &lt;code&gt;let&lt;/code&gt;, leaving out the named-&lt;code&gt;let&lt;/code&gt; case, which shows how good the pattern matching is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax (with stx)
  (syntax-case stx ()
    [(_ ([var val] ...) body ...)
     #'((λ (var ...) body ...) val ...)]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A better implementation which deals with the empty body case (&lt;code&gt;(λ (...))&lt;/code&gt; is illegal in Racket) and also optimises a simple case:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax (with stx)
  (syntax-case stx ()
    [(_ () body ...)
     ;; no vars: trivial case
     #'(begin body ...)]
    [(_ ([var val] ...))
     ;; null body: make sure vars are evaluated
     #'(begin val ... (void))]
    [(_ ([var val] ...) body ...)
     #'((λ (var ...) body ...) val ...)]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One thing which &lt;code&gt;syntax-case&lt;/code&gt; allows is the notion of literal names which must occur in the source. So for instance let&amp;rsquo;s say I wanted to write some mutant &lt;code&gt;loop&lt;/code&gt; macro whose syntax was &lt;code&gt;(loop for x in y do ...)&lt;/code&gt;: where &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;in&lt;/code&gt;, &lt;code&gt;do&lt;/code&gt; are literals. Well, I can write something to match this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (define-syntax (loop stx)
    (syntax-case stx (for in do)
    [(_ for v in l do body ...)
     #'(for ([v (in-list l)]) body ...)]))
&amp;gt; (loop for x in '(1 2 3) do (print x))
123
&amp;gt; (loop with x in '(1 2 3) do (print x))
loop: bad syntax in: (loop with x in (quote (1 2 3)) do (print x))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The syntax object that corresponds to &lt;code&gt;stx&lt;/code&gt; here is the whole form: the equivalent to CL&amp;rsquo;s &lt;code&gt;&amp;amp;WHOLE&lt;/code&gt;. It&amp;rsquo;s almost never necessary to worry about the &lt;code&gt;car&lt;/code&gt; of this since it will obviously be &lt;code&gt;loop&lt;/code&gt;. However I&amp;rsquo;m always tempted to provide it as a literal.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._syntax-rules))" style="color: inherit"&gt;syntax-rules&lt;/a&gt;&lt;/code&gt; is (almost: there is some complexity I think) a wrapper around &lt;code&gt;syntax-case&lt;/code&gt; which provides the function wrapper for it and which implicitly wraps the right hand side of the cases, which must be just one form, in a &lt;code&gt;syntax&lt;/code&gt; form. So the above definition of &lt;code&gt;with&lt;/code&gt; could be written:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax with
  (syntax-rules ()
    [(_ () body ...)
     ;; no vars: trivial case
     (begin body ...)]
    [(_ ([var val] ...))
     ;; null body: make sure vars are evaluated
     (begin val ... (void))]
    [(_ ([var val] ...) body ...)
     ((λ (var ...) body ...) val ...)]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;syntax-rules&lt;/code&gt; can be defined something like this (this is due to &lt;a href="https://gist.github.com/tfeb/0b8531c94cf685824626"&gt;bmastenbrook&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require (for-syntax 
          (rename-in racket 
                     [syntax-rules racket:syntax-rules])))

(begin-for-syntax
  (define-syntax syntax-rules
    (racket:syntax-rules ()
      [(_ literals (pattern expansion) ...)
       (lambda (s)
         (syntax-case s literals
           (pattern #'expansion) ...))])))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/misc..rkt)._define-syntax-rule))" style="color: inherit"&gt;define-syntax-rule&lt;/a&gt;&lt;/code&gt; combines &lt;code&gt;define-syntax&lt;/code&gt; and a single rule for &lt;code&gt;syntax-rules&lt;/code&gt;. I &lt;em&gt;think&lt;/em&gt; it might be equivalent to this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax define-syntax-rule
  (syntax-rules ()
    [(_ (name pat ...) expansion)
     (define-syntax name
       (syntax-rules ()
         [(name pat ...) expansion]))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;although I am probably missing some complexity here.&lt;/p&gt;

&lt;p&gt;There is a useful variant on &lt;code&gt;syntax-case&lt;/code&gt; called &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._with-syntax))" style="color: inherit"&gt;with-syntax&lt;/a&gt;&lt;/code&gt;: it looks more like &lt;code&gt;let&lt;/code&gt;-style thing, and &lt;em&gt;all&lt;/em&gt; the patterns in the clauses must match, when all the pattern variables will be bound.&lt;/p&gt;

&lt;p&gt;So, what about our desirable macros?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;collect&lt;/code&gt; is pretty easy. Here are two different versions. The first uses &lt;code&gt;quasisyntax&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax (collecting stx)
  (syntax-case stx ()
    [(_) #'(void)]
    [(_ body ...)
     #`(let ([r '()])
         (define (#,(datum-&amp;gt;syntax stx 'collect) it)
           (set! r (cons it r)) it)
         body ...
         (reverse r))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The second uses &lt;code&gt;with-syntax&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax (collecting stx)
  (syntax-case stx ()
    [(_) #'(void)]
    [(_ body ...)
     (with-syntax ([collect (datum-&amp;gt;syntax stx 'collect)])
       #'(let ([r '()])
         (define (collect it)
           (set! r (cons it r)) it)
           body ...
           (reverse r)))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is pretty nice, I think. Note that you could not do this with &lt;code&gt;syntax-rules&lt;/code&gt;, or at least I can&amp;rsquo;t see how to do it: &lt;code&gt;syntax-rules&lt;/code&gt; is quite a lot less general than &lt;code&gt;syntax-case&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;clet&lt;/code&gt; is harder, because each element of the binding list may be either an identifier or a two-element list. If we insisted on a two-element list it would be easy (see above). Here is the best I can do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require racket/undefined)        

(define-syntax (clet stx)
  (syntax-case stx ()
    [(_ ()) #'(void)]
    [(_ () body ...) #'(begin body ...)]
    [(_ (b ...) body ...)
     (let-values ([(vars vals)
                   (for/lists (as vs) ([binding (syntax-&amp;gt;list #'(b ...))])
                     (syntax-case binding ()
                       [(var val) 
                        (identifier? #'var)
                        (values #'var #'val)]
                       [var
                        (identifier? #'var)
                        (values #'var #'undefined)]
                       [_ (raise-syntax-error #f "bad binding" stx)]))])
       #`((λ #,vars body ...) #,@vals))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, this is still quite hairy, but almost all of the hair involves processing the binding list, which is done using &lt;code&gt;syntax-case&lt;/code&gt; again, using an additional feature of it whereby it can use a &amp;lsquo;guard&amp;rsquo; expression to decide whether a clause matches: &lt;code&gt;identifer?&lt;/code&gt; returnt true if a syntax object refers to an identifier. I think there must be a way of using &lt;code&gt;with-syntax&lt;/code&gt; to avoid the &lt;code&gt;quasisyntax&lt;/code&gt; form.&lt;/p&gt;

&lt;p&gt;Even with all this hair, this version of &lt;code&gt;clet&lt;/code&gt; is far easier to read than the previous one, and not harder to read than the CL equivalent.&lt;/p&gt;

&lt;p&gt;A better version of &lt;code&gt;clet&lt;/code&gt; would, I think, need a proper parser for syntax. I think that is what &lt;code&gt;&lt;a href="http://docs.racket-lang.org/syntax/Parsing_Syntax.html#(form._((lib._syntax/parse..rkt)._syntax-parse))" style="color: inherit"&gt;syntax-parse&lt;/a&gt;&lt;/code&gt; is, although I have not investigated that.&lt;/p&gt;

&lt;h2 id="macro-composition"&gt;Macro composition&lt;/h2&gt;

&lt;p&gt;As mentioned above, we don&amp;rsquo;t yet have quite all the tools we need to write some kinds of macros: specifically macros which are intentionally slightly unygienic, such as &lt;code&gt;collecting&lt;/code&gt;. As an example, let&amp;rsquo;s suppose we wanted a general purpose, intentionally-unhygenic, &lt;code&gt;with-abort&lt;/code&gt; macro which provided an &lt;code&gt;abort&lt;/code&gt; function which would, well, abort. Without thinking too hard about the implications of &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/cont.html#(def._((lib._racket/private/more-scheme..rkt)._call/cc))" style="color: inherit"&gt;call/cc&lt;/a&gt;&lt;/code&gt; we could write this as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax (with-abort stx)
  (syntax-case stx ()
    [(_ body ...)
     #`(call/cc (λ (#,(datum-&amp;gt;syntax stx 'abort))
                  body ...))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So now &lt;code&gt;(with-abort (abort 2) (end-the-world))&lt;/code&gt; returns &lt;code&gt;2&lt;/code&gt; and does not end the world.&lt;/p&gt;

&lt;p&gt;Well, we might want to use this macro in another macro:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax-rule (while/abort test body ...)
  (with-abort
    (let loop ([r test])
      (when r
        body ...
        (loop test)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now something like the following will work:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (let ([x 0])
    (while/abort (&amp;lt; x 10) (set! x (+ x 1)) (print x)))
12345678910&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But the whole point was to be able to use &lt;code&gt;abort&lt;/code&gt; in the body, and that &lt;em&gt;doesn&amp;rsquo;t&lt;/em&gt; work:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (let ([x 0])
    (while/abort (&amp;lt; x 10) (set! x (+ x 1)) (when (&amp;gt; x 1) (abort 'done))))
abort: undefined;
 cannot reference an identifier before its definition&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Oh, dear. The problem here is that &lt;code&gt;while/abort&lt;/code&gt; is hygenic, so the &lt;code&gt;abort&lt;/code&gt; binding that is introduced by &lt;code&gt;with-abort&lt;/code&gt; is not visible in the body.&lt;/p&gt;

&lt;p&gt;We could fix this by better design:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax-rule (with-named-abort (abort) body ...)
  ;; a better macro
  (call/cc (λ (abort) body ...)))

(define-syntax (with-abort stx)
  ;; backwards compatible
  (syntax-case stx ()
    [(_ body ...)
     #`(with-abort (#,(datum-&amp;gt;syntax stx 'abort)) body ...)]))

(define-syntax (while/abort stx)
  ;; the end result
  (syntax-case stx ()
    [(_ test body ...)
     #`(with-named-abort (#,(datum-&amp;gt;syntax stx 'abort))
         (let loop ([r test])
           (when r
             body ...
             (loop test))))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But that&amp;rsquo;s not the solution we&amp;rsquo;re after.&lt;/p&gt;

&lt;p&gt;Racket&amp;rsquo;s answer to this is &lt;a href="http://www.schemeworkshop.org/2011/papers/Barzilay2011.pdf"&gt;syntax parameters&lt;/a&gt;. I don&amp;rsquo;t completely understand these, but they are at least close to dynamic variables, except at macro-expansion time. What you do is to define a syntax parameter, and then rebind it during the expansion: the rebound value is visible to macros which are expanded dynamically within the rebinding form. As with Racket&amp;rsquo;s &lt;a href="http://docs.racket-lang.org/guide/parameterize.html"&gt;ordinary special variables&lt;/a&gt; these look like functions (yet another namespace in disguise).&lt;/p&gt;

&lt;p&gt;So we can define a syntax parameter called &lt;code&gt;abort&lt;/code&gt; using &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stxparam.html#(form._((lib._racket/stxparam..rkt)._define-syntax-parameter))" style="color: inherit"&gt;define-syntax-parameter&lt;/a&gt;&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require racket/stxparam)

(define-syntax-parameter abort
  (λ (stx)
    (raise-syntax-error #f "not available" stx)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So now any reference to &lt;code&gt;abort&lt;/code&gt; will result in a syntax error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (abort)
abort: not available in: (abort)
&amp;gt; abort
abort: not available in: abort&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And we can now try to use &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stxparam.html#(form._((lib._racket/stxparam..rkt)._syntax-parameterize))" style="color: inherit"&gt;syntax-parameterize&lt;/a&gt;&lt;/code&gt;, to rebind &lt;code&gt;abort&lt;/code&gt; as a macro:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax with-abort
  (syntax-rules (with-abort)
    [(with-abort) (void)]
    [(with-abort body ...)
     (call/cc
      (λ (a)
        (syntax-parameterize ([abort
                               (syntax-rules ()
                                 [(_ ...) (a ...)])])
          body ...)))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this fails horribly, because the outer &lt;code&gt;syntax-rules&lt;/code&gt; thinks it owns the patterns and sees &lt;code&gt;...&lt;/code&gt;s that it does not expect. So much for that.&lt;/p&gt;

&lt;p&gt;Well, we could at least check this works with a specific number of arguments:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax with-abort
  (syntax-rules (with-abort)
    [(with-abort) (void)]
    [(with-abort body ...)
     (call/cc
      (λ (a)
        (syntax-parameterize ([abort
                               (λ (stx)
                                 (syntax-case stx (abort)
                                   [(abort) #'(a)]
                                   [(abort x) #'(a x)]
                                   [_ (raise-syntax-error #f "I give up" stx)]))])
          body ...)))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But this is obviously just a rubbish answer.&lt;/p&gt;

&lt;p&gt;Well, there is an answer to this: all we really need to do is to make the &lt;code&gt;abort&lt;/code&gt; macro attach itself to &lt;code&gt;a&lt;/code&gt;, and there is a special hack, &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stxtrans.html#(def._((quote._~23~25kernel)._make-rename-transformer))" style="color: inherit"&gt;make-rename-transformer&lt;/a&gt;&lt;/code&gt;, to do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax with-abort
  (syntax-rules (with-abort)
    [(with-abort) (begin)]
    [(with-abort body ...)
     (call/cc
      (λ (a)
        (syntax-parameterize ([abort (make-rename-transformer #'a)])
          body ...)))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this now works:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; (with-abort (abort 1 2 3))
     
1
2
3&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And we can use this to write a really robust version of &lt;code&gt;collecting&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require racket/stxparam)

(define-syntax-parameter collect
  (λ (stx)
    (raise-syntax-error #f "not collecting" stx)))

(define-syntax collecting
  (syntax-rules ()
    [(_) (void)]
    [(_ body ...)
     (let ([r '()])
       (define (clct it)
         (set! r (cons it r)) it)
       (syntax-parameterize ([collect (make-rename-transformer #'clct)])
         body ...
         (reverse r)))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As far as I can see there is still a problem, however: it is very hard to write macros which expand to other macros which themselves do pattern-matching, since the patterns get acquired by the outer macros. There must be some answer to this, but I can&amp;rsquo;t see what it is.&lt;/p&gt;

&lt;p&gt;On the other hand, this is also extremely painful in CL: here is a version of &lt;code&gt;collecting&lt;/code&gt; where &lt;code&gt;collect&lt;/code&gt; is a local macro:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defmacro collecting (&amp;amp;body forms)
  ;; collect lists forwards using a tail pointer
  ;; local macro version
  (let ((rn (make-symbol "R"))
        (rtn (make-symbol "RT"))
        (itn (make-symbol "IT")))
    `(let ((,rn '())
           (,rtn nil))
       (macrolet ((collect (form)
                    `(let ((,',itn ,form))
                       (if (not (null ,',rn))
                           (setf (cdr ,',rtn) (cons ,',itn nil)
                                 ,',rtn (cdr ,',rtn))
                         (setf ,',rn (cons ,',itn nil)
                               ,',rtn ,',rn))
                       ,',itn)))
         ,@forms)
       ,rn)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is not easy to understand.&lt;/p&gt;

&lt;p&gt;Additionally, the problem almost always comes from ellipses, and in many interesting cases they can be avoided by using dotted pairs as patterns &amp;mdash; here is yet another version of &lt;code&gt;with-abort&lt;/code&gt; that does this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require racket/stxparam)

(define-syntax-parameter abort
  (λ (stx)
    (raise-syntax-error #f "not available" stx)))

(define-syntax with-abort
  (syntax-rules (with-abort)
    [(with-abort) (void)]
    [(with-abort body ...)
     (call/ec
      (λ (a)
        (syntax-parameterize ([abort
                               (syntax-rules (abort)
                                 [(abort . args) (a . args)])])
                             

          body ...)))]))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is clearly better than the CL version.&lt;/p&gt;

&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;

&lt;p&gt;Well, I think I now know enough about Racket&amp;rsquo;s macros to be going on with: I can certainly write the macros I need to be able to write now without it just being cargo-cult programming. There are still things I don&amp;rsquo;t understand, and the whole system smells to me as if, by trying remain ideologically pure, it has become vast and essentially incomprehensible. This seems to be a common problem with Scheme, unfortunately.&lt;/p&gt;

&lt;h2 id="small-notes"&gt;Small notes&lt;/h2&gt;

&lt;p&gt;Macro definitions scope properly, so you can define a local macro the same way you can define a local function, so this works:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (foo ...)
  (define-syntax-rule (while test body ...)
    (let loop ()
      (when test
        body ...
        (loop))))
  ... (while ... ...) ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes the equivalent of CL&amp;rsquo;s &lt;code&gt;MACROLET&lt;/code&gt; easy to do.&lt;/p&gt;

&lt;p&gt;For fun, here is a version of &lt;code&gt;with&lt;/code&gt; which can deal with named-&lt;code&gt;let&lt;/code&gt;: There must be a way of implementing this without assignment, but I can never work out what it is.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax (with stx)
  (syntax-case stx ()
    [(_ ())
     ;; all null
     #'(void)]
    [(_ () body ...)
     ;; no vars: trivial case
     #'(begin body ...)]
    [(_ ([var val] ...))
     ;; null body: make sure vars are evaluated
     #'(begin val ... (void))]
    [(_ ([var val] ...) body ...)
     ;; normal let
     #'((λ (var ...) body ...) val ...)]
    [(_ n ())
     (identifier? #'n)
     ;; named null
     #'(void)]
    [(_ n ([var val] ...))
     (identifier? #'n)
     ;; named null body
     #'(begin val ... (void))]
    [(_ n ([var val] ...) body ...)
     ;; named let with arguments
     ;; (is there an implementation without assignment?
     (identifier? #'n)
     #'((λ (n)
          ((λ (l)
             (set! n l)
             (l val ...))
           (λ (var ...) body ...)))
        #f)]
    [_ (raise-syntax-error #f "bad syntax" stx)]))&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="things-i-still-do-not-know-or-understand"&gt;Things I still do not know or understand&lt;/h2&gt;

&lt;p&gt;At this point I&amp;rsquo;m mostly comfortable writing macros in Racket, but there are things I still do not understand:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;protecting and arming syntax objects &amp;mdash; I just don&amp;rsquo;t understand what this is about at all;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;&lt;a href="http://docs.racket-lang.org/syntax/Parsing_Syntax.html#(form._((lib._syntax/parse..rkt)._syntax-parse))" style="color: inherit"&gt;syntax-parse&lt;/a&gt;&lt;/code&gt; is, I think, not difficult but I have not bothered to learn about it as it seems to add yet another layer.&lt;/li&gt;
 &lt;li&gt;there are probably other things that I don&amp;rsquo;t even know I don&amp;rsquo;t know.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;At some point I might write a further part of this series on some of that.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id="pointers"&gt;Pointers&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.schemeworkshop.org/2011/papers/Barzilay2011.pdf"&gt;Eli Barilay&amp;rsquo;s paper on &lt;code&gt;syntax-parameterize&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.greghendershott.com/fear-of-macros/index.html"&gt;Fear of Macros&lt;/a&gt;, again.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">Macros in Racket, part one</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2015/01/13/macros-in-racket-part-one/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2015-01-13-macros-in-racket-part-one</id>
  <published>2015-01-13T14:45:48Z</published>
  <updated>2015-01-13T14:45:48Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;I&amp;rsquo;ve written in Lisp for a long time, but I&amp;rsquo;ve never used a hygienic macro system in any way other than the most simple. Here are some initial notes on my experiences learning &lt;a href="http://racket-lang.org/"&gt;Racket&lt;/a&gt;&amp;rsquo;s macro system.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;This is the first part of several: see &lt;a href="../../../../2015/01/28/macros-in-racket-part-two"&gt;part two&lt;/a&gt; and &lt;a href="../../../../2015/12/12/macros-in-racket-part-three/"&gt;part three&lt;/a&gt;. I&amp;rsquo;m not completely fluent with Racket macros yet: there are almost certainly mistakes and confusions here. Despite appearances, I also have no axe to grind: I&amp;rsquo;m learning Racket because I want to and I have time. Finally this is not a tutorial: look at Greg Hendershott&amp;rsquo;s &lt;a href="http://www.greghendershott.com/fear-of-macros/index.html"&gt;Fear of Macros&lt;/a&gt; for something closer to that. This is just some notes which were useful to me, and might be useful to other CL people.&lt;/p&gt;

&lt;h2 id="macros-in-common-lisp"&gt;Macros in Common Lisp&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.lispworks.com/documentation/common-lisp.html"&gt;Common Lisp&lt;/a&gt;&amp;rsquo;s macro system is, in essence, simple: it&amp;rsquo;s what you&amp;rsquo;d end up writing if you had to write a macro system for a Lisp. That&amp;rsquo;s not surprising because it &lt;em&gt;is&lt;/em&gt; the descendent of the first macro systems people wrote for Lisp. In CL what happens is this:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;the reader ingests the source text and produces data structures which represent the source of the program;&lt;/li&gt;
 &lt;li&gt;these structures are possibly transformed by macros, which are simply Lisp functions which are given the Lisp representation of the source and return some other representation;&lt;/li&gt;
 &lt;li&gt;once all macros are expanded, then the code is compiled, evaluated or both.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;(I have missed out some subtleties here, but they don&amp;rsquo;t matter for my purposes.)&lt;/p&gt;

&lt;p&gt;In CL, what the reader produces is exactly what you would expect. If it reads &lt;code&gt;"(defun foo (a) a)"&lt;/code&gt; then, with standard settings, it returns a list whose car is the symbol &lt;code&gt;DEFUN&lt;/code&gt; (in the &lt;code&gt;CL&lt;/code&gt; package) and so on. It is this structure that macros transform.&lt;/p&gt;

&lt;p&gt;CL provides relatively limited support for writing macros: there is backquote, which is critical to being able to write macros which are even slightly readable, limited pattern matching in the form of destructuring, and there are mechanisms to generate unique names as well a few other things. There is a semi-standard way of enquiring about bindings in the environment at macro expansion time, although this is not in the standard.&lt;/p&gt;

&lt;p&gt;In practice, CL&amp;rsquo;s macro system has turned out to work very well; in theory it has all sorts of problems, the most important being that the programmer is entirely responsible for making sure that macros don&amp;rsquo;t introduce or accidentally use names they should not. Consider this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defmacro collecting (&amp;amp;body forms)
  ;; collect lists forwards using a tail pointer
  ;; polluting version
  `(let ((r '())
         (rt nil))
     (flet ((collect (form)
              (if (not (null r))
                  (setf (cdr rt) (cons form nil)
                        rt (cdr rt))
                (setf r (cons form nil)
                      rt r))
              form))
       ,@forms)
     r))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This intentionally introduces a function binding, &lt;code&gt;collect&lt;/code&gt;, but also accidentally introduces bindings for &lt;code&gt;r&lt;/code&gt; and &lt;code&gt;rt&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(let ((r 2))
  (collecting
    (+ r r)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Does not do what it should. One right way to write the &lt;code&gt;collecting&lt;/code&gt; macro is like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defmacro collecting (&amp;amp;body forms)
  ;; collect lists forwards using a tail pointer
  ;; non-polluting version
  (let ((rn (make-symbol "R"))
        (rtn (make-symbol "RT")))
    `(let ((,rn '())
           (,rtn nil))
       (flet ((collect (form)
                (if (not (null ,rn))
                    (setf (cdr ,rtn) (cons form nil)
                          ,rtn (cdr ,rtn))
                  (setf ,rn (cons form nil)
                        ,rtn ,rn))
                form))
         ,@forms)
       ,rn)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now the above form does not signal an error and correctly returns &lt;code&gt;()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that the problem is with &lt;em&gt;names&lt;/em&gt; and not just bindings. Consider this CL code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defvar *stashes* '())
(defvar *mark* nil)
  
(defun stash (name thing)
  ;; Stash something under a name
  (setf *stashes* (acons name thing *stashes*))
  (values name thing))

(defun retrieve (name)
  ;; Retrieve the value of a name, dropping everything stashed more
  ;; recently, and stopping at the mark, if any.
  (let ((mark *mark*))
    (labels ((rl (tail)
               (if (or (null tail)
                       (eq (first tail) mark))
                   (values nil nil)
                 (destructuring-bind ((n . v) . r) tail
                   (if (eql n name)
                       (progn
                         (setf *stashes* r)
                         (values v t))
                     (rl r))))))
      (rl *stashes*))))

(defmacro with-marked-stash (&amp;amp;body forms)
  ;; mark the stack of stashes for the dynamic extent of FORMS
  (let ((mn (make-symbol "MARK")))
    `(let ((*stashes* (cons ',mn *stashes*))
           (*mark* ',mn))
       ,@forms)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this code the marks on the stack of stashes established by &lt;code&gt;with-marked-stash&lt;/code&gt; are not bound anywhere: they are just names. But it&amp;rsquo;s important to the correct functioning of the code that they are &lt;em&gt;unique&lt;/em&gt; names. (There are better ways of doing this such as using a fresh cons for the mark: I just wanted an example where a name mattered other than as the name of a variable.)&lt;/p&gt;

&lt;p&gt;The politically correct way of saying that we&amp;rsquo;re talking about names is to talk about &amp;lsquo;lexical context&amp;rsquo; or &amp;lsquo;lexical information&amp;rsquo;: it&amp;rsquo;s the same thing but more confusing to those not initiated into the cult, which is always good.&lt;/p&gt;

&lt;p&gt;The disadvantages of the CL macro system are this problem with hygiene and the lack of any clever tools to do pattern matching on macro forms. The second of these is easily overcome by using any of a number of tools, while the first is generally not a problem in practice: CL being a Lisp&amp;ndash;2 (separate namespaces for functions and variables) helps here.&lt;/p&gt;

&lt;p&gt;The advantage of the CL macro system is that there is no magic: macros get passed the things that the source code looks like &amp;mdash; generally a structure whose interesting parts are lists and symbols &amp;mdash; which you process using the normal list-processing tools to produce some other structure which is the expansion of the macro. It&amp;rsquo;s easy enough that you could write it yourself: there are no special opaque objects being handed around.&lt;/p&gt;

&lt;p&gt;That being said, having a &lt;em&gt;standard&lt;/em&gt; set of tools for pattern matching in macros and a way of dealing with the hygiene problems which is less ugly than in CL might well be worth the cost in transparency.&lt;/p&gt;

&lt;h2 id="macros-in-scheme"&gt;Macros in Scheme&lt;/h2&gt;

&lt;p&gt;I am not a native &lt;a href="https://en.wikipedia.org/wiki/Scheme_%28programming_language%29"&gt;Scheme&lt;/a&gt; person, but it has clearly taken the whole hygiene thing very seriously: Scheme, as a set of languages, treats purity as much more than CL, which revels in being a fairly grungy language, does. However these posts are not about Scheme: the only reason I am mentioning it is to say that I have not cared at all whether anything here applies generally to Scheme or is specific to Racket.&lt;/p&gt;

&lt;h2 id="macros-in-racket-baby-steps"&gt;Macros in Racket: baby steps&lt;/h2&gt;

&lt;p&gt;For a long time the only kind of macros that I&amp;rsquo;ve really been able to define in Racket are annoyingly trivial ones using &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/misc..rkt)._define-syntax-rule))" style="color: inherit"&gt;define-syntax-rule&lt;/a&gt;&lt;/code&gt;, things like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax-rule (while test body ...)
  (let loop ()
    (when test
      body ...
      (loop))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;rsquo;s all very well, but the &amp;lsquo;obvious&amp;rsquo; (and obviously wrong) definition of &lt;code&gt;collect&lt;/code&gt; then looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax-rule (collecting body ...)
  ;; horribly wrong	
  (let ([s '()])
    (define (collect it)
      (set! s (cons it s))
      it)
    body ...
    (reverse s)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(There&amp;rsquo;s no obvious way to build lists backwards in Racket: reversing the list is probably as cheap as anything). This is either introducing a spurious binding for &lt;code&gt;s&lt;/code&gt; or not introducing a deliberate one for &lt;code&gt;collect&lt;/code&gt;, and in fact, of course, it&amp;rsquo;s the latter.&lt;/p&gt;

&lt;p&gt;Quite apart from this, &lt;code&gt;define-syntax-rule&lt;/code&gt; gives the strong impression that it lets you write only the sort of macros that would give people who write C++ great pride: simple ones. (Actually you can do reasonably hairy things even with this because the pattern matching is very competent:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax-rule (mlet ([var val] ...) body ...)
  ((λ (var ...) body ...) val ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;is an implementation of simple &lt;code&gt;let&lt;/code&gt;, for instance. Indeed we can defined named &lt;code&gt;let&lt;/code&gt; as well:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define-syntax-rule (nlet label ([var val] ...) body ...)
  (mlet ()
    (define (label var ...) body ...)
    (label val ...)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What I &lt;em&gt;can&amp;rsquo;t&lt;/em&gt; work out how to do is to make &lt;code&gt;mlet&lt;/code&gt; do both things: I think this is too hard for &lt;code&gt;define-syntax-rule&lt;/code&gt; although I might be wrong.)&lt;/p&gt;

&lt;p&gt;But for a long time I was stuck with that: whenever I looked at Racket macros in more detail I walked into a wall of opaque terminology and just decided that I had better things to do that year. This year, I don&amp;rsquo;t.&lt;/p&gt;

&lt;h2 id="two-desirable-macros"&gt;Two desirable macros&lt;/h2&gt;

&lt;p&gt;There are many ways people use macros in Lisp: some of them are good. I decided that if I could write two macros &lt;em&gt;and understand them&lt;/em&gt; then I would be well on my way.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;collecting&lt;/code&gt; / &lt;code&gt;collect&lt;/code&gt;. This is the macro given above in CL. It&amp;rsquo;s interesting not for what it does &amp;mdash; the tail-pointer stuff is less interesting now than it once was and is hard to implement in Racket anyway &amp;mdash; but because it introduces a binding: it is intentionally not completely hygienic, while having an essentially trivial expansion: no complicated destructuring is needed.&lt;/li&gt;
 &lt;li&gt;CL&amp;rsquo;s &lt;code&gt;let&lt;/code&gt;, which I&amp;rsquo;ll call &lt;code&gt;clet&lt;/code&gt;. This is interesting because it requires destructuring of arguments which is not completely simple, but it does not present problems of hygiene. The reason it&amp;rsquo;s not just a subset of Racket&amp;rsquo;s &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/let.html#(form._((lib._racket/private/letstx-scheme..rkt)._let))" style="color: inherit"&gt;let&lt;/a&gt;&lt;/code&gt; is that CL allows variables with no initial value, which get bound to &lt;code&gt;nil&lt;/code&gt; and should, I think, become &lt;code&gt;undefined&lt;/code&gt; in Racket. So &lt;code&gt;(clet ((x 1) y) body ...)&lt;/code&gt; should expand to &lt;code&gt;(let ([x 1] [y undefined]) body ...)&lt;/code&gt; or something equivalent to that.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Here is a simple implementation of &lt;code&gt;clet&lt;/code&gt; in CL, missing any error checking:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defmacro clet (bindings &amp;amp;body forms)
  (multiple-value-bind (args vals)
      (loop for binding in bindings
            for consp = (consp binding)
            collect (if consp (first binding) binding) into as
            collect (if consp (second binding) nil) into vs
            finally (return (values as vs)))
    `((lambda (,@args) ,@forms) ,@vals)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Like most macros in CL it&amp;rsquo;s not particularly pretty but it is reasonably clear what it does.&lt;/p&gt;

&lt;p&gt;I will use these two macros as examples below.&lt;/p&gt;

&lt;h2 id="phases"&gt;Phases&lt;/h2&gt;

&lt;p&gt;To understand macros in any Lisp you need to develop a strong idea of the various &amp;lsquo;times&amp;rsquo; that things happen and the relationships between them: for CL these are things like read time, macro expansion time, compilation time (compiler-macro expansion time), load time, run time and so on. Racket has formalised the parts of this after read time into a notion of &amp;lsquo;phase&amp;rsquo;:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;phase 0 is run-time;&lt;/li&gt;
 &lt;li&gt;phase 1 is macro expansion time;&lt;/li&gt;
 &lt;li&gt;phase 2 would, I think, be macros used in macro expansion;&lt;/li&gt;
 &lt;li&gt;and so on.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;However I am not sure how this ties in to read time: is that phase 1? For CL read time is &lt;em&gt;before&lt;/em&gt; macro expansion time although the two are, or may be, interleaved at the granularity of forms (rather than a per-file or per-compilation-unit). Also there are negative phases which I don&amp;rsquo;t understand, although I think they must be to do with code which exists at macro expansion time (phase 1) wanting to make things available at run time (phase 0). All of this is integrated into the module system (and CL gets away without it mostly because it does not have a formalised module system).&lt;/p&gt;

&lt;p&gt;Bindings exist at a phase, and the same name can have different bindings at different phases.&lt;/p&gt;

&lt;p&gt;Modules can say what they &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/require.html#(form._((lib._racket/private/base..rkt)._provide))" style="color: inherit"&gt;provide&lt;/a&gt;&lt;/code&gt; at which phase, and, importantly, the &lt;code&gt;racket&lt;/code&gt; module does indeed provide different things at different phases: if you look at it you&amp;rsquo;ll find:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(provide ...
         (for-syntax (all-from-out racket/base)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which means that, at phase 1, what is available is &lt;code&gt;racket/base&lt;/code&gt;: a significantly smaller language than &lt;code&gt;racket&lt;/code&gt; itself. If you need things in macros which are in &lt;code&gt;racket&lt;/code&gt; but not &lt;code&gt;racket/base&lt;/code&gt; you need to &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/require.html#(form._((lib._racket/private/base..rkt)._require))" style="color: inherit"&gt;require&lt;/a&gt;&lt;/code&gt; them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require (for-syntax ...))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;An example of this is &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((lib._racket/list..rkt)._first))" style="color: inherit"&gt;first&lt;/a&gt;&lt;/code&gt; &amp;amp; &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((lib._racket/list..rkt)._rest))" style="color: inherit"&gt;rest&lt;/a&gt;&lt;/code&gt;, both of which are provided at phase 0 by &lt;code&gt;racket&lt;/code&gt; but &lt;em&gt;not&lt;/em&gt; at phase one: if you want them you need to say &lt;code&gt;(require (for-syntax racket/list))&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="syntax-objects"&gt;Syntax objects&lt;/h2&gt;

&lt;p&gt;As in CL, Racket macros are source-to-source functions. The difference is that in Racket the source is represented by a &lt;a href="http://docs.racket-lang.org/reference/syntax-model.html"&gt;syntax object&lt;/a&gt; and a macro needs to produce another syntax object, while in CL source is represented as it looks: usually as nested lists.&lt;/p&gt;

&lt;p&gt;So then a Racket macro is simply a function which maps from syntax objects to other syntax objects. The reason for having an opaque syntax object is that it can carry around all sorts of information around with it, and in particular it can carry information about &lt;em&gt;names&lt;/em&gt;, which help the system maintain hygiene. (There is also information about source location and so on, but this isn&amp;rsquo;t so important.)&lt;/p&gt;

&lt;p&gt;So the Racket macro system needs tools to transform syntax objects into other syntax objects, ultimately by digging around inside them to find out what the source code actually was. This is necessarily more complicated than it is in CL both because the objects are opaque and because they contain information which is not present at all in the objects CL macros get.&lt;/p&gt;

&lt;p&gt;Additionally, and mostly independently, there is a layer on top of this which does not exist in CL (without libraries) at all: pattern matching and template filling. This means that for many purposes you can write macros in Racket simply by specifying patterns that the source must match and filling templates with the results of those matches. This is a very nice way of writing macros, although it renders what is actually going on even more opaque. For a CL person, used to feeling the bits between their toes, this can be quite disconcerting at first since what is actually &lt;em&gt;happening&lt;/em&gt; can become entirely obscure.&lt;/p&gt;

&lt;h2 id="syntax-objects-for-the-unwashed-lisp-hacker"&gt;Syntax objects for the unwashed Lisp hacker&lt;/h2&gt;

&lt;p&gt;Well, of course it is possible to ignore all this terrifyingly modern pattern matching stuff and write macros almost the way you do in CL, and it&amp;rsquo;s worth doing that at least once, perhaps. So here is &lt;code&gt;clet&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require (for-syntax racket/list)
         racket/undefined)

(define-syntax clet
  (λ (stx)
    (define ctx (quote-syntax clet))
    (define top-level (syntax-&amp;gt;list stx))
    (define bindings (second top-level))
    (define body (rest (rest top-level)))
    (define-values (args vals)
      (for/lists (as vs) ([binding (syntax-&amp;gt;list bindings)])
        (define it (syntax-&amp;gt;list binding))
        (if it
            (values (first it) (second it))
            (values binding (datum-&amp;gt;syntax ctx 'undefined)))))
    (datum-&amp;gt;syntax 
     ctx
     `((λ (,@args) ,@body) ,@vals))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So how does this work? Well, it uses some functions provided by Racket to look inside the syntax object (getting the &amp;lsquo;datum&amp;rsquo; in the syntax object) and in turn to construct a new one:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3elist))" style="color: inherit"&gt;syntax-&amp;gt;list&lt;/a&gt;&lt;/code&gt; takes a syntax object which wraps a proper list and unpacks one level of it, returning a list of syntax objects, or &lt;code&gt;#f&lt;/code&gt; if it does not wrap a proper list;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" style="color: inherit"&gt;datum-&amp;gt;syntax&lt;/a&gt;&lt;/code&gt; takes a context object and a datum and wraps it into a syntax object, leaving any syntax objects in the datum as they are;&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/Syntax_Quoting__quote-syntax.html#(form._((quote._~23~25kernel)._quote-syntax))" style="color: inherit"&gt;quote-syntax&lt;/a&gt;&lt;/code&gt; is like &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" style="color: inherit"&gt;quote&lt;/a&gt;&lt;/code&gt; but it creates a syntax object, and this object contains the lexical information present in the source.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;So the macro pulls apart the syntax object in a fairly straightforward way: making it into a list, extracting the second element and all the remaining elements, which will be the binding specifications, and then grinding over the binding specifications, using &lt;code&gt;syntax-&amp;gt;list&lt;/code&gt; both to work out if the bindings are a list or not and to extract the variable and value if it is, and then reassembles everything as a call to an anonymous function.&lt;/p&gt;

&lt;p&gt;The critical trick is that the context that &lt;code&gt;datum-&amp;gt;syntax&lt;/code&gt; needs &lt;em&gt;is a syntax object&lt;/em&gt; and you need to pick the right one: you can use the syntax object you got given, which provides the context of the place where the macro was expanded, or you can use a syntax object of your own devising which provides that object&amp;rsquo;s context. And in this case we want our own context, not the context of place where the macro was expanded. This is what &lt;code&gt;ctx&lt;/code&gt; is for: providing a suitable context.&lt;/p&gt;

&lt;p&gt;Notice the &lt;code&gt;require&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;we need &lt;code&gt;racket/list&lt;/code&gt; at phase 1 (macro expansion time) because the macro uses &lt;code&gt;first&lt;/code&gt; and so on;&lt;/li&gt;
 &lt;li&gt;we need &lt;code&gt;racket/undefined&lt;/code&gt; at phase 0 (run time) as the expansion of the macro uses &lt;code&gt;undefined&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;So we can try this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(clet ((x 12) y) (values x y))
12
#&amp;lt;undefined&amp;gt;
&amp;gt; (let ((undefined 'hello)) (clet (x) x))
#&amp;lt;undefined&amp;gt;
&amp;gt; (clet ((undefined 'hello)) (clet (x) x))
#&amp;lt;undefined&amp;gt;
&amp;gt; (clet ((x 1)))
λ: bad syntax in: (λ (x))
&amp;gt; (clet (1) 1)
λ: not an identifier, identifier with default, or keyword in: 1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The second and third examples show why we need the macro context: we don&amp;rsquo;t want a binding of &lt;code&gt;undefined&lt;/code&gt; to alter what the &lt;code&gt;clet&lt;/code&gt; picks as the undefined value. The fourth and fifth examples show that the macro isn&amp;rsquo;t very robust, and has terrible error reporting.&lt;/p&gt;

&lt;p&gt;Some notes:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;I&amp;rsquo;ve deliberately written &lt;code&gt;(define-syntax clet (λ (stx) ...)&lt;/code&gt; rather than the more pleasant &lt;code&gt;(define-syntax (clet stx) ...)&lt;/code&gt; to make it clear that &lt;code&gt;clet&lt;/code&gt; is a function which transforms a syntax object;&lt;/li&gt;
 &lt;li&gt;but I&amp;rsquo;ve used internal &lt;code&gt;&lt;a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))" style="color: inherit"&gt;define&lt;/a&gt;&lt;/code&gt; where in CL there would be &lt;code&gt;let*&lt;/code&gt; or nested &lt;code&gt;let&lt;/code&gt;s &amp;mdash; I&amp;rsquo;m not sure why other than reducing indentation;&lt;/li&gt;
 &lt;li&gt;the destructuring of the syntax object is done in a way which is primitive even by the standards of CL;&lt;/li&gt;
 &lt;li&gt;it should be evident that the macro is not very robust &amp;mdash; something like &lt;code&gt;(clet ((x 1) 2) ...)&lt;/code&gt; will fail horribly;&lt;/li&gt;
 &lt;li&gt;it&amp;rsquo;s not &lt;em&gt;much&lt;/em&gt; less clear than the CL version, although I think it is a bit less clear.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;I am fairly but not completely sure that this macro is right: I am slightly confused by the handling of &lt;code&gt;undefined&lt;/code&gt;: although it is easy to check, by wrapping &lt;code&gt;clet&lt;/code&gt; into a module, that clients of that module don&amp;rsquo;t themselves need to import &lt;code&gt;racket/undefined&lt;/code&gt; and do get the right initial values in forms like &lt;code&gt;(clet (x) ...)&lt;/code&gt; I am still a bit queasy about what it&amp;rsquo;s doing.&lt;/p&gt;

&lt;p&gt;What is very clear is that this macro is just horrible: even by the standards of CL macros it&amp;rsquo;s horrible, because there is so much explcit unpacking and repacking going on. Things would be even worse if there was any significant error checking. Something better than this is needed to deal with syntax objects, in a way that it isn&amp;rsquo;t needed for CL macros. In &lt;a href="../../../../2015/01/28/macros-in-racket-part-two"&gt;next week&amp;rsquo;s exciting episode&lt;/a&gt; I&amp;rsquo;ll look at ways of making this better.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id="pointers"&gt;Pointers&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://blog.racket-lang.org/2011/04/writing-syntax-case-macros.html"&gt;Writing &amp;lsquo;syntax-case&amp;rsquo; Macros&lt;/a&gt; by Eli Barzilay. This was the article that first helped me understand what was going on.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.greghendershott.com/fear-of-macros/index.html"&gt;Fear of Macros&lt;/a&gt; by Greg Greg Hendershott. This is an introduction to macros, and macros in Racket in particular, by the author of Frog.&lt;/p&gt;</content></entry>
 <entry>
  <title type="text">The cult of programming</title>
  <link rel="alternate" href="https://www.tfeb.org/fragments/2015/01/05/the-cult-of-programming/?utm_source=lisp&amp;utm_medium=Atom" />
  <id>urn:https-www-tfeb-org:-fragments-2015-01-05-the-cult-of-programming</id>
  <published>2015-01-05T19:24:26Z</published>
  <updated>2015-01-05T19:24:26Z</updated>
  <author>
   <name>Tim Bradshaw</name></author>
  <content type="html">
&lt;p&gt;Programming is &lt;em&gt;not meant to be easy&lt;/em&gt; and it&amp;rsquo;s important to make sure that it is as cryptic as possible otherwise people other than cult members might be able to understand it. Of course, you also need to make sure it&amp;rsquo;s &lt;em&gt;pure&lt;/em&gt;, because otherwise cult members will laughingly throw you into a pit full of spikes and the rotting remains of other heretics.&lt;/p&gt;
&lt;!-- more--&gt;

&lt;p&gt;For instance, you can&amp;rsquo;t be writing this sort of thing:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun ss (n)
  (let ((s 0) (i 0))
    (tagbody
     loop
     (when (&amp;gt; i n) (go done))
     (setf s (+ s (* i i))
           i (+ i 1))
     (go loop)
     done
     (return-from ss s))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is just terrible code. Non cult members may well be able to understand it, and the cultists will have you in the pit before you know it.&lt;/p&gt;

&lt;p&gt;You might think this was better&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun ss (n)
  (loop for i from 0 to n
    summing (* i i)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But in fact it&amp;rsquo;s far worse. Fellow cultists will definitely still be at the laughing and pit-throwing, and the others will certainly understand it &lt;em&gt;and laugh at you&lt;/em&gt; because you don&amp;rsquo;t know the closed form.&lt;/p&gt;

&lt;p&gt;Instead, you must write this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define (ss n)
  (let-values ([(a i l) (call/cc (λ (c) (values 0 0 c)))])
    (l (+ a (* i i))
       (+ i 1)
       (if (&amp;lt; i (- n 1))
           l
           (λ (a i l) a)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is almost a perfect solution. It&amp;rsquo;s so achingly pure and cryptic that you will be immediately appointed king of the cult and be able to do your own laughing, and throw other members into pits you have first made them dig, for which they will thank you as they slide down the spikes. Non cult members stand essentially no chance of understanding what it does and sniping about the whole silly closed-form thing: certainly the only way they will be able to learn what it does is by first joining the cult, at which point, as king, you can just throw them straight into the pit.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s important you understand this.&lt;/p&gt;</content></entry></feed>