<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>
            
                    lisp on
                
            
            The Neo-Babbage Files</title>
        <link>https://babbagefiles.xyz/categories/lisp/</link>
        <description>Recent content  in lisp
            on The Neo-Babbage Files</description>
        <language>en-gb</language>
        
                <managingEditor>slade@lambda-y.net (Benjamin Slade)</managingEditor>
                <webMaster>slade@lambda-y.net (Benjamin Slade)</webMaster><lastBuildDate>Mon, 29 Dec 2025 11:00:32 +0000</lastBuildDate>
        <generator>Hugo -- gohugo.io</generator>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
            <atom:link href="https://babbagefiles.xyz/categories/lisp/index.xml" rel="self" type="application/rss&#43;xml" />
        
            
            <item>
                <title>Lambda Calculus and Lisp, part 2 (recursion excursion)</title>
                <link>https://babbagefiles.xyz/lambda-calculus-and-lisp-02-recursion/</link>
                
                
                <description>&lt;p&gt;From the &lt;a href=&#34;https://babbagefiles.xyz/lambda-calculus-and-lisp-01/&#34;&gt;previous entry in this series&lt;/a&gt;, one of the things of note in
discussing the nature of the connections between LISP and (the) lambda
calculus was John McCarthy&amp;rsquo;s concern about recursion and higher-order
functions.&lt;/p&gt;
&lt;p&gt;A couple of excerpts from previous quotes from McCarthy on the subject
to set the stage:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…And so, the way in which to [be able to handle function passing/higher
order functions] was to borrow from Church&amp;rsquo;s Lambda Calculus, to
borrow the lambda definition. Now, having borrowed this notation, one
the myths concerning LISP that people think up or invent for
themselves becomes apparent, and that is that LISP is somehow a
realization of the lambda calculus, or that was the intention. The
truth is that I didn&amp;rsquo;t understand the lambda calculus, really. In
particular, I didn&amp;rsquo;t understand that you really could do conditional
expressions in &lt;strong&gt;recursion&lt;/strong&gt; in some sense in the pure lambda calculus.…&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[McCarthy 1978a:190&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!--quoteend--&gt;
&lt;blockquote&gt;
&lt;p&gt;…Writing &lt;code&gt;eval&lt;/code&gt; required inventing a notation representing LISP
functions as LISP data, and such a notation was devised for the
purposes of the paper with no thought that it would be used to express
LISP programs in practice. Logical completeness required that the
notation used to express functions used as functional arguments be
extended to provide for recursive functions, and the &lt;code&gt;LABEL&lt;/code&gt; notation
was invented by Nathaniel Rochester for that purpose. D.M.R. Park
pointed out that &lt;code&gt;LABEL&lt;/code&gt; was logically unnecessary since the result
could be achieved using only &lt;code&gt;LAMBDA&lt;/code&gt; — by a construction analogous to
Church&amp;rsquo;s &lt;em&gt;Y&lt;/em&gt;-operator, albeit in a more complicated way.…&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[McCarthy 1978a:179&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Examining Church&amp;rsquo;s Y Combinator will be something we return to
(probably in a number of posts), but I&amp;rsquo;ll defer discussion of it for
the moment.&lt;/p&gt;
&lt;p&gt;For now, let&amp;rsquo;s consider recursion in lisps. We&amp;rsquo;ll be talking a lot of
recursion in Emacs Lisp today in fact.&lt;/p&gt;
&lt;h2 id=&#34;self-reference-self-embedding&#34;&gt;Self-reference, self-embedding&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Recursion&lt;/strong&gt; is a concept or process depends on a simpler or previous
version of itself. It&amp;rsquo;s ubiquitous, including in the natural world:
Wikipedia &lt;a href=&#34;https://en.wikipedia.org/wiki/Recursion#In_biology&#34;&gt;notes&lt;/a&gt; that &amp;ldquo;Shapes that seem to have been created by
recursive processes sometimes appear in plants and animals, such as in
branching structures in which one large part branches out into two or
more similar smaller parts. One example is Romanesco broccoli.&amp;rdquo;&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/Romanesco_broccoli_%28Brassica_oleracea%29.jpg&#34; alt=&#34;Figure 1: Romanesco broccoli (Brassica oleracea), from Wikipedia&#34;/&gt; &lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 1: &lt;/span&gt;Romanesco broccoli (Brassica oleracea), from &lt;a href=&#34;Romanesco broccoli (Brassica oleracea)&#34;&gt;Wikipedia&lt;/a&gt;
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Recursion is a thing I deal with a lot in my day job, as it is a
feature of natural language, especially syntax and semantics. To
provide a quick illustration — though this is not at all how modern
generative syntax is done anymore — consider &lt;a href=&#34;https://en.wikipedia.org/wiki/Phrase_structure_grammar&#34;&gt;phrase structure grammar&lt;/a&gt;
and &lt;a href=&#34;https://en.wikipedia.org/wiki/Phrase_structure_rules&#34;&gt;phrase structure rules&lt;/a&gt; used by &lt;a href=&#34;https://en.wikipedia.org/wiki/Noam_Chomsky&#34;&gt;Noam Chomsky&lt;/a&gt; and his colleagues in
the 1950s.&lt;/p&gt;
&lt;p&gt;Sentences (and linguistics objects generally) have formal structure,
and it is part of the productive/creative nature of language that we
might envision this structure as involving abstract structure rules
that can be expanded in different ways (and then have vocabulary
filled in).&lt;/p&gt;
&lt;p&gt;A phrase structure rule will generally have the form &lt;code&gt;A → [B C]&lt;/code&gt;,
indicating that &lt;code&gt;A&lt;/code&gt; may be rewritten or expanded into &lt;code&gt;[B C]&lt;/code&gt;. (In the
following, I&amp;rsquo;ll use round brackets &lt;code&gt;()&lt;/code&gt;&#39;s to denote optional
constituents.)&lt;/p&gt;
&lt;p&gt;So, a subset of these rules for English might include something like
(note that some things have multiple rules that can apply to them):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-prolog&#34; data-lang=&#34;prolog&#34;&gt;&lt;span class=&#34;mf&#34;&gt;1.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;S&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;NP&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt;
&lt;span class=&#34;mf&#34;&gt;2.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;NP&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;Det&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt;
&lt;span class=&#34;mf&#34;&gt;3.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;AdjP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt;
&lt;span class=&#34;mf&#34;&gt;4.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt;
&lt;span class=&#34;mf&#34;&gt;5.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;NP&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;NP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;mf&#34;&gt;6.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CP&lt;/span&gt;
&lt;span class=&#34;mf&#34;&gt;7.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CP&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;S&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 1:&lt;/span&gt;
  a snippet of phrase structure grammar rules for English [Nb.: again, not prolog, but maybe the best fontlocking choice here]
&lt;/div&gt;
&lt;p&gt;(Where &lt;code&gt;S&lt;/code&gt; is &amp;ldquo;sentence&amp;rdquo;; &lt;code&gt;Det&lt;/code&gt; is a determiner (like &amp;ldquo;the&amp;rdquo;, &amp;ldquo;a&amp;rdquo;); &lt;code&gt;NP&lt;/code&gt; is a
noun phrase; &lt;code&gt;Nₙ&lt;/code&gt; is a noun head; &lt;code&gt;AdjP&lt;/code&gt; is an adjective phrase; &lt;code&gt;VP&lt;/code&gt; is
a verb phrase; &lt;code&gt;V&lt;/code&gt; is a verb head; &lt;code&gt;CP&lt;/code&gt; is a complementiser phrase; &lt;code&gt;Comp&lt;/code&gt;
is a complementiser (like &amp;ldquo;that&amp;rdquo;).)&lt;/p&gt;
&lt;p&gt;So we can rewrite &lt;code&gt;S&lt;/code&gt; as &lt;code&gt;NP VP&lt;/code&gt; (1) and then rewrite &lt;code&gt;NP VP&lt;/code&gt; as &lt;code&gt;Det N VP&lt;/code&gt;
(2, choosing an optional &lt;code&gt;Det&lt;/code&gt;) and then &lt;code&gt;Det N VP&lt;/code&gt; as &lt;code&gt;Det N V&lt;/code&gt; (4) and then
insert lexical items of the appropriate category into the &amp;lsquo;heads&amp;rsquo; (the
non-&lt;code&gt;P&lt;/code&gt; elements). So we might choose &amp;ldquo;the&amp;rdquo; for &lt;code&gt;Det&lt;/code&gt; and &amp;ldquo;cat&amp;rdquo; for &lt;code&gt;N&lt;/code&gt; and
&amp;ldquo;purrs&amp;rdquo; for &lt;code&gt;V&lt;/code&gt;, and get the sentence &amp;ldquo;the cat purrs&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;But note that some of the rules allow for expansion into elements that
contain expansions back into themselves. So rule (1) allows an &lt;code&gt;S&lt;/code&gt; to
exapnd into &lt;code&gt;NP VP&lt;/code&gt; and rule (6) allows for a &lt;code&gt;VP&lt;/code&gt; to expand into &lt;code&gt;V CP&lt;/code&gt; and rule
(7) allows for a &lt;code&gt;CP&lt;/code&gt; to expand into an &lt;code&gt;S&lt;/code&gt;. At which point we can apply
rule (1) again to expand the new &lt;code&gt;S&lt;/code&gt; into &lt;code&gt;NP VP&lt;/code&gt;, and then repeat this
process as many times as we like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-prolog&#34; data-lang=&#34;prolog&#34;&gt;&lt;span class=&#34;nv&#34;&gt;S&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;NP&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;S&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;NP&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;S&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;NP&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;S&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;NP&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CP&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;S&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;V&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Comp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;NP&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VP&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 2:&lt;/span&gt;
  a recursive English sentence expansion [Nb.: again, not prolog, but maybe the best fontlocking choice here]
&lt;/div&gt;
&lt;p&gt;And it&amp;rsquo;s easy to imagine examples of what such a sentence could be
like, e.g., &amp;ldquo;John said that Sita said that Bill said that Mary said
that Ram said that Kim said that&amp;hellip;&amp;quot;. It won&amp;rsquo;t be infinitely long, but
there&amp;rsquo;s no particular theoretical bound on how long it could be
(memory processing and finite human lifespans will impose practical
limits, of course).&lt;/p&gt;
&lt;p&gt;On the formal semantics side, things are similar: consider that
logical languages too (which are often used to formalise natural
language semantics) allow for recursion. &lt;a href=&#34;https://en.wikipedia.org/wiki/Propositional_calculus&#34;&gt;Propositional logic&lt;/a&gt;
construction with Boolean operators too have no theoretical upper
limits: we can write &lt;code&gt;(t ↔ (p ∧ (q ∨ (r → (s ∧ ¬¬¬¬¬¬t)))))&lt;/code&gt;,&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; and
there&amp;rsquo;s nothing which prevents composing this bit of formalism with
yet another bit, and so on.&lt;/p&gt;
&lt;p&gt;And in mathematics and computer science, recursion is often a thing
which suggests itself.&lt;/p&gt;
&lt;p&gt;For instance, though there are other ways of calculating it, the
Fibonacci sequence&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, i.e., a sequence of numbers in which each
element is the sum of the two elements that precede it (e.g. &lt;code&gt;0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144…&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;A natural way of writing an equation to calculate these is something
like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Fib(0) = 0 as base case 1.&lt;/li&gt;
&lt;li&gt;Fib(1) = 1 as base case 2.&lt;/li&gt;
&lt;li&gt;For all integers &lt;em&gt;n&lt;/em&gt; &amp;gt; 1, Fib(&lt;em&gt;n&lt;/em&gt;) = Fib(&lt;em&gt;n&lt;/em&gt; − 1) + Fib(&lt;em&gt;n&lt;/em&gt; − 2).&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;Rule 3 makes reference to itself. I.e., in order (by this method) to
calculate &lt;code&gt;Fib(6)&lt;/code&gt;, you have to calculate &lt;code&gt;Fib(5)&lt;/code&gt;, for which you have to
calculate &lt;code&gt;Fib(4))&lt;/code&gt;, for which you have to calculate &lt;code&gt;Fib(3)&lt;/code&gt;, for which
you have to calculate &lt;code&gt;Fib(2)&lt;/code&gt;, which you can then base on rules (1) &amp;amp;
(2): you can add &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; (= &lt;code&gt;Fib(0)&lt;/code&gt; and &lt;code&gt;Fib(1))&lt;/code&gt; together to get &lt;code&gt;Fib(2)&lt;/code&gt;,
and then you can calculate &lt;code&gt;Fib(3)&lt;/code&gt; by adding &lt;code&gt;Fib(1)&lt;/code&gt; and &lt;code&gt;Fib(2)&lt;/code&gt; and so on.&lt;/p&gt;
&lt;h2 id=&#34;cursed-recursion&#34;&gt;Cursed recursion&lt;/h2&gt;
&lt;p&gt;In early Lisp(s), despite the concern around recursion, writing
recursive functions was/is not always pragmatically viable, because it
can lead to stack overflows (potential infinities are hard in
practice).&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Scheme_(programming_language)&#34;&gt;Scheme&lt;/a&gt;, a Lisp dialect originally created at MIT by &lt;a href=&#34;https://en.wikipedia.org/wiki/Guy_L._Steele&#34;&gt;Guy L. Steele, Jr.&lt;/a&gt;
and &lt;a href=&#34;https://en.wikipedia.org/wiki/Gerald_Jay_Sussman&#34;&gt;Gerald Jay Sussman&lt;/a&gt;, was the first Lisp to implement tail call
optimisation, which is a way of making significantly recursive
functions viable, making tail calls similar in memory requirement to
their equivalent loops.&lt;/p&gt;
&lt;p&gt;Before talking (a little bit more) about tail recursion, let&amp;rsquo;s look at
concrete examples of a tail recursive function and its loop
equivalent. We&amp;rsquo;ve mentioned Fibonacci numbers already, so let&amp;rsquo;s try to
write functions calculate these (in Emacs Lisp).&lt;/p&gt;
&lt;p&gt;Following the mathematical abstraction for the Fibonacci sequence
above, we could write a function like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; -*- lexical-binding: t; -*-&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Calculate the first &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; Fibonacci numbers, recursively.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;1-&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 3:&lt;/span&gt;
  a first go at a recursive elisp function for fibonacci numbers
&lt;/div&gt;
&lt;p&gt;I&amp;rsquo;ve tried to make this as simple as possible, we could make it nicer
(say, with a wrapper function or some some of &lt;code&gt;flet&lt;/code&gt;) so that we didn&amp;rsquo;t
have to pass in the initial values. But, keeping it simple (for now):
&lt;code&gt;fib1&lt;/code&gt; is a function taking three arguments: &lt;code&gt;n&lt;/code&gt;, the quantity of
Fibonacci numbers to return; &lt;code&gt;a&lt;/code&gt;, the first number to start with; and &lt;code&gt;b&lt;/code&gt;,
the second number to start with.&lt;/p&gt;
&lt;p&gt;Following the schema above, we&amp;rsquo;re going to pass &lt;code&gt;0&lt;/code&gt; for &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; for
&lt;code&gt;b&lt;/code&gt;. Let&amp;rsquo;s get the first ten numbers of the sequence, and pass &lt;code&gt;10&lt;/code&gt; for &lt;code&gt;n&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; (0 1 1 2 3 5 8 13 21 34 . 55)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I know, the output is a bit ugly because we&amp;rsquo;re just cons&amp;rsquo;ing the
results and so it&amp;rsquo;s not a proper list, but we&amp;rsquo;re keeping things
simple.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s walk through how it works. The function first looks at &lt;code&gt;n&lt;/code&gt;, if &lt;code&gt;n&lt;/code&gt;
is less than &lt;code&gt;1&lt;/code&gt;, it returns &lt;code&gt;a&lt;/code&gt; (whatever it is). If &lt;code&gt;n&lt;/code&gt; isn&amp;rsquo;t less than &lt;code&gt;1&lt;/code&gt;,
we return the &lt;code&gt;cons&lt;/code&gt; of &lt;code&gt;a&lt;/code&gt; with the result of calling &lt;code&gt;fib1&lt;/code&gt; itself on &amp;ldquo;&lt;code&gt;n&lt;/code&gt;
minus 1&amp;rdquo; &lt;code&gt;b&lt;/code&gt; and &amp;ldquo;&lt;code&gt;a&lt;/code&gt; plus &lt;code&gt;b&lt;/code&gt;&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;So if we start with &lt;code&gt;n=3&lt;/code&gt;, &lt;code&gt;a=0&lt;/code&gt;, &lt;code&gt;b=1&lt;/code&gt;, that is, evaluate &lt;code&gt;(fib1 3 0 1)&lt;/code&gt;, the
function would say, well, 3 isn&amp;rsquo;t less than 1, so I&amp;rsquo;m going to create
a &lt;code&gt;cons&lt;/code&gt; with &lt;code&gt;0&lt;/code&gt; and the result of calling &lt;code&gt;(fib1 2 1 1)&lt;/code&gt; (2 = &amp;ldquo;&lt;code&gt;n&lt;/code&gt; minus 1&amp;rdquo;,
because &lt;code&gt;n&lt;/code&gt; is currently 3; &lt;code&gt;1&lt;/code&gt; because &lt;code&gt;b=1&lt;/code&gt;; and &lt;code&gt;1&lt;/code&gt; because &lt;code&gt;a + b&lt;/code&gt; = &lt;code&gt;0 + 1&lt;/code&gt; =
&lt;code&gt;1&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;So at this point we have a &lt;code&gt;cons&lt;/code&gt; that looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;;; [= (cons 0 (fib1 2 1 1))]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When we evaluate &lt;code&gt;(fib1 2 1 1)&lt;/code&gt;, &lt;code&gt;n&lt;/code&gt; is still not less than &lt;code&gt;1&lt;/code&gt;, so we&amp;rsquo;re
going to &lt;code&gt;cons&lt;/code&gt; the current value of &lt;code&gt;a&lt;/code&gt; (which is &lt;code&gt;1&lt;/code&gt;) with another call to
&lt;code&gt;fib1&lt;/code&gt;: &lt;code&gt;(fib1 1 1 2)&lt;/code&gt; (1 = &amp;ldquo;&lt;code&gt;n&lt;/code&gt; minus 1&amp;rdquo;, because &lt;code&gt;n&lt;/code&gt; is currently 2; &lt;code&gt;1&lt;/code&gt;
because &lt;code&gt;b=1&lt;/code&gt;; and &lt;code&gt;2&lt;/code&gt; because &lt;code&gt;a + b&lt;/code&gt; = &lt;code&gt;1 + 1&lt;/code&gt; = &lt;code&gt;2&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;So now we have:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;;; [= (cons 0 (cons 1 (fib1 1 1 2)))]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we have to evaluate &lt;code&gt;(fib1 1 1 2)&lt;/code&gt;. &lt;code&gt;n&lt;/code&gt; is still not less than 1; so
we create another &lt;code&gt;cons&lt;/code&gt; of &lt;code&gt;1&lt;/code&gt; (as &lt;code&gt;a&lt;/code&gt; is currently &lt;code&gt;1&lt;/code&gt;) with yet another
call of &lt;code&gt;fib1&lt;/code&gt;: &lt;code&gt;(fib1 0 2 3)&lt;/code&gt; (0 = &amp;ldquo;&lt;code&gt;n&lt;/code&gt; minus 1&amp;rdquo;, because &lt;code&gt;n&lt;/code&gt; is currently 1; &lt;code&gt;2&lt;/code&gt;
because &lt;code&gt;b=2&lt;/code&gt;; and &lt;code&gt;3&lt;/code&gt; because &lt;code&gt;a + b&lt;/code&gt; = &lt;code&gt;1 + 2&lt;/code&gt; = &lt;code&gt;3&lt;/code&gt;). And so now:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;;; [= (cons 0 (cons 1 (cons 1 (fib1 0 2 3))))]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And, finally, evaluating &lt;code&gt;(fib1 0 2 3)&lt;/code&gt;, now &lt;code&gt;n&lt;/code&gt; is less than one, so we
take the first branch of the conditional and just return &lt;code&gt;a&lt;/code&gt;, which is
&lt;code&gt;2&lt;/code&gt;. So the result of starting with &lt;code&gt;(fib1 3 0 1)&lt;/code&gt; is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;;; [= (cons 0 (cons 1 (cons 1 2)))]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And you can try this with other values of &lt;code&gt;n&lt;/code&gt;, e.g., try evaluating
&lt;code&gt;(fib1 100 0 1)&lt;/code&gt; to get the first 100 members of the sequence.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;But, at least for me on Emacs 30.0.93, 529 is the limit. If we try
&lt;code&gt;(fib1 520 0 1)&lt;/code&gt;, the debugger pops up with a 1622 line long error,
which begins:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Debugger&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entered--Lisp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;error:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;excessive-lisp-nesting&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1622&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;cl-print--cons-tail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;excessive-lisp-nesting&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1601&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;buffer&lt;/span&gt;  &lt;span class=&#34;vg&#34;&gt;*temp*&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compiled-function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;object&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;bytecode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;0x491d55561699a09&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;buffer&lt;/span&gt;  &lt;span class=&#34;vg&#34;&gt;*temp*&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nf&#34;&gt;apply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compiled-function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;object&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;bytecode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;0x491d55561699a09&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;buffer&lt;/span&gt;  &lt;span class=&#34;vg&#34;&gt;*temp*&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compiled-function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kp&#34;&gt;&amp;amp;rest&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;bytecode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;0x1c31d892b8046a8b&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)()&lt;/span&gt;
  &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compiled-function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cl--cnm&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;object&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;bytecode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;0x7c361f66f109692&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compiled-function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kp&#34;&gt;&amp;amp;rest&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;bytecode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;0x1c31d892b8046a8b&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;buffer&lt;/span&gt;  &lt;span class=&#34;vg&#34;&gt;*temp*&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nf&#34;&gt;apply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compiled-function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cl--cnm&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;object&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;bytecode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;0x7c361f66f109692&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compiled-function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kp&#34;&gt;&amp;amp;rest&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;bytecode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;0x1c31d892b8046a8b&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;buffer&lt;/span&gt;  &lt;span class=&#34;vg&#34;&gt;*temp*&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compiled-function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;object&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;bytecode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;0x1f277a9a6dc403fa&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;buffer&lt;/span&gt;  &lt;span class=&#34;vg&#34;&gt;*temp*&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nf&#34;&gt;apply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compiled-function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;object&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;bytecode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;0x1f277a9a6dc403fa&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;buffer&lt;/span&gt;  &lt;span class=&#34;vg&#34;&gt;*temp*&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;cl-print-object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;buffer&lt;/span&gt;  &lt;span class=&#34;vg&#34;&gt;*temp*&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;cl-prin1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;buffer&lt;/span&gt;  &lt;span class=&#34;vg&#34;&gt;*temp*&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;backtrace--print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;buffer&lt;/span&gt;  &lt;span class=&#34;vg&#34;&gt;*temp*&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;cl-print-to-string-with-limit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;backtrace--print&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;backtrace--print-to-string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;backtrace-print-to-string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;debugger--insert-header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:backtrace-base&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;eval-expression--debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compiled-function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;bytecode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;0x299e53d67d1ac62&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)()&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;backtrace-print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;debugger-setup-buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:backtrace-base&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;eval-expression--debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:backtrace-base&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;eval-expression--debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;eval-expression--debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;1-&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;259396630450514843945535792456880074043523940756078363514486570322782139633750401577338505233670220572153381665&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;419712564636128966418863068957011388899128076671547993021605479585858227224221424221791102364954108601240491394&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;1-&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;1-&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;160315934185614122473327276500131314855604135915469629507118909263076087590471022644452597131283888029087109729&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;259396630450514843945535792456880074043523940756078363514486570322782139633750401577338505233670220572153381665&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;1-&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;1-&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;fib1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99080696264900721472208515956748759187919804840608734007367661059706052043279378932885908102386332543066271936&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;160315934185614122473327276500131314855604135915469629507118909263076087590471022644452597131283888029087109729&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 4:&lt;/span&gt;
  beginning of excessive-lisp-nesting error for our fib1 function
&lt;/div&gt;
&lt;p&gt;Because we&amp;rsquo;ve built up a long, deeply-embedded list of conses and
Emacs has a limit of how deep it&amp;rsquo;s willing/able to go (you can see
above that we&amp;rsquo;ve almost made it to the end, just needing to calculate
&lt;code&gt;fib1(0)&lt;/code&gt;, when Emacs decides it&amp;rsquo;s had enough).&lt;/p&gt;
&lt;p&gt;In Scheme and elsewhere, self-recursive calls at the ends (&amp;ldquo;tails&amp;rdquo;) of
functions can be optimised to avoid these sorts of stack overflows
(&lt;code&gt;excessive-lisp-nesting&lt;/code&gt;).&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; Tail-call optimisation lets
procedure calls in tail positions be treated a specialised GOTO
statements, which can be efficiently processed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…only in cases where structures are explicitly declared to be
dynamically referenced should the compiler be forced to leave them on
the stack in an otherwise tail-recursive situation. In general,
procedure calls may be usefully thought of as GOTO statements which
also pass parameters, and can be uniformly encoded as JUMP
instructions. This is a simple, universal technique, to be contrasted
with […] more powerful recursion-removal techniques…&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[Steele 1977:155&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But our &lt;code&gt;fib1&lt;/code&gt; function doesn&amp;rsquo;t do this, and we end up flooded the stack
with too many conses.&lt;/p&gt;
&lt;h2 id=&#34;back-to-loops&#34;&gt;Back to loops&lt;/h2&gt;
&lt;p&gt;Recursive functions are perhaps most idiomatic in Scheme (among lisps,
I mean). Some implementations of Common Lisp can do tail-call
optimisation, but loops are perhaps more common, and certainly in
Emacs Lisp (for reasons you can see above), loops are usually what are
used. And so we can write a new Fibonacci function with a loop. It
won&amp;rsquo;t be nearly as pretty, but it&amp;rsquo;ll work better.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s one possible implementation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; -*- lexical-binding: t; -*-&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fib2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Calculate the first &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; Fibonacci numbers,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in a loop.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;dotimes&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;c&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;tempa&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;tempa&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nreverse&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib2&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; (0 1 1 2 3 5 8 13 21 34)&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bigfib-50000&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib2&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;50000&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; this will work - we can get 50,000 numbers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 5:&lt;/span&gt;
  a second go at a fibonacci function, with looping
&lt;/div&gt;
&lt;p&gt;The result is prettier at least: a proper rather than an improper list
(because we started by &lt;code&gt;cons&lt;/code&gt;&#39;ing onto an empty list). Our &lt;code&gt;fib2&lt;/code&gt; function
itself isn&amp;rsquo;t as mathematically pleasing as our &lt;code&gt;fib1&lt;/code&gt; function, we end
up with a lot of &lt;code&gt;setq&lt;/code&gt;&#39;s (the &lt;code&gt;nreverse&lt;/code&gt; at the end reverses our list,
because the way we build up our list is by &lt;code&gt;cons&lt;/code&gt;&#39;ing the first results
first, so they end up at the end until we flip them with
&lt;code&gt;nreverse&lt;/code&gt;). But it works well. If you try to &lt;code&gt;(fib2 100000 0 1)&lt;/code&gt;, it&amp;rsquo;ll
fail, but not because of stack overflow, just because we end up with
numbers that are too big for Emacs. But you can certain get the over
50,000 members of the Fibonacci sequence, which is much better than
&lt;code&gt;fib1&lt;/code&gt;&#39;s limit of 529.&lt;/p&gt;
&lt;p&gt;And &lt;code&gt;dotimes&lt;/code&gt; is just one loop procedure available. (See &lt;a href=&#34;https://www.gnu.org/software/emacs/manual/html_node/cl/Loop-Examples.html&#34;&gt;&lt;code&gt;cl-loop&lt;/code&gt;&lt;/a&gt; for a more
powerful one.)&lt;/p&gt;
&lt;h2 id=&#34;optimal-tail-with-emacs&#34;&gt;Optimal Tail with Emacs&lt;/h2&gt;
&lt;p&gt;Ok, so, practically, we should probably generally prefer loops over
tail-recursive functions in Emacs. But, what if we just like the latter
more?&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; Are there any other possibilities?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://mastodon.social/@wilfredh&#34;&gt;Wilfred Hughes&lt;/a&gt; has an emacs package &lt;a href=&#34;https://github.com/Wilfred/tco.el&#34;&gt;&lt;code&gt;tco.el&lt;/code&gt;&lt;/a&gt; which implements a
special macro for writing tail-recursive functions.&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt; It works by
replacing each self-call with a &lt;a href=&#34;https://en.wikipedia.org/wiki/Thunk&#34;&gt;thunk&lt;/a&gt;, and wrapping the function body
in a loop that repeatedly evaluates the thunk. Thus a
function &lt;code&gt;foo&lt;/code&gt; defined with the &lt;code&gt;defun-tco&lt;/code&gt; macro:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;defun-tco&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;foo&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;foo&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;would be re-written as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;foo&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;flet&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;foo-thunk&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;foo-thunk&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;apply&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;foo-thunk&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;functionp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;funcall&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
       &lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And this delays evaluation in such a way as to avoid stack
overflows. Unfortunately, at least currently for me (Emacs 30.0.93
again), tco.el seems to &lt;a href=&#34;https://github.com/Wilfred/tco.el/issues/10&#34;&gt;have some issues&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In Emacs 28.1, &lt;code&gt;cl-labels&lt;/code&gt; (one of the ways of sort of doing &lt;code&gt;let&lt;/code&gt;&#39;s for
functions) &lt;a href=&#34;https://github.com/emacs-mirror/emacs/commit/29c7f8c915c3889dfd5b25878aa0692f826cd38f&#34;&gt;gained some limited tail-call optimisation&lt;/a&gt; (as did
&lt;code&gt;named-let&lt;/code&gt;, which uses &lt;code&gt;cl-labels&lt;/code&gt;).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; -*- lexical-binding: t; -*-&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fib3&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Calculate the first &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; Fibonacci numbers,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;recursively, with limited tail-call optimisation
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;through &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`cl-labels&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;?!&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cl-labels&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                    &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;
                  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;
                        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;1-&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                              &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;
                              &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bigfib3&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib3&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;397&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; 396 highest that works&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 6:&lt;/span&gt;
  a third go at a fibonacci function, with cl-labels
&lt;/div&gt;
&lt;p&gt;At least the way I&amp;rsquo;ve written it, it seems to suffer an overflow even
sooner (at 397 rather than 529 as for our &lt;code&gt;fib1&lt;/code&gt;), because it has to
come back and do the &lt;code&gt;cons&lt;/code&gt; after the tail-call — so &lt;code&gt;fib*&lt;/code&gt; isn&amp;rsquo;t actually
in the tail. (We can fix this in at least one way, which we&amp;rsquo;ll do in &lt;code&gt;fib5&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;We could try to write an accumulator as a hack, where we try to do
ours conses one at a time and pass along the results, but this fares no
better than our &lt;code&gt;fib1&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; -*- lexical-binding: t; -*-&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fib4&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Calculate the first &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; Fibonacci numbers, recursively,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;but collect conses as we go and keep track of the length of
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`accum&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; cp. against &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;accum-lng&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum-lng&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nreverse&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib4&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bigfib4-529&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib4&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;529&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; last good&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bigfib4-530&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib4&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;530&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; overflows&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 7:&lt;/span&gt;
  a fourth go at a fibonacci function, with an accumulator
&lt;/div&gt;
&lt;p&gt;If we combine &lt;code&gt;cl-labels&lt;/code&gt; and the accumulator trick, however, we do seem
to be able to escape stack overflows, because now we&amp;rsquo;ve got &lt;code&gt;fib*&lt;/code&gt;
properly in the tail:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; -*- lexical-binding: t; -*-&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fib5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Calculate the first &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; Fibonacci numbers, recursively,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;using both cl-labels and the accumulator trick.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cl-labels&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
                         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;accum-lng&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
                     &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum-lng&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nreverse&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;accum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bigfib5-10000&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib5&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; ok&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bigfib5-50000&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib5&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;50000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; very slow, but ok&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 8:&lt;/span&gt;
  a fifth go at a fibonacci function, with cl-labels and an accumulator
&lt;/div&gt;
&lt;p&gt;Now we&amp;rsquo;re back in the realms of what our &lt;code&gt;fib2&lt;/code&gt; non-recursive loop-style
function could do. Although &lt;code&gt;(setq bigfib5-50000 (fib5 50000))&lt;/code&gt;
calculates very slowly (worse than our looping &lt;code&gt;fib2&lt;/code&gt;), so that&amp;rsquo;s not ideal.&lt;/p&gt;
&lt;h2 id=&#34;stream-of-conses-ness&#34;&gt;Stream of Conses-ness&lt;/h2&gt;
&lt;p&gt;But here&amp;rsquo;s another possibility: &lt;a href=&#34;https://nicolas.petton.fr&#34;&gt;Nicholas Pettton&lt;/a&gt;&amp;lsquo;s &lt;a href=&#34;https://elpa.gnu.org/packages/stream.html&#34;&gt;&lt;code&gt;stream&lt;/code&gt;&lt;/a&gt; package
for emacs, where &amp;ldquo;streams&amp;rdquo; are delayed evaluations of &lt;code&gt;cons&lt;/code&gt; cells.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; -*- lexical-binding: t; -*-&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fib6&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Return a list of the first &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; Fibonacci numbers,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;implemented as stream of (delayed evaluation) conses.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cl-labels&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fibonacci-populate&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;stream-cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fibonacci-populate&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fibonacci-stream&lt;/span&gt;
           &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fibonacci-populate&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fibs&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;dotimes&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;c&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fibs&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;stream-pop&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fibonacci-stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fibs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nreverse&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fibs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fib6-10k&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib6&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; ok&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fib6-50k&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib6&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;50000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; little slow, but works&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fib6-100k&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fib6&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; little slow &amp;amp; overflow error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 9:&lt;/span&gt;
  a sixth go at a fibonacci function, with delayed evaluation conses
&lt;/div&gt;
&lt;p&gt;This works well. &lt;code&gt;(fib6 50000)&lt;/code&gt; still turns out to run a bit slower than
our &lt;code&gt;(fib2 50000)&lt;/code&gt;, so loops are still probably more efficient, but
streams are pretty interesting. They can can used to represent
infinite sequences. So here, above, &lt;code&gt;fibonacci-stream&lt;/code&gt; (set by
&lt;code&gt;(fibonacci-populate 0 1)&lt;/code&gt;) is actually an infinite stream of Fibonaccis
numbers, but lazily evaluated, so we just get the next one each time
we call &lt;code&gt;stream-pop&lt;/code&gt; on our &lt;code&gt;fibonacci-stream&lt;/code&gt; local variable. (What
happens is that &lt;code&gt;stream-pop&lt;/code&gt; takes the &lt;code&gt;car&lt;/code&gt; of &lt;code&gt;fibonacci-stream&lt;/code&gt;,
evaluates and returns it, and then sets &lt;code&gt;fibonacci-stream&lt;/code&gt; to be its &lt;code&gt;cdr&lt;/code&gt;
(i.e., popping off and &amp;ldquo;discarding&amp;rdquo; the first element; which which
captured in our &lt;code&gt;fibs&lt;/code&gt; collector.))&lt;/p&gt;
&lt;h3 id=&#34;cascades-of-fibonacci-numbers&#34;&gt;Cascades of Fibonacci numbers&lt;/h3&gt;
&lt;p&gt;Oh, incidentally and irrelevantly, if you inspect the contents of your
&lt;code&gt;fib6-50k&lt;/code&gt;, it&amp;rsquo;s very aesthetically pleasing, a cascade of numbers:&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/Fibonacci_Flooding_Streams.png&#34; alt=&#34;Figure 2: fibonacci numbers burst forth from their seeds and spill out into the buffer&#34;/&gt; &lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 2: &lt;/span&gt;fibonacci numbers burst forth from their seeds and spill out into the buffer
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;h2 id=&#34;excessive-lisp-nesting--overflow-error&#34;&gt;&lt;code&gt;excessive-lisp-nesting&lt;/code&gt;: &lt;strong&gt;(overflow-error)&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;I had hoped to get to the Y Combinator today (and think I might have
suggested a promise of that), for that&amp;rsquo;s where things really get
interesting. And we need to get back to lambda calculus, of course.
But we may be near the limits of excessive lisp nesting ourselves
here.&lt;/p&gt;
&lt;p&gt;However, the recursion discussion here has set the stage for the Y
Combinator, which we&amp;rsquo;ve already talked a couple of times, especially
in connection to John McCarthy&amp;rsquo;s claims about &amp;ldquo;not really
understanding&amp;rdquo; lambda calculus and the fact that these really centre
on his not seeing how one could get recursion without direct
Self-reference (and thus the need for &lt;code&gt;LABEL&lt;/code&gt;) because of not knowing
about the Y Combinator.&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/phoe-ycombinator-codex-closeup-fibo.jpg&#34; alt=&#34;Figure 3: a close-up of a section of Michał &amp;ldquo;phoe&amp;rdquo; Herda&amp;rsquo;s hand-illuminated Y Combinator Codex showing part of a Fibonacci defun&#34;/&gt; &lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 3: &lt;/span&gt;a close-up of a section of &lt;a href=&#34;https://phoe.github.io/&#34;&gt;Michał &amp;ldquo;phoe&amp;rdquo; Herda&amp;rsquo;s&lt;/a&gt; hand-illuminated &lt;a href=&#34;https://phoe.github.io/codex.html&#34;&gt;Y Combinator Codex&lt;/a&gt; showing part of a Fibonacci defun
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;And, the Y Combinator ties in with all sorts of other curious
things. Paradoxes, types, calligraphy.&lt;/p&gt;
&lt;p&gt;[Thus, I ended up with an excursus on this excursus as the next
post. I&amp;rsquo;ll put a link here to the proper third part when it&amp;rsquo;s up.]&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;McCarthy, John. 1978a. History of Lisp. In &lt;em&gt;History of programming languages&lt;/em&gt;, ed. Richard L. Wexelblat, 173–185. New York:
Association for Computing Machinery. &lt;a href=&#34;https://dl.acm.org/doi/10.1145/800025.1198360&#34;&gt;https://dl.acm.org/doi/10.1145/800025.1198360&lt;/a&gt; &lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;&amp;ldquo;t if and only if p and q or if r then s and
not not not not not not t&amp;rdquo; &lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;A number of Indian philosophers, at least as far back as
Virahāṅka (ca. AD 600–800), gave formulations for what is usually
called the Fibonacci sequence. See Singh, P. (1985). The so-called
fibonacci numbers in ancient and medieval India. &lt;em&gt;Historia Mathematica&lt;/em&gt;,
12(3), 229–244. &lt;a href=&#34;https://doi.org/10.1016/0315-0860(85)90021-7&#34;&gt;https://doi.org/10.1016/0315-0860(85)90021-7&lt;/a&gt; [&lt;a href=&#34;https://sci-hub.se/https://www.sciencedirect.com/science/article/pii/0315086085900217?via%3Dihub&#34;&gt;pdf&lt;/a&gt;] &lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;You might actually want to do something like &lt;code&gt;(setq my-fib1-100 (fib1 100 0 1))&lt;/code&gt; to put the result into a variable, because
the echo area at the bottom of Emacs isn&amp;rsquo;t big enough for all of the
numbers. (Oh, to &lt;code&gt;eval&lt;/code&gt; things in an Emacs buffer, put your cursor/point
at the end of the expression and press &lt;code&gt;C-x C-e&lt;/code&gt;. But don&amp;rsquo;t do that for
this one. If you want Emacs to just stick the results in directly into
the buffer rather than echoing them, press &lt;code&gt;C-u C-x C-e&lt;/code&gt;. But don&amp;rsquo;t do
that here either, because Emacs will still end up printing an ellipsis
because it thinks it&amp;rsquo;s too long.) And then press &lt;code&gt;C-h v&lt;/code&gt; and type
&lt;code&gt;my-fib1-100&lt;/code&gt; and enter to see the result. &lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;See further &lt;a href=&#34;https://en.wikipedia.org/wiki/Tail_call&#34;&gt;here&lt;/a&gt;, for instance, for more about tail calls and
tail call optimisation. &lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Steele, Guy L., Jr. 1977. Debunking the “expensive procedure
call” myth or, procedure call implementations considered harmful or,
LAMBDA: The Ultimate GOTO. &lt;em&gt;ACM &amp;lsquo;77: Proceedings of the 1977 annual
conference&lt;/em&gt;, 153–162. [&lt;a href=&#34;https://dl.acm.org/doi/10.1145/800179.810196&#34;&gt;https://dl.acm.org/doi/10.1145/800179.810196&lt;/a&gt;] &lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;If you&amp;rsquo;ve read any of Paul Graham&amp;rsquo;s Common Lisp books
(e.g., &lt;a href=&#34;https://en.wikipedia.org/wiki/On_Lisp&#34;&gt;&lt;em&gt;On Lisp&lt;/em&gt;&lt;/a&gt;) or any of the &lt;a href=&#34;https://web.archive.org/web/20150426092105/http://www.ccs.neu.edu/home/matthias/BTLS/&#34;&gt;Little Schemer&lt;/a&gt; books (the latter with
&lt;a href=&#34;https://wiki.c2.com/?DuaneBibby&#34;&gt;Duane Bibby&lt;/a&gt;&amp;lsquo;s lovely artwork in them), you may be disposed towards
using recursion rather than loops.&lt;/p&gt;
&lt;p&gt;


&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/little-scheming-phant.png&#34; alt=&#34;Figure 4: close-up of Duane Bibby&amp;rsquo;s cover illustration for &amp;ldquo;The Little Schemer&amp;rdquo;&#34;/&gt; &lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 4: &lt;/span&gt;close-up of Duane Bibby&amp;rsquo;s cover illustration for &amp;ldquo;The Little Schemer&amp;rdquo;
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;
 &lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;One of my emacs packages, &lt;a href=&#34;https://melpa.org/#/equake&#34;&gt;Equake&lt;/a&gt;, actually used to use
tco.el (until &lt;a href=&#34;https://github.com/emacsomancer/equake/commit/0ab08019e8aee5f2e27db6ee90f6a64856f39ff9&#34;&gt;commit #0ab0801&lt;/a&gt; &lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2020-08-24 Mon]&lt;/span&gt;&lt;/span&gt;). &lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lambdacalculus">lambdacalculus</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                
                            
                        
                     
                        
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/tags/recursion">recursion</category>
                                
                            
                        
                    
                
                <guid>https://babbagefiles.xyz/lambda-calculus-and-lisp-02-recursion/</guid>
                <pubDate>Thu, 20 Feb 2025 01:26:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Lambda Calculus and Lisp, part 1</title>
                <link>https://babbagefiles.xyz/lambda-calculus-and-lisp-01/</link>
                
                
                <description>&lt;p&gt;The first of a series of envisioned blog posts on lambda calculus, and
Lisp. It&amp;rsquo;s unclear exactly where to start: there is a whole heap of
interesting issues, both theoretical and in terms of concrete
implementations, which tangle and interconnect.&lt;/p&gt;
&lt;p&gt;A particular application of lambda calculus is a very salient part of
my &amp;ldquo;day job&amp;rdquo; as a formal semanticist of natural language. And my
interests in Emacs and lisp(s) feel like they tie in here as
well—though that&amp;rsquo;s a question in itself which is probably as good of a
starting point into this (planned) series of posts as any.&lt;/p&gt;
&lt;p&gt;There is much to explore: origins of &lt;a href=&#34;https://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist)&#34;&gt;John McCarthy&lt;/a&gt;&amp;lsquo;s Lisp and &lt;a href=&#34;https://en.wikipedia.org/wiki/Alonzo_Church&#34;&gt;Alonzo
Church&lt;/a&gt;&amp;lsquo;s lambda calculus; encodings of the simple made complex by
restriction to a limited set of tools; recursion, fixed points, and
paradoxes; infinities, philosophy, and engineering. But much of this
requires stage setting.&lt;/p&gt;
&lt;p&gt;And finding an exact entry point is yet tricky. But perhaps we start
with &lt;strong&gt;λ&lt;/strong&gt;: the divining rod, the wizard&amp;rsquo;s crooked staff, as it is the key
component of much magic of a sort.&lt;/p&gt;
&lt;h2 id=&#34;lisp-lambda-the-ultimate&#34;&gt;Lisp: LAMBDA the Ultimate?&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ll start on the programming side, before turning to more
philosophical or mathematical abstractions, with &lt;code&gt;lambda&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It is now not only Lisps which contain &lt;code&gt;lambda&lt;/code&gt; as a keyword, many/most
programming languages have &lt;code&gt;lambda&lt;/code&gt; as a keyword, usually for the
introduction of an anonymous function. That is, an unnamed function,
sometimes for one-off use.&lt;/p&gt;
&lt;p&gt;But in McCarthy&amp;rsquo;s original formulation of LISP in 1958, &lt;code&gt;LAMBDA&lt;/code&gt;
was used as the basis for the implementation of functions generally:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Let &lt;code&gt;f&lt;/code&gt; be an expression that stands for a function of two integer variables.
It should make sense to write &lt;code&gt;f&lt;/code&gt; (3, 4) and the value of this expression should be
determined. The expression &lt;code&gt;y^2 + x&lt;/code&gt; does not meet this requirement; &lt;code&gt;y^2 + x(3, 4)&lt;/code&gt;
is not a conventional notation, and if we attempted to define it we would be
uncertain whether its value would turn out to be 13 or 19. Church calls an
expression like &lt;code&gt;y2 + x&lt;/code&gt;, a form. A form can be converted into a function if we
can determine the correspondence between the variables occurring in the form
and the ordered list of arguments of the desired function. This is accomplished
by Church’s λ-notation. [p.6]&lt;/p&gt;
&lt;p&gt;&amp;hellip;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;{λ[[x_1;…; x_n]; 𝓔]}∗&lt;/code&gt; is &lt;code&gt;(LAMBDA, (x∗_1,…, x∗_n), 𝓔∗)&lt;/code&gt;. [p.16]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[McCarthy 1960:6, 16&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As in lambda calculus, &lt;code&gt;LAMBDA&lt;/code&gt; binds variables, and replaces any
occurrences of them in the scope of the operator with whatever it
receives as arguments.&lt;/p&gt;
&lt;p&gt;So the expression:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;LAMBDA&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;z&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;if given the arguments &lt;code&gt;5&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, would replace &lt;code&gt;x&lt;/code&gt;&#39;s with &lt;code&gt;5&lt;/code&gt;; &lt;code&gt;y&lt;/code&gt;&#39;s with &lt;code&gt;2&lt;/code&gt;,
and &lt;code&gt;z&lt;/code&gt;&#39;s with &lt;code&gt;3&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;;; = (+ 10 15) = 25&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;the-illusion-of-a-blue-suffused-platonic-universe-of-car-s&#34;&gt;The illusion of a blue-suffused platonic universe of &lt;code&gt;car&lt;/code&gt;&#39;s&lt;/h3&gt;
&lt;p&gt;The origin of &lt;code&gt;lambda&lt;/code&gt; keywords in LISP, and the origin of LISP&amp;rsquo;s &lt;code&gt;LAMBDA&lt;/code&gt;
in lambda calculus has suggested the idea that LISP was something like
an implementation of lambda calculus as a programming language, and
the certain mysticism&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; attaching to both suggests perhaps a tighter
surface association than there is direct evidence for.&lt;/p&gt;



&lt;figure&gt;
    
        
            &lt;img src=&#34;https://imgs.xkcd.com/comics/lisp.jpg&#34; alt=&#34;Figure 1: xkcd 224 [see https://www.explainxkcd.com/wiki/index.php/224:_Lisp]&#34;/&gt; &lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 1: &lt;/span&gt;xkcd 224 [see &lt;a href=&#34;https://www.explainxkcd.com/wiki/index.php/224:_Lisp&#34;&gt;https://www.explainxkcd.com/wiki/index.php/224:_Lisp&lt;/a&gt;]
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;This is the topic of a 2019 blog post based on his talk for the Heart of Clojure
conference in Daniel Szmulewicz expands on the theme &amp;ldquo;Lisp is &lt;strong&gt;not&lt;/strong&gt; a
realization of the Lambda Calculus&amp;rdquo;.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; One of the points
Szmulewicz draws attention to is McCarthy&amp;rsquo;s own words:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…one of the myths concerning LISP that people think up or invent for
themselves becomes apparent, and that is that LISP is somehow a
realization of the lambda calculus, or that was the intention. The
truth is that I didn&amp;rsquo;t understand the lambda calculus, really.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[McCarthy 1978b:190&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the paper version of the talk, McCarthy makes a similar point, but
it&amp;rsquo;s worth looking at it in the larger context:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…how do you talk about the sum of the derivatives, and in programming
it, there were clearly two kinds of programs that could be written.&lt;/p&gt;
&lt;p&gt;One is where you have a sum of a fixed number of terms, like just two,
where you regard a sum as a binary operation. And then you could write
down the formula easy enough. But the other was where you have a sum
of an indefinite number of terms, and you&amp;rsquo;d really like to make that
work too. To make that work, what you want to be able to talk about is
doing the same operation on all the elements of a lit. You want to be
able to get a new list whose elements are obtained from the old list
by just taking each element and doing a certain operation to it.&lt;/p&gt;
&lt;p&gt;In order to describe that, one has to have a notation for
functions. So one could write this function called &lt;code&gt;mapcar&lt;/code&gt;. This says,
&amp;ldquo;Apply the function &lt;code&gt;f&lt;/code&gt; to all the elements of the list.&amp;rdquo; If the list is
null then you&amp;rsquo;re going to get a &lt;code&gt;NIL&lt;/code&gt; here. Otherwise you are going to
apply the function to the first element of the list and put that onto
a front of a list which is obtained by doing the same operation again
to the rest of the list. So that&amp;rsquo;s &lt;code&gt;mapcar&lt;/code&gt;. It wasn&amp;rsquo;t called &lt;code&gt;mapcar&lt;/code&gt;
then. It was called &lt;code&gt;maplist&lt;/code&gt;, but &lt;code&gt;maplist&lt;/code&gt; is something different, which
I will describe in just a moment.&lt;/p&gt;
&lt;p&gt;That was fine for that recursive definition of applying a function to
everything on the list. No new ideas were required. But then, how do
you write these functions?&lt;/p&gt;
&lt;p&gt;And so, the way in which to do that was to borrow from Church&amp;rsquo;s Lambda
Calculus, to borrow the lambda definition. Now, having borrowed this
notation, one the myths concerning LISP that people think up or invent
for themselves becomes apparent, and that is that LISP is somehow a
realization of the lambda calculus, or that was the intention. The
truth is that I didn&amp;rsquo;t understand the lambda calculus, really. In
particular, I didn&amp;rsquo;t understand that you really could do conditional
expressions in recursion in some sense in the pure lambda
calculus. So, it wasn&amp;rsquo;t an attempt to make the lambda calculus
practical, although if someone had started out with that intention, he
might have ended up with something like LISP.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[McCarthy 1978a:189–190&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;the-discovery-of-lisp&#34;&gt;The Discovery of LISP&lt;/h3&gt;
&lt;p&gt;Two bits from the end of this I want to highlight. The first, well,
it&amp;rsquo;ll come up in future posts, and probably later in this post itself,
and it has to do with recursion:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;I didn&amp;rsquo;t understand that you really could do conditional expressions in recursion in some sense in the pure lambda
calculus&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And the second is that McCarthy hedges his &amp;ldquo;LISP as a realisation of
the lambda calculus is myth&amp;rdquo; stance slightly:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;So, it wasn&amp;rsquo;t an attempt to make the lambda calculus practical, although if someone had started out with that intention, he
might have ended up with something like LISP.&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This does fit rather well with (and perhaps suggested) the framing
that &lt;a href=&#34;https://en.wikipedia.org/wiki/Paul_Graham_(programmer)&#34;&gt;Paul Graham&lt;/a&gt; does of McCarthy as the &amp;ldquo;discoverer&amp;rdquo; of Lisp — like
Euclid of geometry — rather than its inventor in his &amp;ldquo;The Roots of
Lisp&amp;rdquo; paper:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In 1960, John McCarthy published a remarkable paper in which he &lt;strong&gt;did
for programming something like what Euclid did for geometry&lt;/strong&gt;. He
showed how, given a handful of simple operators and a notation for
functions, you can build a whole programming language. He called this
language Lisp, for “List Processing,” because one of his key ideas was
to use a simple data structure called a list for both code and data.&lt;/p&gt;
&lt;p&gt;It’s worth understanding what McCarthy &lt;strong&gt;discovered&lt;/strong&gt;, not just as a
landmark in the history of computers, but as a model for what
programming is tending to become in our own time.
….
In this article I’m going to try to explain in the simplest possible
terms what McCarthy &lt;strong&gt;discovered&lt;/strong&gt;. The point is not just to learn about
an interesting theoretical result someone figured out forty years ago,
but to show where languages are heading. The unusual thing about
Lisp—in fact, the defining quality of Lisp—is that it can be written
in itself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[Graham 2002:1&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; (emphasis mine)]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Graham&amp;rsquo;s paper itself, as well as some of Graham&amp;rsquo;s other
publications/postings (e.g., talking about Lisp as a sort of &amp;ldquo;secret
weapon&amp;rdquo; in comparison to &amp;ldquo;blub languages&amp;rdquo;)&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; is perhaps another
contributor to the mystique of Lisp. (With the flip side of &amp;ldquo;Lisp as
the Cleveriest Hacker&amp;rsquo;s Secret Weapon&amp;rdquo; enchanted coin being &amp;ldquo;the Curse
of Lisp&amp;rdquo;&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;.)&lt;/p&gt;
&lt;p&gt;There are other components of the history of LISP, which are
suggestive of discovery rather than invention. McCarthy&amp;rsquo;s initial aim
for LISP was more akin that of the &lt;a href=&#34;https://en.wikipedia.org/wiki/Turing_machine&#34;&gt;Turing Machine&lt;/a&gt;: as a formal abstraction
describing a mathematical model whose components were simple and few
but yet was capable of performing any (and all) arbitrary
computational operation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One mathematical consideration that influenced LISP was to express
programs as applicative expressions built up from variables and
constants using functions. I considered it important to make these
expressions obey the usual mathematical laws allowing replacement of
expressions by expressions giving the same value. The motive was to
allow proofs of properties of programs using ordinary mathematical
methods. This is only possible to the extent that side effects can be
avoided. Unfortunately, side effects are often a great convenience
when computational efficiency is important, and &amp;ldquo;functions&amp;rdquo; with side
effects are present in LISP. However, the so-called pure LISP is free
of side effects, and Cartwright (1976) and Cartwright and McCarthy
(1978) show how to represent pure LISP programs by sentences and
schemata in first-order logic and prove their properties. This is an
additional vindication of the striving for mathematical neatness,
because it is now easier to prove that pure LISP programs meet their
specifications than it is for any other programming language in
extensive use. (Fans of other programming languages are challenged to
write a program to concatenate lists and prove that the operation is
associative.)&lt;/p&gt;
&lt;p&gt;Another way to show that LISP was neater than Turing machines was to
write a universal LISP function and show that is briefer and more
comprehensible than the description of a universal Turing
machine. This was the LISP function &lt;code&gt;eval[e,a]&lt;/code&gt;, which computers the
value of a LISP expression &lt;code&gt;e&lt;/code&gt;, the second argument &lt;code&gt;a&lt;/code&gt; being a list of
assignments of values to variables. (&lt;code&gt;a&lt;/code&gt; is needed to make the recursion
work.) Writing &lt;code&gt;eval&lt;/code&gt; required inventing a notation representing LISP
functions as LISP data, and such a notation was devised for the
purposes of the paper with no thought that it would be used to express
LISP programs in practice. Logical completeness required that the
notation used to express functions used as functional arguments be
extended to provide for recursive functions, and the &lt;code&gt;LABEL&lt;/code&gt; notation
was invented by Nathaniel Rochester for that purpose. D.M.R. Park
pointed out that &lt;code&gt;LABEL&lt;/code&gt; was logically unnecessary since the result
could be achieved using only &lt;code&gt;LAMBDA&lt;/code&gt; — by a construction analogous to
Church&amp;rsquo;s &lt;em&gt;Y&lt;/em&gt;-operator, albeit in a more complicated way.&lt;/p&gt;
&lt;p&gt;S.R. Russell noticed that &lt;code&gt;eval&lt;/code&gt; could serve as an interpreter for LISP,
promptly hand coded it, and we now had a programming language with an
interpreter.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[McCarthy 1978:179&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(There&amp;rsquo;s a lot going on in this passage, and its context.&lt;/p&gt;
&lt;p&gt;Notions of reasons to avoid side-effects (an ideal of &amp;ldquo;functional
programming&amp;rdquo;, emphasised in &lt;a href=&#34;https://en.wikipedia.org/wiki/Haskell&#34;&gt;Haskell&lt;/a&gt; and &lt;a href=&#34;https://en.wikipedia.org/wiki/Clojure&#34;&gt;Clojure&lt;/a&gt; (another lisp)): thus
the &amp;ldquo;functional&amp;rdquo; mode of lambda calculus rather than the &amp;ldquo;everything
is state&amp;rdquo; mode of Turing machines and their infinitely long memory tapes.&lt;/p&gt;
&lt;p&gt;Recursion again (which we&amp;rsquo;ll get to, repeatedly).&lt;/p&gt;
&lt;p&gt;And Alonzo Church, the originator (discoverer?)&lt;a href=&#34;#are-we-in-platonic-heaven-yet&#34;&gt;^{see &amp;ldquo;X&amp;rdquo; below}&lt;/a&gt; of lambda calculus,
who we&amp;rsquo;ll talk more about soon, and who was also Alan Turing&amp;rsquo;s PhD
supervisor at Princeton.&lt;/p&gt;
&lt;p&gt;But, first: let&amp;rsquo;s turn back to the topic of the concrete instantiation
of Lisp on physical hardware by &lt;a href=&#34;https://en.wikipedia.org/wiki/Steve_Russell_(computer_scientist)&#34;&gt;Stephen Russell&lt;/a&gt;.)&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/lisp-byte_magazine-1979.jpg&#34; alt=&#34;Figure 2: cover of Byte Magazine August 1979 [full mag here]&#34;/&gt; &lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 2: &lt;/span&gt;cover of Byte Magazine August 1979 [full mag &lt;a href=&#34;https://dn790008.ca.archive.org/0/items/byte-magazine-1979-08-rescan/1979_08_BYTE_04-08_LISP.pdf&#34;&gt;here&lt;/a&gt;]
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Elsewhere, McCarthy makes clear that he hadn&amp;rsquo;t thought at that point
of LISP being instantiatable but as a theoretical exploration of
computing at an abstract level. But, instead, the theoretical
description translated fairly easily and directly to a runnable
program, a LISP interpreter:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This &lt;code&gt;EVAL&lt;/code&gt; was written and published in the paper and Steve Russell
said, &amp;ldquo;look, why don&amp;rsquo;t I program this &lt;code&gt;EVAL&lt;/code&gt;&amp;rdquo; … and I said to him, &amp;ldquo;ho,
ho, you&amp;rsquo;re confusing theory with practice, this &lt;code&gt;EVAL&lt;/code&gt; is intended for
reading, not for computing&amp;rdquo;. But he went ahead and did it. That is, he
compiled the &lt;code&gt;EVAL&lt;/code&gt; in my paper into IBM 704 machine code, fixing bugs,
and then advertised this as a Lisp interpreter, which it certainly
was. So at that point Lisp had essentially the form that it has today…&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[McCarthy 1974a:307&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;no-compute-dot-only-read-dot-hell-eval-that-dot&#34;&gt;&amp;ldquo;No compute. Only read.&amp;rdquo; &amp;ldquo;Hell, EVAL that.&amp;rdquo;&lt;/h3&gt;
&lt;p&gt;This is the &lt;code&gt;EVAL&lt;/code&gt; code &amp;ldquo;in the paper&amp;rdquo; referred to above:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-prolog&#34; data-lang=&#34;prolog&#34;&gt;&lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
   &lt;span class=&#34;s&#34;&gt;atom&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;assoc&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;

   &lt;span class=&#34;s&#34;&gt;atom&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
        &lt;span class=&#34;s&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;QUOTE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
        &lt;span class=&#34;s&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;ATOM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;atom&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]];&lt;/span&gt;
        &lt;span class=&#34;s&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;EQ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;caddr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]];&lt;/span&gt;
        &lt;span class=&#34;s&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;COND&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;evcon&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
        &lt;span class=&#34;s&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CAR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]];&lt;/span&gt;
        &lt;span class=&#34;s&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CDR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]];&lt;/span&gt;
        &lt;span class=&#34;s&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;caddr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]];&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;assoc&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;evlis&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]];&lt;/span&gt;

   &lt;span class=&#34;s&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;caar&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;LABEL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;caddar&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]];&lt;/span&gt;
                                &lt;span class=&#34;s&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;list&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cadar&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]];&lt;/span&gt;

   &lt;span class=&#34;s&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;caar&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;LAMBDA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;caddar&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
                                 &lt;span class=&#34;s&#34;&gt;append&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;pair&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cadar&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
                                               &lt;span class=&#34;s&#34;&gt;evlis&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]]&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;evcon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;caar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cadar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;evcon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cdr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;evlis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;NIL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;→&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;cons&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;eval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;car&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;evlis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;cdr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 1:&lt;/span&gt;
  McCarthy 1960, p.17 (see &lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;fn. [1]&lt;/a&gt;) [Nb.: not actually `prolog&#39; but highlights better as]
&lt;/div&gt;
&lt;p&gt;Translated into slightly more familiar Lisp style (with added
named-function-making &lt;code&gt;label&lt;/code&gt;&#39;s), it is:&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt;
           &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;atom&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;assoc&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
           &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;atom&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;quote&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;atom&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;atom&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;eq&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;caddr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;car&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;cons&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;cons&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;caddr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;cond&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;evcon&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;&amp;#39;t&lt;/span&gt;                  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;assoc&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
                                         &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
           &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;caar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;caddar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
                                         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;list&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cadar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
           &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;caar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;lambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;caddar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;append&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pair&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cadar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                                       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;evlis&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
                                                 &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;evcon&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;c&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;caar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cadar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;&amp;#39;t&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;evcon&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;evlis&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;m&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;null&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;&amp;#39;t&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eval&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;evlis&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 2:&lt;/span&gt;
  EVAL in more recognisable lisp form
&lt;/div&gt;
&lt;p&gt;The above, given the few additional definitions for convenience
immediately following, is a full LISP interpreter.&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;null&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;&amp;#39;t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())))&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;&amp;#39;t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;&amp;#39;t&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;append&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;null&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;&amp;#39;t&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;append&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pair&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;null&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;null&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;atom&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;atom&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;list&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
                      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pair&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;assoc&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;caar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cadar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;&amp;#39;t&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;assoc&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 3:&lt;/span&gt;
  additional convenience functions for EVAL
&lt;/div&gt;
&lt;p&gt;The brevity of the code combined with the details of the story of the
implementation: seemingly the theoretical code works without
translation, suggesting a sort of natural discovery. But, the nature
of even the theoretical, pre-implementation code did not exist in some
Platonic heaven of mathematics, as can be seen by the nature of some
of the operations, particularly &lt;code&gt;car&lt;/code&gt; and &lt;code&gt;cdr&lt;/code&gt; (often in modern Lisps,
especially Scheme and Scheme-influenced Lisps, rendered instead more
transparently as &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;rest&lt;/code&gt;.)&lt;/p&gt;
&lt;h3 id=&#34;the-non-platonic-mechanics-of-1950s-ibm-mainframes&#34;&gt;The Non-Platonic mechanics of 1950s IBM mainframes&lt;/h3&gt;
&lt;p&gt;LISP was designed with the &lt;a href=&#34;https://en.wikipedia.org/wiki/IBM_704&#34;&gt;IBM 704&lt;/a&gt;-style architecture in mind, and &lt;code&gt;car&lt;/code&gt;
and &lt;code&gt;cdr&lt;/code&gt; make some reference to particular details of the hardware,
where the IBM 704 had &amp;ldquo;address&amp;rdquo; and &amp;ldquo;decrement&amp;rdquo; fields in memory index
registers (≈locations in physical RAM), and &lt;code&gt;car&lt;/code&gt; referenced the
&amp;ldquo;address&amp;rdquo; field of the register (so CAR = &amp;ldquo;&lt;strong&gt;C&lt;/strong&gt;-ontents of the &lt;strong&gt;A&lt;/strong&gt;-ddress
part of the &lt;strong&gt;R&lt;/strong&gt;-egister&amp;rdquo;) and &lt;code&gt;cdr&lt;/code&gt; the &amp;ldquo;decrement&amp;rdquo; field of the register
(CDR = &amp;ldquo;&lt;strong&gt;C&lt;/strong&gt;-ontents of the &lt;strong&gt;D&lt;/strong&gt;-ecrement part of the &lt;strong&gt;R&lt;/strong&gt;-egister&amp;rdquo;).&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/my-other-car-is-a-cdr.jpg&#34; alt=&#34;Figure 3: my other car is a cdr&#34;/&gt; &lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 3: &lt;/span&gt;my other car is a cdr
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Lists in Lisp are singly-linked lists, with each node in the list
having a &amp;ldquo;value&amp;rdquo; field and a &amp;ldquo;next&amp;rdquo; field, which points to the next
node; these &amp;ldquo;value&amp;rdquo; and &amp;ldquo;next&amp;rdquo; fields correspond to the &lt;code&gt;car&lt;/code&gt; and
&lt;code&gt;cdr&lt;/code&gt; operations. So, if we have a list like &lt;code&gt;(a b c)&lt;/code&gt;, the first node in the list has a
&amp;ldquo;value&amp;rdquo; field of &lt;code&gt;a&lt;/code&gt; and a &amp;ldquo;next&amp;rdquo; field pointing at another node, with
this second node actually itself being — not &lt;code&gt;b&lt;/code&gt; — but rather the list
&lt;code&gt;(b c)&lt;/code&gt;. A proper list in Lisp is &lt;code&gt;nil&lt;/code&gt;-terminated: that is, the last item
in the list is actually &lt;code&gt;nil&lt;/code&gt; (which is the empty list &lt;code&gt;&#39;()&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;The operation &lt;code&gt;cons&lt;/code&gt; above (for CONstructor) is a pair-forming operation
(where the pairs correspond to the &amp;ldquo;value&amp;rdquo; and &amp;ldquo;next&amp;rdquo; fields),
returning what are variously called (in different lisps) &amp;ldquo;conses&amp;rdquo; or
&amp;ldquo;pairs&amp;rdquo;. Not all conses/pairs are lists (at least in most Lisps),
since a proper &lt;code&gt;list&lt;/code&gt; in Lisp is &lt;code&gt;nil&lt;/code&gt;-terminated.&lt;/p&gt;
&lt;p&gt;The operation &lt;code&gt;(cons &#39;a &#39;b)&lt;/code&gt; will return a &lt;code&gt;cons&lt;/code&gt;&#39;ed object with
essentially a single node, where the &amp;ldquo;value&amp;rdquo; field will be &lt;code&gt;a&lt;/code&gt; and the
&amp;ldquo;next&amp;rdquo; field will be &lt;code&gt;b&lt;/code&gt;. Lisps will usually print such non-list conses
(sometimes called &amp;ldquo;improper lists&amp;rdquo;) as &amp;ldquo;dotted lists&amp;rdquo;, i.e., &lt;code&gt;(cons &#39;a &#39;b)&lt;/code&gt; will print out as &lt;code&gt;(a . b)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The list &lt;code&gt;(a b c)&lt;/code&gt; is actually the result of doing &lt;code&gt;(cons a (cons b (cons c nil)))&lt;/code&gt; and would be printed in dotted-pair notation as &lt;code&gt;(a . (b . (c . nil)))&lt;/code&gt; [which is equivalent to &lt;code&gt;(a . (b . (c . ())))&lt;/code&gt;, since &lt;code&gt;nil&lt;/code&gt; is
the empty list].&lt;/p&gt;
&lt;p&gt;Unsurprisingly, a lot of early/traditional Lisp programming involves
manipulations of lists. But all modern Lisps implement other types of
data structures as well, including vectors/arrays, hash tables,
objects, and so on.&lt;/p&gt;
&lt;p&gt;But, on the main topic of &lt;code&gt;(eq &#39;lisp &#39;lambdacalculus)&lt;/code&gt;, others have also
pointed out the concrete hardware-connections of LISP from early days,
telling against the &amp;ldquo;Lisp-as-pure-formal-&lt;del&gt;invention&lt;/del&gt;-discovery&amp;rdquo; or
&amp;ldquo;Lisp as (semi-)direct implementation of lambda calculus&amp;rdquo; notions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Lisp was intended to be implemented on a computer from day 0. For
their IBM 704. Actually Lisp is based on earlier programming
experience. From 56 onwards John McCarthy implemented Lisp ideas in
Fortran &amp;amp; FLPL. Then 58 the implementation of Lisp was started. 59 a
first runnable version was there. 1960 there was the Lisp 1
implementation. The widely known paper on the Lisp implementation and
recursive function theory was published in 1960. But his original
prime motivation was not to have a notation for recursive function
theory, it was to have a list processing programming language for
their IBM 704 for AI research.&lt;/p&gt;
&lt;p&gt;Lisp as designed by McCarthy was very different from lambda calculus.&lt;/p&gt;
&lt;p&gt;[going on to point to the &lt;a href=&#34;https://doi.org/10.1145/800055.802047&#34;&gt;Stoyan (1984) Early LISP history
(1956 - 1959) paper&lt;/a&gt;.]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;— &lt;a href=&#34;https://moth.social/@lispm&#34;&gt;lispm&lt;/a&gt;&amp;lsquo;s comment on &lt;a href=&#34;https://www.reddit.com/r/lisp/comments/e467tk/is_it_more_correct_to_say_that_lisp_is_based_on/f99keh3/&#34;&gt;r/lisp&lt;/a&gt; thread on this topic&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There&amp;rsquo;s obviously much more to explore for the early history of Lisp
and the nature of its connections to lambda calculus, but this much at
least should give a general sense of the distinctions/divergences
between Lisp and lambda calculus, while not ignoring important
interconnections between them.&lt;/p&gt;
&lt;h3 id=&#34;reaching-the--of-the-line&#34;&gt;Reaching the &lt;code&gt;&#39;()&lt;/code&gt; of the line&lt;/h3&gt;
&lt;p&gt;And so while it&amp;rsquo;s tempting to delve off into other interesting
features (homoiconicity!) of LISP/Lisps and their history and dialects
(the Common Lisp of Endor; Schemes, Rackets, Chickens and Guile (oh
my!), Clojure, Fennel and others), I&amp;rsquo;d wanted to get to lambda
calculus proper much earlier in this piece already, and so we&amp;rsquo;ll set
our (lispy) parens down for a moment, and trade in our &lt;code&gt;LAMBDA&lt;/code&gt; for a &lt;code&gt;λ&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;cattle-prodding-functions-the-lambda-calculus&#34;&gt;Cattle-prodding functions: the lambda calculus&lt;/h2&gt;
&lt;p&gt;The aforementioned Alonzo Church&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;, a Princeton
mathematician who supervised 31 doctoral students during his career,
influencing others important researchers (including &lt;a href=&#34;https://en.wikipedia.org/wiki/Haskell_Curry&#34;&gt;Haskell Curry&lt;/a&gt; [for
whom the programming language Haskell is named; as well as the
operating of &lt;a href=&#34;https://en.wikipedia.org/wiki/Currying&#34;&gt;currying&lt;/a&gt;]), developed (the) lambda calculus as part of
his research into the foundations of mathematics.&lt;/p&gt;
&lt;p&gt;Lambda calculus is &lt;a href=&#34;https://en.wikipedia.org/wiki/Turing_completeness&#34;&gt;Turing complete&lt;/a&gt;, thus equivalent in computation
power to a Turing machine and a universal model of computation.&lt;/p&gt;
&lt;p&gt;There are very few bits of machinery in basic untyped lambda
calculus. (A reason for which it seemed to be attractive to McCarthy
as a touchstone.)&lt;/p&gt;
&lt;p&gt;Lambda calculus has variables and lambdas; function application; a
reduction operation (which may follow function application); and a
convenience variable-renaming operation.&lt;/p&gt;
&lt;p&gt;More specifically, we have:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;variables&lt;/strong&gt;, like &lt;code&gt;x&lt;/code&gt;, which are characters or strings representing &amp;ldquo;a
parameter&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;lambda abstraction&lt;/strong&gt;: essentially just the definition of a function,
specifying its input (by a bound variable, say, &lt;code&gt;λx&lt;/code&gt;) and returning
an output (say, &lt;code&gt;M&lt;/code&gt;). E.g., the expression &lt;code&gt;λx.M&lt;/code&gt; will take an input,
and replace any and all instances of &lt;code&gt;x&lt;/code&gt; in the body &lt;code&gt;M&lt;/code&gt;&lt;sup id=&#34;fnref:14&#34;&gt;&lt;a href=&#34;#fn:14&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt; with
whatever the input was. (The &lt;code&gt;.&lt;/code&gt; separates the lambda and
specification of bound variable (here &lt;code&gt;x&lt;/code&gt;) (&amp;ldquo;input taker&amp;rdquo;) from the
body (the &amp;ldquo;output&amp;rdquo;).)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;function application&lt;/strong&gt;: a representation like &lt;code&gt;(M N)&lt;/code&gt;, the function &lt;code&gt;M&lt;/code&gt;
applies to &lt;code&gt;N&lt;/code&gt;, where both &lt;code&gt;M&lt;/code&gt; and &lt;code&gt;N&lt;/code&gt; are some sort of lambda terms.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;β-reduction&lt;/strong&gt; (beta reduction): bound variables inside body of the
expression are replaced by inputs &amp;ldquo;taken&amp;rdquo; by the lambda
expressions. The basic form: &lt;code&gt;((λx.M) N)&lt;/code&gt; → &lt;code&gt;(M[x := N])&lt;/code&gt;. (That is, an
expression &lt;code&gt;(λx.M)&lt;/code&gt; combining with an expression &lt;code&gt;N&lt;/code&gt; returns &lt;code&gt;(M)&lt;/code&gt; where
where all instances of &lt;code&gt;x&lt;/code&gt; inside of &lt;code&gt;M&lt;/code&gt; are replaced with &lt;code&gt;N&lt;/code&gt;.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(Setting aside rule 4 for the moment.)&lt;/p&gt;
&lt;p&gt;For example, we might have an expression:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;λf.λx.(f x)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This would be an expression which combines, one at a time, with two
inputs, the lambdas operating from left to right, and then applying
the &lt;code&gt;f&lt;/code&gt; input to the &lt;code&gt;x&lt;/code&gt; input.&lt;/p&gt;
&lt;p&gt;To see this in full working order, we need to specific one of the two
remaining operations (both reduction operations):&lt;/p&gt;
&lt;p&gt;So, turning to rule 4 for β-reduction, taking our expression from
above and providing it with inputs, and walking through the (two)
application+β-reduction steps one at a time:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;((λf.λx.(f x)) b a)&lt;/code&gt; =&lt;/p&gt;
&lt;p&gt;&lt;code&gt;((λx.(b x)) a)&lt;/code&gt; =&lt;/p&gt;
&lt;p&gt;&lt;code&gt;(b a)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That is, first, the leftmost lambda, &lt;code&gt;λf,&lt;/code&gt; &amp;ldquo;takes&amp;rdquo; the leftmost argument &lt;code&gt;b&lt;/code&gt;
(in &amp;ldquo;taking&amp;rdquo; an argument, it &amp;ldquo;discharges&amp;rdquo; and disappears) and the
(single) bound instance of the variable &lt;code&gt;f&lt;/code&gt; in the body is replaced by
&lt;code&gt;b&lt;/code&gt;. Then, the same thing happens with the remaining lambda, &lt;code&gt;λx&lt;/code&gt;, and the
remaining argument, &lt;code&gt;a&lt;/code&gt;. The result is a function where &lt;code&gt;b&lt;/code&gt; applies to
&lt;code&gt;a&lt;/code&gt;. (Though since in this case there are no more lambdas, nothing more
happens.)&lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;(b a)&lt;/code&gt; looks somewhat unexciting/opaque, we can imagine a sort of
hybrid proper untyped lambda calculus/Lisp hybrid language — let&amp;rsquo;s
call this toy language of ours ΛΙΣΠ — and illustrate what things might
look like there (assuming here that numbers are numbers and &lt;code&gt;#&#39;*&lt;/code&gt; is a lispy
prefix multiplication function):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;((λf.λx.λy.(f x y)) #&#39;* 6 7)&lt;/code&gt; =&lt;/p&gt;
&lt;p&gt;&lt;code&gt;((λx.λy.(* x y)) 6 7)&lt;/code&gt; =&lt;/p&gt;
&lt;p&gt;&lt;code&gt;((λy.(* 6 y)) 7)&lt;/code&gt; =&lt;/p&gt;
&lt;p&gt;&lt;code&gt;(* 6 7)&lt;/code&gt; =&lt;/p&gt;
&lt;p&gt;&lt;code&gt;42&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This isn&amp;rsquo;t how mathematics works in classical untyped lambda calculus
— because we only have the 4 rules/entities enumerated above [plus a
variable-clash reduction operation called α-reduction]&lt;sup id=&#34;fnref:15&#34;&gt;&lt;a href=&#34;#fn:15&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;15&lt;/a&gt;&lt;/sup&gt; and nothing
else&lt;sup id=&#34;fnref:16&#34;&gt;&lt;a href=&#34;#fn:16&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;16&lt;/a&gt;&lt;/sup&gt;: no integers, no stipulated mathematical operations, no &lt;code&gt;car&lt;/code&gt; or
&lt;code&gt;cdr&lt;/code&gt; or &lt;code&gt;cons&lt;/code&gt; or &lt;code&gt;eq&lt;/code&gt; or anything — we can do all of these things in
lambda calculus with the tools we have, and we&amp;rsquo;ll explore that in
another post, but for now I just wanted to show you the toy ΛΙΣΠ
language snippet as I find something that feels a bit more familiar
and concrete can be helpful for understanding the notional unpinnings
of what&amp;rsquo;s going on in lambda calculus.&lt;/p&gt;
&lt;h3 id=&#34;ok-so-there-s-no-integers-or-cars-but-what-s-all-this-about-cattle-prods&#34;&gt;Ok, so there&amp;rsquo;s no integers or cars, but what&amp;rsquo;s all this about cattle prods?&lt;/h3&gt;
&lt;p&gt;Well, why is &lt;code&gt;λ&lt;/code&gt; / &lt;code&gt;LAMBDA&lt;/code&gt; the &amp;ldquo;function&amp;rdquo;-making operator? Maybe just
eeny-meeny-miney-moe amongst Greek letters, but at least at one point
Church explained that [A. Church, 7 July 1964. Unpublished letter to
Harald Dickson, §2] that it came from the notation “x̂” used for
class-abstraction by Whitehead and Russell in their &lt;em&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Principia_Mathematica&#34;&gt;Principia
Mathematica&lt;/a&gt;&lt;/em&gt; (which we&amp;rsquo;re refer to later on), by first modifying “x̂” to
“^⁣x” to (and then for better visibility to “∧x”) to distinguish
function-abstraction from class-abstraction, and then changing “∧”
(which is similar to uppercase Greek &amp;ldquo;Λ&amp;rdquo;) to (lowercase Greek) “λ” for
ease of printing (and presumably to avoid confusion with other
mathematical uses of &amp;ldquo;∧&amp;rdquo;, e.g., logical AND).&lt;sup id=&#34;fnref:17&#34;&gt;&lt;a href=&#34;#fn:17&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;17&lt;/a&gt;&lt;/sup&gt;
[So maybe &amp;ldquo;x̂&amp;rdquo; ⇒ &amp;ldquo;^⁣x&amp;rdquo; → &amp;ldquo;∧x&amp;rdquo; → &amp;ldquo;λx&amp;rdquo;.]&lt;/p&gt;
&lt;p&gt;The Greek lambda (uppercase Λ, lowercase λ) as an ortheme itself
derives ultimately from a Semitic abjad, specifically from the
Phoenician &lt;em&gt;lāmd&lt;/em&gt; &lt;strong&gt;𐤋&lt;/strong&gt;, which (like most letters began as a pictogram of
sorts) is considered to originate from something like an ox-goad,
i.e., a cattle prod, or else a shepherd&amp;rsquo;s crook, i.e., a pastoral
staff. (The reconstructed Proto-Semitic word &lt;em&gt;*lamed-&lt;/em&gt; means a
&amp;ldquo;goad&amp;rdquo;.)&lt;sup id=&#34;fnref:18&#34;&gt;&lt;a href=&#34;#fn:18&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;18&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;are-we-in-platonic-heaven-yet&#34;&gt;Are We in Platonic Heaven Yet?&lt;/h3&gt;
&lt;p&gt;Lambda calculus, not being tied to any particular hardware and being a
true formula abstraction, feels like something that might have a
better claim to being something like a property of the universe that
one might discover (I admit I find it hard not to feel something of
the sort — but then I&amp;rsquo;ve used lambda calculus for work on natural
language within a framework that wants to assign some sort of reality
to our formalisations, so it&amp;rsquo;s hard not to be pulled in this
direction), however, Church says (of his own formalism):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We do not attach any character of uniqueness or absolute truth to any
particular system of logic. The entities of formal logic are
abstractions, invented because of their use in describing and
systematizing facts of experience or observation, and their
properties, determined in rough outline by this intended use, depend
for their exact character on the arbitrary choice of the inventor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[Alonzo Church 1932:348&lt;sup id=&#34;fnref:19&#34;&gt;&lt;a href=&#34;#fn:19&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;19&lt;/a&gt;&lt;/sup&gt;]&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(This seems part of Church&amp;rsquo;s constructivist philosophy, in
common with Frege.)&lt;sup id=&#34;fnref:20&#34;&gt;&lt;a href=&#34;#fn:20&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;20&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;what-s-next-λy-dot--equal-cdr-l--y&#34;&gt;What&amp;rsquo;s &lt;code&gt;next&lt;/code&gt;? : &lt;code&gt;λy.(equal? (cdr L) y)&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ve pulled at a lot of disparate threads here, trying to explore
the nature of the connections between Lisp and (the) lambda
calculus. Neither the idea that Lisp is a direct instantiation of
lambda calculus nor the idea that McCarthy was largely ignorant of
properties of lambda calculus are quite right. But that there are an
interesting interplay of connections.&lt;/p&gt;
&lt;p&gt;But. This is really to set the stage for me to talk about things I&amp;rsquo;m
interested in which draw on different aspects of Lisp(s) and lambda
calculus and formal or applied applications to do with one or the
other.&lt;/p&gt;
&lt;p&gt;I was going to talk about &lt;a href=&#34;https://en.wikipedia.org/wiki/Montague_grammar&#34;&gt;Montague Grammar&lt;/a&gt;, because it&amp;rsquo;s fascinating
(and it&amp;rsquo;s my day job), for which lambda calculus is a crucial
component.&lt;sup id=&#34;fnref:21&#34;&gt;&lt;a href=&#34;#fn:21&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;21&lt;/a&gt;&lt;/sup&gt; But we&amp;rsquo;re at length now, so it should be
another day.&lt;/p&gt;
&lt;p&gt;What I do want to look at next is a combination of Lisp and lambda
calculus, in various ways, starting with attempts to implement aspects
of lambda calculus in Emacs Lisp, and the challenges therein.&lt;/p&gt;
&lt;p&gt;[fingers crossed that &lt;code&gt;(next &#39;blog)&lt;/code&gt; does not eval to &lt;code&gt;undefined&lt;/code&gt;.]&lt;/p&gt;
&lt;p&gt;(Update: &lt;code&gt;(eval (next &#39;blog))&lt;/code&gt;: &lt;a href=&#34;https://babbagefiles.xyz/lambda-calculus-and-lisp-02-recursion/&#34;&gt;Part 2: Recursion Excursion&lt;/a&gt;.)&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;McCarthy, John. 1960. Recursive functions of symbolic
expressions and their computation by machine. &lt;em&gt;Communications of the
Association for Computing Machinery&lt;/em&gt; 3(4):184-195. [&lt;a href=&#34;https://web.archive.org/web/20131006003734/http://www-formal.stanford.edu/jmc/recursive.html&#34;&gt;available at the
Wayback Archive&lt;/a&gt;; page nos. refer to those of the PDF at the link,
a reformatted version in LaTeX, not those of the original publication.] &lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;On Lisp&amp;rsquo;s mystical aura, see &lt;a href=&#34;https://twobithistory.org/2018/10/14/lisp.html&#34;&gt;How Lisp Became God&amp;rsquo;s
Own Programming Language&lt;/a&gt; (and the associated &lt;a href=&#34;https://news.ycombinator.com/item?id=23163596&#34;&gt;Hacker News discussion&lt;/a&gt;). &lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://danielsz.github.io/blog/2019-08-05T21_14.html&#34;&gt;&amp;ldquo;Lisp ≠ Lambda Calculus&amp;rdquo; | Daniel Szmulewicz: Perfumed
nightmare (A blog for the somnambulisp)&lt;/a&gt; &lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;McCarthy, John. 1978b. Transcript of presentation. History of Lisp. In &lt;em&gt;History of
programming languages&lt;/em&gt;, ed. Richard L. Wexelblat, 185–191. New York:
Association for Computing Machinery. &lt;a href=&#34;https://dl.acm.org/doi/10.1145/800025.1198361&#34;&gt;https://dl.acm.org/doi/10.1145/800025.1198361&lt;/a&gt; &lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;McCarthy, John. 1978a. History of Lisp. In &lt;em&gt;History of
programming languages&lt;/em&gt;, ed. Richard L. Wexelblat, 173–185. New York:
Association for Computing Machinery. &lt;a href=&#34;https://dl.acm.org/doi/10.1145/800025.1198360&#34;&gt;https://dl.acm.org/doi/10.1145/800025.1198360&lt;/a&gt; &lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Graham, Paul. 2002. The Roots of Lisp. Ms.,
&lt;a href=&#34;https://paulgraham.com/rootsoflisp.html&#34;&gt;https://paulgraham.com/rootsoflisp.html&lt;/a&gt;. [&lt;a href=&#34;https://web.archive.org/web/20240222160957/http://slackwise.net/files/docs/The%20Roots%20of%20Lisp.pdf&#34;&gt;PDF version&lt;/a&gt;] &lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;See, e.g., Graham&amp;rsquo;s 2001 &lt;a href=&#34;https://www.paulgraham.com/avg.html&#34;&gt;&amp;ldquo;Beating the Averages&amp;rdquo;&lt;/a&gt;. &lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;On the &amp;ldquo;Curse of Lisp&amp;rdquo;, see for instance Rudolf
Winestock&amp;rsquo;s &lt;a href=&#34;https://winestockwebdesign.com/Essays/Lisp_Curse.html&#34;&gt;&amp;ldquo;The Lisp Curse&amp;rdquo;&lt;/a&gt;; but also &lt;a href=&#34;https://old.reddit.com/r/Clojure/comments/qq0xh9/what_is_the_curse_of_lisp_in_simple_terms/&#34;&gt;this 2021 discussion on
r/clojure&lt;/a&gt;, where it&amp;rsquo;s mentioned that Winestock said in 2017 in &lt;a href=&#34;https://news.ycombinator.com/item?id=14480157&#34;&gt;a
comment&lt;/a&gt; on (one of the innumerable) Hacker News threads on the topic
&amp;ldquo;I wrote that essay five years ago. Nowadays, just use Clojure or
Racket and ignore what I&amp;rsquo;ve written.&amp;rdquo; &lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;J. McCarthy: LISP History. Talk at MIT, Spring or Summer
1974 (Written from tape 7/10/75, unpublished: cited in Stoyan,
Herbert. 1984. Early LISP history (1956 - 1959). &lt;em&gt;LFP &amp;lsquo;84: Proceedings
of the 1984 ACM Symposium on LISP and functional programming&lt;/em&gt;,
eds. Robert S. Boyer, Edward S. Schneider, Guy L. Steele, 299–310. New
York: Association for Computing
Machinery. [&lt;a href=&#34;https://doi.org/10.1145/800055.802047&#34;&gt;https://doi.org/10.1145/800055.802047&lt;/a&gt;]) (Quote from p.307.) &lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Descriptively:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;(quote x)&lt;/code&gt;  returns (the symbol) &lt;code&gt;x&lt;/code&gt; (rather than the value of &lt;code&gt;x&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(atom x)&lt;/code&gt;  returns &lt;code&gt;t&lt;/code&gt; if the value of &lt;code&gt;x&lt;/code&gt; is an atom or else &lt;code&gt;&#39;()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(eq x y)&lt;/code&gt;  returns &lt;code&gt;t&lt;/code&gt; if the values of &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; are the same atom, or both the empty list; otherwise returns &lt;code&gt;()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(car x)&lt;/code&gt;  expects the value of &lt;code&gt;x&lt;/code&gt; to be &lt;code&gt;cons&lt;/code&gt; expression of some sort, like a list, and returns its first element.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(cdr x)&lt;/code&gt;  expects the value of &lt;code&gt;x&lt;/code&gt; to be &lt;code&gt;cons&lt;/code&gt; expression of some sort, like a list, and returns everything after the first element.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(cons x y)&lt;/code&gt;  returns an object composed of a link between &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;; this is how lists are formed, if the second argument of the innermost &lt;code&gt;cons&lt;/code&gt; is &lt;code&gt;()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(cond (p₁ e₁)…(pₙ eₙ))&lt;/code&gt;  evaluates the &lt;code&gt;p&lt;/code&gt; expressions in order until one returns &lt;code&gt;t&lt;/code&gt;, at which point it returns the co-indexed &lt;code&gt;e&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;((lambda (p₁…pₙ) e) a₁…aₙ)&lt;/code&gt;  evaluates each &lt;code&gt;aᵢ&lt;/code&gt; expression and replaces the occurrence of all occurrences of each &lt;code&gt;pᵢ&lt;/code&gt; in &lt;code&gt;e&lt;/code&gt; with the value of the corresponding &lt;code&gt;aᵢ&lt;/code&gt; expression, and then evaluates &lt;code&gt;e&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(label f (lambda (p₁…pₙ) e))&lt;/code&gt;  makes all occurrences of the symbol &lt;code&gt;f&lt;/code&gt; behave like the following &lt;code&gt;(lambda (p₁…pₙ) e)&lt;/code&gt; expression, including inside of &lt;code&gt;e&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
 &lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:11&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;With just tad bits more sugar to reduce &lt;code&gt;car&lt;/code&gt; / &lt;code&gt;cdr&lt;/code&gt;
recursion spam:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;caar&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;cadr&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;caddr&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;cadar&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;caddar&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:12&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;See McCarthy, John, Paul W. Abrahams, Daniel J. Edwards, Timothy&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Hart, and Michael I. Levin. 1962. /LISP 1.5 Programmer&amp;rsquo;s&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Manual/. Cambridge, Mass.: M.I.T. Press [&lt;a href=&#34;https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf&#34;&gt;pdf&lt;/a&gt;], at p.36f and also
McCarthy (1960:26–7), as well as the &lt;a href=&#34;https://en.wikipedia.org/wiki/CAR_and_CDR&#34;&gt;Wikipedia page on CAR and CDR&lt;/a&gt;. &lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Church is also well-known for his proof that the
Entscheidungsproblem is undecidable (Church&amp;rsquo;s theorem), the
&lt;a href=&#34;https://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis&#34;&gt;Church-Turing thesis&lt;/a&gt;, the &lt;a href=&#34;https://en.wikipedia.org/wiki/Frege%E2%80%93Church_ontology&#34;&gt;Frege-Church ontology&lt;/a&gt;, amongst much else. I
don&amp;rsquo;t know any particularly interesting details of his personal life
(he was no Richard Montague, about whom more later); he was apparently a
lifelong Presbyterian. &lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;The &lt;code&gt;M&lt;/code&gt; here can be standing in for something more complex,
e.g., the whole expression might really be &lt;code&gt;λx.(a (b d))&lt;/code&gt;, where &lt;code&gt;M&lt;/code&gt; here
is a place-holder for &lt;code&gt;(a (b d))&lt;/code&gt;. &lt;a href=&#34;#fnref:14&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:15&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;The &lt;strong&gt;α-conversion&lt;/strong&gt; (fifth) rule is: bound variables can be
substituted with different bound variables. So, &lt;code&gt;λx.M[x]&lt;/code&gt; can be
α-converted to &lt;code&gt;λy.M[y]&lt;/code&gt;. Bound variable names have no significance
except as place-holders, so these two expressions are equivalent. The
reason for doing this is to avoid name-clashes (see &lt;a href=&#34;https://martinfowler.com/bliki/TwoHardThings.html&#34;&gt;Two Hard Things&lt;/a&gt;?)
when combining expressions.&lt;/p&gt;
&lt;p&gt;E.g., if we wanted to combine &lt;code&gt;λxλy.(x y)&lt;/code&gt;
with itself, e.g. &lt;code&gt;((λxλy.(x y)) (λxλy.(x y)))&lt;/code&gt; (this is of the function
application form &lt;code&gt;(M N)&lt;/code&gt;), we could do α-conversion so we don&amp;rsquo;t end up
with accidental variable capture.&lt;/p&gt;
&lt;p&gt;If we didn&amp;rsquo;t this would happen:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;((λxλy.(x y)) (λxλy.(x y)))&lt;/code&gt; =&lt;/p&gt;
&lt;p&gt;&lt;code&gt;((λy.((λxλy.(x y)) y))&lt;/code&gt; =&lt;/p&gt;
&lt;p&gt;&lt;code&gt;(λy.(λy.(y y))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Since variables are arbitrary names, whose point is distinctionness,
we need instead to α-convert on one of the expressions:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;λxλy.(x y)&lt;/code&gt; = (by α-conversion)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;λaλb.(a b)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And then we can combine as we tried to before, and correctly arrive at:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;((λxλy.(x y)) (λaλb.(a b)))&lt;/code&gt; =&lt;/p&gt;
&lt;p&gt;&lt;code&gt;(λy.((λaλb.(a b)) y))&lt;/code&gt; =&lt;/p&gt;
&lt;p&gt;&lt;code&gt;λy.(λb.(y b))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;(We&amp;rsquo;ll talk more about α-conversion and its implement in a later post.) &lt;a href=&#34;#fnref:15&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:16&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Well, there&amp;rsquo;s also (optional/debated) sixth rule:
&lt;strong&gt;η-conversion&lt;/strong&gt;, which touches on some more philosophical concerns
(though ones which will eventually concern us too), to do with
&lt;a href=&#34;https://en.wikipedia.org/wiki/Extensionality&#34;&gt;extensionality&lt;/a&gt; (vs. &lt;a href=&#34;https://en.wikipedia.org/wiki/Intension&#34;&gt;intensionality&lt;/a&gt;) [essentionally &lt;a href=&#34;https://en.wikipedia.org/wiki/Sense_and_reference&#34;&gt;Frege&amp;rsquo;s Sinn und
Bedeutung&lt;/a&gt;].&lt;/p&gt;
&lt;p&gt;η-conversion says that in a case where &lt;code&gt;(f x) = (g x)&lt;/code&gt; for all possible
values of &lt;code&gt;x&lt;/code&gt;, then &lt;code&gt;f&lt;/code&gt; = &lt;code&gt;g&lt;/code&gt;. It&amp;rsquo;s not always something which is
implemented, and it raises questions around extensionality vs
intensionality vs hyperintensionality we&amp;rsquo;ll probably touch on a later
point.&lt;/p&gt;
&lt;p&gt;But, for a taste, by η-conversion (because it&amp;rsquo;s about extensionality,
roughly what&amp;rsquo;s true in the world rather than conceptually), the
following two expressions are identical (&lt;code&gt;G&lt;/code&gt; has an extra component
involving an identity function):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;F = λx.x&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;G = λx.(λy.y)x&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Do they conceptuality (intensionally) count as the same function, &lt;code&gt;F&lt;/code&gt;
and &lt;code&gt;G&lt;/code&gt;? No, perhaps, but their extensions are the same (they&amp;rsquo;re always
produce the same results), and so &lt;code&gt;F&lt;/code&gt; counts as the α-reduction of &lt;code&gt;G&lt;/code&gt;. &lt;a href=&#34;#fnref:16&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:17&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;On the Church λ story, see Cardone, Felice &amp;amp; Hindley,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Roger, 2006. History of Lambda-calculus and Combinatory Logic. In&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Gabbay and Woods (eds.), &lt;em&gt;Handbook of the History of Logic&lt;/em&gt;,
vol. 5. Elsevier. [&lt;a href=&#34;https://web.archive.org/web/20210506154120/http://www.users.waitrose.com/~hindley/SomePapers_PDFs/2006CarHin,HistlamRp.pdf&#34;&gt;pdf&lt;/a&gt;] On uses of ∧ as notation in formal theories,
see &lt;a href=&#34;https://en.wikipedia.org/wiki/Wedge_(symbol)#Use&#34;&gt;here&lt;/a&gt;. &lt;a href=&#34;#fnref:17&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:18&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://en.wikipedia.org/wiki/Lamedh&#34;&gt;Wikipedia on Lamedh&lt;/a&gt;. &lt;a href=&#34;#fnref:18&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:19&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Church, Alonzo. 1932. A set of postulates for the
foundation of logic. &lt;em&gt;Annals of mathematics&lt;/em&gt; 33(2):346-366. [&lt;a href=&#34;https://web.archive.org/web/20240123184324/https://raw.githubusercontent.com/emintham/Papers/master/Church-%20A%20Set%20of%20Postulates%20for%20the%20Foundation%20of%20Logic.pdf&#34;&gt;pdf&lt;/a&gt;] &lt;a href=&#34;#fnref:19&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:20&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Thanks to &lt;a href=&#34;https://philpeople.org/profiles/e-j-slade&#34;&gt;Dr E.J. Slade&lt;/a&gt; for discussion on this point
(Church&amp;rsquo;s constructivism, and the connection with Frege&amp;rsquo;s positions). &lt;a href=&#34;#fnref:20&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:21&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;And one I&amp;rsquo;ve worked on implementing &lt;strong&gt;in a Lisp&lt;/strong&gt; at various
points, e.g., &lt;a href=&#34;https://gitlab.com/emacsomancer/frege&#34;&gt;Frege&lt;/a&gt;, the beginnings of a Racket-based DSL for natural
language semantics. &lt;a href=&#34;#fnref:21&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lambdacalculus">lambdacalculus</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/lambda-calculus-and-lisp-01/</guid>
                <pubDate>Tue, 18 Feb 2025 03:05:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Group-agnostic previous-focussed-window memory in StumpWM</title>
                <link>https://babbagefiles.xyz/agnostic-focus-stumpwm/</link>
                
                
                <description>&lt;p&gt;I&amp;rsquo;ve started using StumpWM&amp;rsquo;s groups (like &amp;ldquo;workspaces&amp;rdquo; in other window
managers) more extensively, but this broke a behaviour I like: the
ability to easily switch back to the last focussed window, because
StumpWM&amp;rsquo;s &amp;ldquo;last focussed&amp;rdquo; is group-specific. So I wasn&amp;rsquo;t easily about
to switch quickly back and forth between two windows that were inb
different groups, which turns out to be something I frequently want to
do (e.g. switch back and forth between an emacsclient frame in my
&amp;ldquo;emacs&amp;rdquo; group and a Firefox instance in my &amp;ldquo;web&amp;rdquo; group).&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s my fix [updated with some fixes on &lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2025-01-27 Mon]&lt;/span&gt;&lt;/span&gt;]:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; Global &amp;#39;last focussed window&amp;#39;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-ante-earlier-focussed-window*&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-earlier-focussed-window*&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-prev-focussed-window*&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-cur-focussed-window*&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;panrecord-of-last-focussed-window&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;currwin&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;lastwin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Record last visited windows and their group.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;search&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*EQUAKE*[&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;window-name&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;currwin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;;; don&amp;#39;t record Equake&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-cur-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-window-globally&lt;/span&gt;
           &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;screen-groups&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-screen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-ante-earlier-focussed-window*&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-window-globally&lt;/span&gt;
           &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-prev-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;screen-groups&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-screen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-earlier-focussed-window*&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-prev-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-window-globally&lt;/span&gt;
           &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-cur-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;screen-groups&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-screen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-prev-focussed-window*&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-cur-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-cur-focussed-window*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;cons&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;currwin&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;find-window-globally&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;group-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Check for presence of window in all groups.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;group-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;ss&#34;&gt;&amp;#39;nil&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;member&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;window&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;group-windows&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;group-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
          &lt;span class=&#34;nv&#34;&gt;window&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-window-globally&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;window&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;group-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;defcommand&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;switch-to-last-focussed-window&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Switch to last focussed window, irrespective of which group it is in and what group we&amp;#39;re currently in.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;progn&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-cur-focussed-window*&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-prev-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt;
       &lt;span class=&#34;c1&#34;&gt;;; we&amp;#39;re in the same group [same logic below]&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;screen-groups&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-screen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-prev-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
       &lt;span class=&#34;c1&#34;&gt;;; or we can switch to the previous group&lt;/span&gt;
       &lt;span class=&#34;vg&#34;&gt;*global-prev-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;progn&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-group&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-prev-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;focus-window&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-prev-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-cur-focussed-window*&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;screen-groups&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-screen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;vg&#34;&gt;*global-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;progn&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-group&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;focus-window&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-cur-focussed-window*&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-ante-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;screen-groups&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-screen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-ante-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
         &lt;span class=&#34;vg&#34;&gt;*global-ante-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;progn&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-group&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-ante-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;focus-window&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*global-ante-earlier-focussed-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;No window to switch to.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*focus-window-hook*&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;panrecord-of-last-focussed-window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; my binding; set as you will&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*root-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;s-f&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;switch-to-last-focussed-window&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;unless&lt;/code&gt; statement in &lt;code&gt;panrecord-of-last-focussed-window&lt;/code&gt; prevents
my drop-down terminal &lt;a href=&#34;https://babbagefiles.xyz/categories/stumpwm&#34;&gt;Equake&lt;/a&gt; &amp;ldquo;window&amp;rdquo; from &amp;ldquo;counting&amp;rdquo; for history
tracking purposes.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;switch-to-last-focussed-window&lt;/code&gt; function essentially just switches
to the last focussed window, after making sure it still exists. (If
not, switch to the window which was focussed before that one, or the
one before that one, or else don&amp;rsquo;t switch and display message
indicating this to the user.)&lt;/p&gt;
&lt;p&gt;The last line, &lt;code&gt;(define-key *root-map* (kbd &amp;quot;s-f&amp;quot;) &amp;quot;switch-to-last-focussed-window&amp;quot;)&lt;/code&gt;, means that I can double tap &lt;code&gt;s-f&lt;/code&gt;
(since my StumpWM prefix key is set to &lt;code&gt;s-f&lt;/code&gt; with &lt;code&gt;(set-prefix-key (kbd &amp;quot;s-f&amp;quot;))&lt;/code&gt;) to switch to the last focussed window, no matter which group
it belongs to.&lt;/p&gt;
&lt;p&gt;I continue to really enjoy the power that StumpWM&amp;rsquo;s Common Lisp
underpinnings provides the user!&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/stumpwm">stumpwm</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/commonlisp">commonlisp</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/agnostic-focus-stumpwm/</guid>
                <pubDate>Sat, 25 Apr 2020 14:25:00 -0500</pubDate>
            </item>
        
            
            <item>
                <title>Running pdfpc in StumpWM</title>
                <link>https://babbagefiles.xyz/pdfpc-in-stumpwm/</link>
                
                
                <description>&lt;p&gt;&lt;a href=&#34;https://pdfpc.github.io/&#34;&gt;&lt;code&gt;pdfpc&lt;/code&gt;&lt;/a&gt; is a fantastic application for presenting PDF slides,
including perhaps especially those produced using &lt;a href=&#34;https://ctan.org/pkg/beamer&#34;&gt;LaTeX Beamer&lt;/a&gt;. It
creates two (full-screen) windows, one a presenter viewer which shows
the time elapsed and a preview of the next slide, and one the
presentation view which is what is shown to the audience. It also has
a bunch of other cool features like being able to draw on slides;
highlight areas of slides, &amp;amp;c.&lt;/p&gt;
&lt;p&gt;Here is an example, with the presenter&amp;rsquo;s view shown on the left; the
audience&amp;rsquo;s view on the right:&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/pdfpc-screenshot01.png&#34;/&gt; &lt;/figure&gt;

&lt;p&gt;In many environments &lt;code&gt;pdfpc&lt;/code&gt; is pretty smart about getting the
presentation view to the external display, but in StumpWM both end up
getting created in the same frame in the same display.&lt;/p&gt;
&lt;p&gt;(General tip: in StumpWM, after connecting/activating an external
display, you may need to run &lt;a href=&#34;https://stumpwm.github.io/git/stumpwm-git_9.html#External-Monitors&#34;&gt;&lt;code&gt;refresh-heads&lt;/code&gt;&lt;/a&gt; to get StumpWM to display
things properly.)&lt;/p&gt;
&lt;p&gt;For whatever reason, I can&amp;rsquo;t get any of the &lt;a href=&#34;https://stumpwm.github.io/git/stumpwm-git_9.html&#34;&gt;Screen-related things&lt;/a&gt; in
StumpWM to behave like I have more than one
screen. E.g. &lt;code&gt;*screen-list*&lt;/code&gt; shows a singleton list even when an
external display is connected and activated:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;nv&#34;&gt;STUMPWM&amp;gt;&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*screen-list*&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;S&amp;lt;screen&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&amp;lt;XLIB:SCREEN&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:0.0&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;1366x768x24&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;TRUE-COLOR&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A passable solution is to use &lt;a href=&#34;https://stumpwm.github.io/git/stumpwm-git_5.html#Rule-Based-Window-Placement&#34;&gt;&lt;code&gt;define-frame-preference&lt;/code&gt;&lt;/a&gt;, adding the
following to your &lt;code&gt;init.lisp&lt;/code&gt; StumpWM configuration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; pdfpc rule - for &amp;#39;Default&amp;#39; group&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;;  move to frame &amp;#39;1&amp;#39;;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;;  non-focussing (&amp;#39;nil) the presentation view;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;;  not only matching (t) the target-group (&amp;#39;Default&amp;#39;);&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;;  moving the &amp;#39;pdfpc&amp;#39; &amp;#39;presentation&amp;#39; window&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-frame-preference&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Default&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:instance&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;pdfpc&amp;#34;&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:role&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;presentation&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This should properly move the presentation window to the external
display when &lt;code&gt;pdfpc&lt;/code&gt; is run.&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/stumpwm">stumpwm</category>
                                
                            
                        
                     
                        
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/tags/pdfpc">pdfpc</category>
                                 
                                    <category domain="https://babbagefiles.xyz/tags/pdf">pdf</category>
                                 
                                    <category domain="https://babbagefiles.xyz/tags/presentation">presentation</category>
                                 
                                    <category domain="https://babbagefiles.xyz/tags/beamer">beamer</category>
                                
                            
                        
                    
                
                <guid>https://babbagefiles.xyz/pdfpc-in-stumpwm/</guid>
                <pubDate>Mon, 29 Jul 2019 15:27:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Guix, Nix: You are in a maze of twisty little $PATHs, some undefined</title>
                <link>https://babbagefiles.xyz/guix-nix-maze-of-twisty-little-paths-undefined/</link>
                
                
                <description>&lt;p&gt;Some notes on interactive fiction/text adventure games and PATHs in
Guix, and StumpWM.&lt;/p&gt;
&lt;h2 id=&#34;maze-no-dot-1&#34;&gt;Maze no. 1&lt;/h2&gt;
&lt;p&gt;There may (likely is) some way of programmatically setting the X
Windows PATH variable in Guix System (née GuixSD) via the base
configuration (e.g. &lt;code&gt;config.scm&lt;/code&gt;), but I haven&amp;rsquo;t been able to uncover
anything that works. This is relevant for being able to use locally
installed static binaries or local shell scripts via the window
manager.&lt;/p&gt;
&lt;p&gt;As a window-manager-specific workaround, in StumpWM, one can
programmatically set PATH variables via &lt;code&gt;(setf (getenv &amp;quot;VARIABLE_NAME&amp;quot;) &amp;quot;variable-value&amp;quot;)&lt;/code&gt;. Thus, if you store local static
binaries and shell scripts in &lt;code&gt;~/bin&lt;/code&gt;, the following (which you could
include in StumpWM&amp;rsquo;s &lt;code&gt;init.lisp&lt;/code&gt;) will add that to your PATH variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;getenv&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;PATH&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;concat&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;/home/YOURUSERNAME/bin:&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;getenv&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;PATH&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I use this with a static Haskell binary &lt;a href=&#34;https://github.com/erebe/greenclip&#34;&gt;greenclip&lt;/a&gt;, which adds clipboard
functionality to &lt;a href=&#34;https://github.com/davatorium/rofi/&#34;&gt;rofi&lt;/a&gt;, and with shell scripts that give &amp;ldquo;pretty names&amp;rdquo;
to Flatpak run commands.&lt;/p&gt;
&lt;p&gt;For example, the literate/natural-language-based programming
interactive fiction design language &lt;a href=&#34;http://inform7.com/&#34;&gt;Inform7&lt;/a&gt; (which is due to be
&lt;a href=&#34;http://inform7.com/talks/2019/06/14/narrascope.html&#34;&gt;open-sourced sometime this year&lt;/a&gt;) is now conveniently &lt;a href=&#34;https://flathub.org/apps/details/com.inform7.IDE&#34;&gt;available as a
Flatpak&lt;/a&gt;. But the run command after installing is &lt;code&gt;flatpak run com.inform7.IDE&lt;/code&gt;, which is non-ideal. So I made a simple shell script
named &lt;code&gt;inform7&lt;/code&gt; placed in &lt;code&gt;~/bin&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;flatpak run com.inform7.IDE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/inform7-guix.png&#34;/&gt; &lt;/figure&gt;

&lt;h2 id=&#34;maze-no-dot-2&#34;&gt;Maze no. 2&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://nixos.org/&#34;&gt;Nix&lt;/a&gt; can be &lt;a href=&#34;https://nixos.org/releases/nix/nix-1.9/manual/#ch-installing-binary&#34;&gt;installed as a standalone package manage on top of other
distros&lt;/a&gt;, including Guix System, which is useful for be able to obtain
software currently lacking in Guix System (including, ironically,
&lt;a href=&#34;https://en.wikipedia.org/wiki/Hugo_(software)&#34;&gt;Hugo&lt;/a&gt;, used by this blog, which is present in Nix). Packages available
in Nix but not in Guix include &lt;a href=&#34;http://ccxvii.net/gargoyle/&#34;&gt;Gargoyle&lt;/a&gt;, a very nice interactive
fiction front-end client that supports a number of different backends,
including Frotz and Glulxe. One of the benefits of Gargoyle is that it
&amp;ldquo;cares about typography&amp;rdquo;. However, Nix applications by default seem to
have trouble finding/seeing fonts, including system fonts, local
fonts, and even fonts installed via Nix.&lt;/p&gt;
&lt;p&gt;This can be fixed by (1) setting the &lt;code&gt;FONTCONFIG_PATH&lt;/code&gt; and
&lt;code&gt;FONTCONFIG_FILE&lt;/code&gt;, e.g. in StumpWM this can be done with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;getenv&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;FONTCONFIG_PATH&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;/home/YOURUSERNAME/.config/fontconfig/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;getenv&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;FONTCONFIG_FILE&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;fonts.conf&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And (2) forcing Nix to look in the right places by manual
specification in &lt;code&gt;~/.config/fontconfig/fonts.conf&lt;/code&gt;, adding right
before the final &lt;code&gt;&amp;lt;/fontconfig&amp;gt;&lt;/code&gt; (as appropriate):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;&amp;lt;cachedir prefix=&amp;quot;xdg&amp;quot;&amp;gt;fontconfig&amp;lt;/cachedir&amp;gt;
&amp;lt;dir&amp;gt;/home/YOURUSERNAME/.local/share/fonts/&amp;lt;/dir&amp;gt;
&amp;lt;dir&amp;gt;/home/YOURUSERNAME/.nix-profile/share/fonts/&amp;lt;/dir&amp;gt;
&amp;lt;dir&amp;gt;/home/YOURUSERNAME/.guix-profile/share/fonts/&amp;lt;/dir&amp;gt;
&amp;lt;dir&amp;gt;/usr/share/fonts&amp;lt;/dir&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And regenerating the font cache (via &lt;code&gt;fc-cache -fv&lt;/code&gt;) [possibly you may
need to install Nix&amp;rsquo;s &lt;code&gt;fontconfig&lt;/code&gt; package].&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/counterfeit-gargoyle-screenshot.png&#34;/&gt; &lt;/figure&gt;

</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/guix">guix</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/linux">linux</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/stumpwm">stumpwm</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/intfic">intfic</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/fonts">fonts</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/inform">inform</category>
                                
                            
                        
                     
                        
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/tags/nix">nix</category>
                                 
                                    <category domain="https://babbagefiles.xyz/tags/gargoyle">gargoyle</category>
                                
                            
                        
                    
                
                <guid>https://babbagefiles.xyz/guix-nix-maze-of-twisty-little-paths-undefined/</guid>
                <pubDate>Wed, 24 Jul 2019 00:48:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Equake(!) Quake-style overlay console in StumpWM</title>
                <link>https://babbagefiles.xyz/equake-in-stumpwm/</link>
                
                
                <description>&lt;p&gt;I&amp;rsquo;ve been alternatively using both KDE Plasma 5 and StumpWM on various
machines and have got a working model for using &lt;a href=&#34;https://babbagefiles.xyz/equake-elisp-console/&#34;&gt;the Equake drop-down&lt;/a&gt;
in StumpWM.&lt;/p&gt;
&lt;p&gt;The StumpWM &lt;code&gt;#&#39;invoke-equake&lt;/code&gt; command hides (using StumpWM native
&lt;code&gt;hide-window&lt;/code&gt;, rather than Emacs&amp;rsquo;s &lt;code&gt;make-frame-invisible&lt;/code&gt; as the
latter creates various issues in finding and fetching the Equake
window) the Equake frame if it&amp;rsquo;s the currently active window; it
searches through all windows in all groups on the current
screen/monitor, and calls &lt;code&gt;emacsclient -n -e &#39;(equake-invoke)&#39;&lt;/code&gt; to
create an Equake frame if no extant Equake window is found; and if an
Equake window does already exist for the current screen, it is yanked
into the current group, pulled into the current frame, and unhidden (if
necessary).&lt;/p&gt;
&lt;p&gt;This seems to work pretty well, though I haven&amp;rsquo;t figured out how to
have StumpWM &amp;lsquo;skip&amp;rsquo; the Equake frame when cycling through Emacs
windows. (And, of course, having a proper partial height floating
Equake window would be ideal.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; Here&amp;rsquo;s a better, more Quake-like set-up, which actually makes
use of recently added partial-height floating windows in non-floating
groups:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calc-equake-width&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;screen-width&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;caddr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;with-input-from-stringp&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient -n -e &amp;#39;(equake-find-workarea-of-current-screen (equake-calculate-mouse-location (display-monitor-attributes-list)) (display-monitor-attributes-list))&amp;#39;&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;read&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;desired-width-perc&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;read-from-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient -n -e &amp;#39;equake-size-width&amp;#39;&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;truncate&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;screen-width&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desired-width-perc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calc-equake-height&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;screen-height&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cadddr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;with-input-from-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient -n -e &amp;#39;(equake-find-workarea-of-current-screen (equake-calculate-mouse-location (display-monitor-attributes-list)) (display-monitor-attributes-list))&amp;#39;&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;read&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;desired-height-perc&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;read-from-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient -n -e &amp;#39;equake-size-height&amp;#39;&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;truncate&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;screen-height&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desired-height-perc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*equake-width*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1368&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; TODO: programmatically get screen dimensions before Emacs starts&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*equake-height*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;768&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;defcommand&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;invoke-equake&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;on-top-windows&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;group-on-top-windows&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;equake-on-top&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-equake-in-group&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;on-top-windows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;equake-on-top&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;progn&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;group-on-top-windows&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;remove&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;equake-on-top&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;on-top-windows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;unfloat-window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;equake-on-top&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;hide-window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;equake-on-top&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;;; then hide Equake window via native Stumpwm method.)&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;found-equake&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-equake-globally&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;screen-groups&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-screen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; Otherwise, search all groups of current screen for Equake window:&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;found-equake&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;          &lt;span class=&#34;c1&#34;&gt;; If Equake cannot be found,&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;progn&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient -n -e &amp;#39;(equake-invoke)&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; then invoke Equake via emacs function.&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*equake-height*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;calc-equake-height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; delay calculation of height &amp;amp; width setting until 1st time equake invoked&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*equake-width*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;calc-equake-width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; (otherwise Emacs may not be fully loaded)&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;progn&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;raise-window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;found-equake&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;move-window-to-group&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;found-equake&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; But if Equake window is found, move it to the current group,&lt;/span&gt;
                   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;unhide-window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;found-equake&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; unhide window, in case hidden&lt;/span&gt;
                   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;float-window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;found-equake&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; float window&lt;/span&gt;
                   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;float-window-move-resize&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-equake-globally&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;screen-groups&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-screen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:width&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*equake-width*&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:height&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*equake-height*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; set size&lt;/span&gt;
                   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;focus-window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;found-equake&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;toggle-always-on-top&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; make on top&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;find-equake-in-group&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;windows-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Search through WINDOWS-LIST, i.e. all windows of a group, for an Equake window. Sub-component of &amp;#39;#find-equake-globally.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-searched-window&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;windows-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;current-searched-window&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;ss&#34;&gt;&amp;#39;nil&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;search&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*EQUAKE*[&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;window-name&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;current-searched-window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
            &lt;span class=&#34;nv&#34;&gt;current-searched-window&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-equake-in-group&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;windows-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;find-equake-globally&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;group-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Recursively search through GROUP-LIST, a list of all groups on current screen, for an Equake window.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;group-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;ss&#34;&gt;&amp;#39;nil&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;equake-window&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-equake-in-group&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;list-windows&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;group-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;equake-window&lt;/span&gt;
            &lt;span class=&#34;nv&#34;&gt;equake-window&lt;/span&gt;               &lt;span class=&#34;c1&#34;&gt;; stop if found and return window&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-equake-globally&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;group-list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; Set the mouse focus policy;  - :click is best for proper Equake functioning&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*mouse-focus-policy*&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;;; also StumpWM default (I think)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; Keybindings&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; bind to an appropriate key&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*top-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;F12&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;invoke-equake&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is what it looks like:
&lt;img src=&#34;https://github.com/emacsomancer/equake/raw/master/image/equake-in-stumpwm.gif&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gitlab.com/emacsomancer/equake/raw/master/image/equake-in-stumpwm.webm&#34;&gt;video
link here&lt;/a&gt;&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/stumpwm">stumpwm</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/equake">equake</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/eshell">eshell</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/equake-in-stumpwm/</guid>
                <pubDate>Wed, 22 May 2019 22:26:00 -0500</pubDate>
            </item>
        
            
            <item>
                <title>Browsing the Web with Common Lisp</title>
                <link>https://babbagefiles.xyz/next_browser-common_lisp/</link>
                
                
                <description>&lt;p&gt;I was a long-time user of &lt;a href=&#34;http://conkeror.org/&#34;&gt;Conkeror&lt;/a&gt;, a highly-extensible browser with
an Emacs ethos. It &lt;a href=&#34;https://www.freelists.org/archive/conkeror/09-2018&#34;&gt;still exists&lt;/a&gt;, but since the changes in the Firefox
back-end away from XULRunner, which Conkeror uses, running Conkeror
became increasingly difficult to use, so I&amp;rsquo;ve largely switched to
just using plain Firefox.&lt;/p&gt;
&lt;p&gt;However, &lt;a href=&#34;http://john.mercouris.online/&#34;&gt;John Mercouris&lt;/a&gt; has been developing &lt;a href=&#34;http://next.atlas.engineer/&#34;&gt;Next Browser&lt;/a&gt; (originally
styled &lt;a href=&#34;https://dm.reddit.com/r/programming/comments/7fw57u/next_browser_a_next_generation_extensible_lisp/&#34;&gt;nEXT Browser&lt;/a&gt;), a browser with a Common Lisp front-end, allowing
for customisability and extensibility along Conkeror/Emacs lines:&lt;/p&gt;



&lt;figure&gt;
    
        
            &lt;img src=&#34;https://web.archive.org/web/20190226201246/https://raw.githubusercontent.com/atlas-engineer/next/master/assets/gifs/fast_navigation.gif&#34;/&gt; &lt;/figure&gt;

&lt;p&gt;The back-ends are – if I understand correctly – planned to be Blink
for the QT port and WebkitGTK+ for the GTK port, with the Mac port of
Webkit for the Mac version. But the front-end, the user-facing side,
is Common Lisp.&lt;/p&gt;
&lt;p&gt;John is currently running an &lt;a href=&#34;https://www.indiegogo.com/projects/next-browser-nix-support#/&#34;&gt;Indiegogo campaign to properly port&lt;/a&gt; it to
Linux and other non-Mac Unix variants (it apparently runs well already
on the Mac, John&amp;rsquo;s main platform it seems [there&amp;rsquo;s no accounting for
taste ;) ]). The raised money would be used in part to pay a
professional C/C++ developer for their time.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://ambrevar.xyz/&#34;&gt;Ambrevar&lt;/a&gt; is &lt;a href=&#34;https://github.com/atlas-engineer/next/issues/92&#34;&gt;currently working on packaging&lt;/a&gt; Next Browser for &lt;a href=&#34;https://www.gnu.org/software/guix/&#34;&gt;Guix&lt;/a&gt;,
which is exciting and promises to add to the amount of Lisp front-end
software we&amp;rsquo;ll be able to use. Currently I&amp;rsquo;m running Emacs (elisp) for
the majority of my non-browser productivity (writing papers &amp;amp; creating
class slides using &lt;a href=&#34;https://www.gnu.org/software/auctex/&#34;&gt;AUCTeX&lt;/a&gt;; reading composing email with &lt;a href=&#34;https://www.djcbsoftware.nl/code/mu/mu4e.html&#34;&gt;mu4e&lt;/a&gt;;
note-taking and scheduling with &lt;a href=&#34;https://orgmode.org/&#34;&gt;Org mode&lt;/a&gt;; &amp;amp;c. &amp;amp;c.) and, at least on
one machine, &lt;a href=&#34;https://stumpwm.github.io/&#34;&gt;StumpWM&lt;/a&gt; (Common Lisp window manager) for my &amp;lsquo;desktop
environment&amp;rsquo;; and &lt;a href=&#34;https://www.gnu.org/software/guix/&#34;&gt;GNU GuixSD&lt;/a&gt; with a Guile-based package manager,
Guile-based cron (&lt;a href=&#34;https://www.gnu.org/software/mcron/manual/html_node/index.html#Top&#34;&gt;mcron&lt;/a&gt;), and Guile-based init/daemon-manager
(&lt;a href=&#34;https://www.gnu.org/software/shepherd/&#34;&gt;Shepherd&lt;/a&gt;). A functional, configurable, Lisp-based browser would be a
most welcome addition. As excellent as Firefox is, especially its
backend, I do really miss the halcyon days of Conkeror, and Next
Browser could represent a return to those heady days of configurable
browsing Emacs-style.&lt;/p&gt;
&lt;p&gt;So, if this sort of thing appeals to you (i.e. if you like Lisp,
Emacs, and/or highly-extendable browsers), you might want to support
the Linux/Unix-port of Next Browser:
&lt;a href=&#34;https://www.indiegogo.com/projects/next-browser-nix-support&#34;&gt;https://www.indiegogo.com/projects/next-browser-nix-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s only about a week left in the campaign.&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/commonlisp">commonlisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/nextbrowser">nextbrowser</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/browsers">browsers</category>
                                
                            
                        
                     
                        
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/tags/web">web</category>
                                
                            
                        
                    
                
                <guid>https://babbagefiles.xyz/next_browser-common_lisp/</guid>
                <pubDate>Sat, 20 Oct 2018 13:22:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Confusion: PDP-10 Zork</title>
                <link>https://babbagefiles.xyz/zork-confusion/</link>
                
                
                <description>&lt;p&gt;I grew up playing &lt;a href=&#34;https://en.wikipedia.org/wiki/Infocom&#34;&gt;Infocom&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/Magnetic_Scrolls&#34;&gt;Magnetic Scrolls&lt;/a&gt;, and &lt;a href=&#34;https://en.wikipedia.org/wiki/Level_9_Computing&#34;&gt;Level 9&lt;/a&gt; text
adventures, with the &lt;a href=&#34;https://en.wikipedia.org/wiki/Zork&#34;&gt;Zork trilogy&lt;/a&gt;, the &lt;a href=&#34;https://en.wikipedia.org/wiki/Enchanter_(video_game)&#34;&gt;Enchanter trilogy&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/Planetfall&#34;&gt;Planetfall&lt;/a&gt;,
&lt;a href=&#34;https://en.wikipedia.org/wiki/Wishbringer&#34;&gt;Wishbringer&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/The_Guild_of_Thieves&#34;&gt;The Guild of Thieves&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/The_Pawn&#34;&gt;The Pawn&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/Knight_Orc&#34;&gt;Knight Orc&lt;/a&gt;, and &lt;a href=&#34;https://en.wikipedia.org/wiki/Silicon_Dreams&#34;&gt;Silicon
Dreams&lt;/a&gt; being particularly prominent in my memory (somewhat
re-activated through recent listening to the &lt;a href=&#34;http://monsterfeet.com/grue/&#34;&gt;Eaten by a Grue
podcast&lt;/a&gt;). I would have played all of these on an Atari 8bit or ST
computer, and didn&amp;rsquo;t have any access to anything like a mainframe, and
so never actually played the &lt;a href=&#34;https://www.filfre.net/2012/01/zork-on-the-pdp-10/&#34;&gt;&lt;strong&gt;original&lt;/strong&gt; Zork&lt;/a&gt;, which was written in the
&lt;a href=&#34;https://en.wikipedia.org/wiki/MDL_(programming_language)&#34;&gt;Lisp-derived MDL language&lt;/a&gt; (which formed the basis for the MDL-subset
Infocom-specific &lt;a href=&#34;https://en.wikipedia.org/wiki/Z-machine&#34;&gt;ZIL language&lt;/a&gt; used for their subsequent offerings) for
the &lt;a href=&#34;https://en.wikipedia.org/wiki/PDP-10&#34;&gt;DEC PDP-10&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Fortunately, some years ago, Matthew Russotto created &lt;a href=&#34;http://www.russotto.net/git/mrussotto/confusion/src/master/src/README&#34;&gt;Confusion&lt;/a&gt;, &amp;ldquo;a
MDL interpreter which works just well enough to play the original Zork
all the way through&amp;rdquo; and runs on Linux/Unix and presumably
macOS. I&amp;rsquo;d tried to install this from Arch&amp;rsquo;s AUR a couple of years
ago, without any luck. Inspecting the &lt;a href=&#34;https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=mdli&#34;&gt;package build&lt;/a&gt;, the AUR Confusion
tries to get around errors by using an ancient version of gcc. I found
that a few fairly trivial fixes were enough to get it to compile with
a recent version of gcc, and so was finally able to try the original
Zork:&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/mdl-zork-white-house.jpg&#34;/&gt; &lt;/figure&gt;

&lt;p&gt;The most fun I always had in text adventures was exploring, and I&amp;rsquo;ve
always found Infocom&amp;rsquo;s various &amp;ldquo;time-limit&amp;rdquo; elements (batteries
running out, health deteriorating, &amp;amp;c.) somewhat irritating. I
remembered that there&amp;rsquo;s a torch in Zork I, and that is also true in
the original Zork, and I managed to obtain it early on so as to save
my (trusty brass) lamp&amp;rsquo;s batteries. I then cheated somewhat wildly
(though, to be fair, a lot of the puzzles I had figured out once upon
a time in Zork I or Zork II; and the bank puzzle and some of the
others I wouldn&amp;rsquo;t have patience for anymore).&lt;/p&gt;
&lt;p&gt;The original code has some bugs in it which made things more
interesting.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-ascii&#34; data-lang=&#34;ascii&#34;&gt;Narrow Ledge
You are on a narrow ledge overlooking the inside of an old dormant
volcano.  This ledge appears to be about in the middle between the
floor below and the rim above. There is an exit here to the south.
There is a very large and extremely heavy wicker basket with a cloth
bag here. Inside the basket is a metal receptacle of some kind.
Attached to the basket on the outside is a piece of wire.
The basket contains:
 A cloth bag
 A braided wire
 A receptacle
 The receptacle contains:
  A newspaper
 A blue label
There is a small hook attached to the rock here.

&amp;gt; untie braided wire from hook

 *ERROR*
 &amp;quot;FIRST-ARG-WRONG-TYPE&amp;quot;
 &amp;quot;First arg to NTH must be structured&amp;quot;
LISTENING-AT-LEVEL 2 PROCESS 1
Atom REP has neither LVAL nor GVAL
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I had a similar issue involving the result of a disagreement with a
suspicious-looking individual holding a bag. It turns out (thanks to
Matthew Russotto for the following information) that this has to do
with issues in saving and restoring files, and (failure of) either
properly recording or decoding certain values. The balloon issue has
to do with a record about the object burning in the receptacle. It is
saved as &lt;code&gt;BINF!-FLAG&lt;/code&gt;, which should be a boolean-type flag, but at
some point it became an object (recording what is burning) and
apparently isn&amp;rsquo;t decoded properly on a restore. Saving-and-restoring
during a battle with the suspicious-looking individual produces a
similar error to the balloon-burnable error, due to the
&lt;code&gt;THIEF-ENGROSSED!-FLAG&lt;/code&gt; (which apparently really is a flag) not
being saved properly. The upshot (for a player) is that you shouldn&amp;rsquo;t
save during either of these bits of the game.&lt;/p&gt;
&lt;p&gt;With these additional lurking grues out of the way, I was able to make
it to the end of the game:&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/zork-end.png&#34;/&gt; &lt;/figure&gt;

&lt;p&gt;Speaking of saving, MDL Zork only has a single restore file. It is
stored in the &lt;code&gt;MTRZORK&lt;/code&gt; directory and is named &lt;code&gt;ZORK.SAVE&lt;/code&gt;. Of course
you can create additional saves by copying out this save file to
different names.&lt;/p&gt;
&lt;p&gt;If you too want to play the original Zork using the original PDP-10 MDL
source code, you should be able to build the MDL interpreter necessary
from the release at Matthew Russotto&amp;rsquo;s site (where my minor patches
should be incorporated):
&lt;a href=&#34;http://www.russotto.net/git/mrussotto/confusion/releases&#34;&gt;http://www.russotto.net/git/mrussotto/confusion/releases&lt;/a&gt; or
from the git repo with my patches at
&lt;a href=&#34;https://github.com/emacsomancer/confusion-mdl&#34;&gt;https://github.com/emacsomancer/confusion-mdl&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Or, the easiest of all, install it via Guix (&lt;a href=&#34;https://www.gnu.org/software/guix/manual/en/html_node/Binary-Installation.html#Binary-Installation&#34;&gt;which can installed on
top of your current distro as a standalone package manager&lt;/a&gt;), as I have
created a Guix package which was accepted upstream (the package name
in Guix is &lt;code&gt;confusion-mdl&lt;/code&gt;). [note: this Guix package stopped building
some time ago and I need to figure out what needs fixing. Right now,
have a look at the mdlzork project at
&lt;a href=&#34;https://github.com/jordanhubbard/mdlzork&#34;&gt;https://github.com/jordanhubbard/mdlzork&lt;/a&gt; , which provides a way to
easily play early versions of Zork online at
&lt;a href=&#34;https://jordanhubbard.github.io/mdlzork/&#34;&gt;https://jordanhubbard.github.io/mdlzork/&lt;/a&gt;.]&lt;/p&gt;
&lt;p&gt;Since I played through this right before designing the propositional
logic homework for my Semantics class, my students are currently
&amp;ldquo;enjoying&amp;rdquo; doing Zork-flavoured propositional logic translations,
e.g.:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The thief only steals your things when you&amp;rsquo;re in the cellar.&lt;/li&gt;
&lt;li&gt;Your sword glows blue whenever the thief or the troll is near and
never any other time.&lt;/li&gt;
&lt;li&gt;Whether or not you are lost in a maze of twisty little passages
(all alike), the grues are lurking in the darkness.&lt;/li&gt;
&lt;li&gt;The grues will eat you unless you bring a light source.&lt;/li&gt;
&lt;/ol&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/mdl">mdl</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/intfict">intfict</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/guix">guix</category>
                                
                            
                        
                     
                        
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/tags/zork">zork</category>
                                
                            
                        
                    
                
                <guid>https://babbagefiles.xyz/zork-confusion/</guid>
                <pubDate>Sun, 23 Sep 2018 23:52:00 -0500</pubDate>
            </item>
        
            
            <item>
                <title>Quake-style drop-down terminal in StumpWM</title>
                <link>https://babbagefiles.xyz/quake_terminal_stumpwm/</link>
                
                
                <description>&lt;p&gt;One thing I&amp;rsquo;ve missed in StumpWM is a Quake-style drop-down terminal,
like what Guake provides (and I have a Lua-one in my AwesomeWM
config). It may be that I&amp;rsquo;m still haven&amp;rsquo;t fully absorbed the
StumpWM-mindset and that I should be doing this a different way. But
up until now when I&amp;rsquo;m using StumpWM I&amp;rsquo;ve tended to end up with a heap
of terminal windows that are a pain to navigate through (I have a
&lt;code&gt;run-or-raise&lt;/code&gt; command associated with xterm, but it starts from the
first xterm window and usually I want the last – something else to
figure out how to do). It&amp;rsquo;s nice to have a &amp;lsquo;working terminal&amp;rsquo; that one
can quickly summon and dismiss.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a number of issues for creating a Quake-type drop-down in
StumpWM (at least based on my current knowledge). The first is fairly
easily dealt with - I don&amp;rsquo;t want more than one Quake terminal around.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;run-or-raise&lt;/code&gt; will prevent multiple instances from being created:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;defcommand&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;urxvt&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Start an urxvt instance or switch to it, if it is already running.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-or-raise&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;urxvt&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;:title&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;urxvt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(I&amp;rsquo;m cheating here a bit because I&amp;rsquo;m not quite sure how to handle
title-management. I know windows can be retitled, and I initially
tried setting the window title in the above function to &amp;ldquo;quake&amp;rdquo;, but
somehow I ended up also sporadically re-titling &lt;strong&gt;other&lt;/strong&gt; windows as
&amp;ldquo;quake&amp;rdquo;, so I&amp;rsquo;ve side-stepped the whole issue by just using urxvt for
my drop-down terminal, with my regular terminal being xterm.)&lt;/p&gt;
&lt;p&gt;What we want then is a function that toggles our Quake terminal
on-and-off: essentially if the current window is not urxvt, then call
the &lt;code&gt;urxvt&lt;/code&gt; function defined above, and if the current window is urxvt
then switch back to the last used window before urxvt was called.  The
basic thing we need for this is &lt;code&gt;(if (equal (window-title (current-window)) &amp;quot;urxvt&amp;quot;)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The trouble is that StumpWM has a nice feature which is similar to
doing &lt;code&gt;C-x b RET&lt;/code&gt; in Emacs: it essentially switches to the last window
used, so it can be a nice feature for switching back and forth between
two different windows you&amp;rsquo;re working in. The function is
&lt;code&gt;pull-hidden-other&lt;/code&gt; and it is invoked with &amp;ldquo;prefix prefix&amp;rdquo;, which for
me is &lt;code&gt;s-f s-f&lt;/code&gt; (Super+F, twice), but by default is &lt;code&gt;C-t C-&lt;/code&gt; (Ctrl+t
twice). Why this creates a problem is because our Quake terminal will
muck that up because &lt;strong&gt;it&lt;/strong&gt; will often end up being the last used
window, and that&amp;rsquo;s not what I want. I want &lt;code&gt;pull-hidden-other&lt;/code&gt; to
switch to the last used window that&amp;rsquo;s &lt;strong&gt;not&lt;/strong&gt; the Quake drop-down.&lt;/p&gt;
&lt;p&gt;I tried a number of different things, and this may still not be the
best solution, but it works:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;defcommand&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;rxvt-quake&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Toggle rxvt-quake window.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;window-title&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;urxvt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; if the current window is quake&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;progn&lt;/span&gt;
	&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;other-window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;; switch back to window quake was called from&lt;/span&gt;
	&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;select-window-by-number&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*real-other-window*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; switch to the &amp;#39;real&amp;#39; &amp;#34;other-window&amp;#34;&lt;/span&gt;
	&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;other-window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; switch back to the original window - this way after quake finishes, the original configuration is restored&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;progn&lt;/span&gt;          &lt;span class=&#34;c1&#34;&gt;; otherwise, if the current window is NOT quake&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;other-window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;; first switch the current &amp;#34;other-window&amp;#34;&lt;/span&gt;
	&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;window-title&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;urxvt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; if the current&lt;/span&gt;
								  &lt;span class=&#34;c1&#34;&gt;; &amp;#34;other-window&amp;#34; is&lt;/span&gt;
								  &lt;span class=&#34;c1&#34;&gt;; quake itself, do&lt;/span&gt;
								  &lt;span class=&#34;c1&#34;&gt;; nothing&lt;/span&gt;
	    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*real-other-window*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;window-number&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; otherwise store the window-number of the current other-window&lt;/span&gt;
	&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;other-window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; switch back to the window originally called from&lt;/span&gt;
	&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;urxvt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; run-or-raise urxvt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So this function indeed checks to see whether the current window is
our Quake drop-down terminal. If it&amp;rsquo;s not, it first switches to the
currently last used window with &lt;code&gt;(other-window)&lt;/code&gt; and stores the number
of this window in &lt;code&gt;*real-other-window*&lt;/code&gt; (but &lt;strong&gt;only&lt;/strong&gt; if this
last-used-window isn&amp;rsquo;t itself urxvt - otherwise we&amp;rsquo;ll sometime end up
&amp;lsquo;over-writing&amp;rsquo; the actual last-used-window we want to keep). It then
switches back to window that was active when &lt;code&gt;rxvt-quake&lt;/code&gt; was invoked,
and then it calls the &lt;code&gt;urxvt&lt;/code&gt; function which either launches a new
urxvt (if none currently exists), or raises the currently running
urxvt window. Storing the value in &lt;code&gt;*real-other-window*&lt;/code&gt; gives us a
way to remember what the &amp;lsquo;real&amp;rsquo; last-used window should be.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;rxvt-quake&lt;/code&gt; is invoked while the Quake urxvt drop-down is the
currently active window, then first &lt;code&gt;(other-window)&lt;/code&gt; is invoked,
switching us back to the window that was active before we called the
drop-down terminal, then we switch to our stored window (which was the
&amp;lsquo;real&amp;rsquo; last-used window before Quake was invoked), and then we switch
back with &lt;code&gt;(other-window)&lt;/code&gt; to the window that was active when Quake
was first invoked.&lt;/p&gt;
&lt;p&gt;This way the window configuration that existed before we summoned our
Quake drop-down terminal is restored, and &lt;code&gt;pull-hidden-other&lt;/code&gt;
effectively ignores the Quake drop-drop.&lt;/p&gt;
&lt;p&gt;Bind this command to the traditional F12 with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*top-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;F12&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;rxvt-quake&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And you&amp;rsquo;re got a &amp;lsquo;traditional&amp;rsquo; Quake drop-down terminal in StumpWM.&lt;/p&gt;
&lt;p&gt;It is a &amp;lsquo;full-length&amp;rsquo; drop-down terminal, however. It might be nice to
have it be a fraction of the screen like a more traditional Quake drop-down.&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/stumpwm">stumpwm</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/quake_terminal_stumpwm/</guid>
                <pubDate>Tue, 18 Sep 2018 20:45:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Dockerised Firefox on GuixSD</title>
                <link>https://babbagefiles.xyz/dockerised_firefox_guix/</link>
                
                
                <description>&lt;p&gt;So GuixSD doesn&amp;rsquo;t currently package Firefox (&lt;a href=&#34;https://lists.gnu.org/archive/html/guix-devel/2018-05/msg00021.html&#34;&gt;though hopefully that
is changing&lt;/a&gt;), but only IceCat (which is now EOL). On freenode#guix,
pkill9 suggested that Firefox (and Chromium etc.) could be installed
on Guix via the &lt;a href=&#34;https://nixos.org/nix/download.html&#34;&gt;Nix&lt;/a&gt; installer (install as per instructions on their
site and then &lt;code&gt;nix-env -i firefox&lt;/code&gt;) with the following trick, create a
file &lt;code&gt;~/.local/bin/firefox&lt;/code&gt; with the following content:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Wrapper to run the Firefox built and packaged by Nix&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;MESA_LIB&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;dirname &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;realpath /run/current-system/profile/lib/libGL.so&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;#To get webgl working&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;LD_LIBRARY_PATH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$MESA_LIB&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;LD_LIBRARY_PATH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:+:&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$LD_LIBRARY_PATH&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;#export FONTCONFIG_PATH=&amp;#34;$(guix build fontconfig)/etc/fonts${FONTCONFIG_PATH:+:}$FONTCONFIG_PATH&amp;#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;FONTCONFIG_PATH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;guix build fontconfig&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/etc/fonts&amp;#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; -a &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/nix/var/nix/profiles/per-user/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/profile/bin/firefox&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then add &lt;code&gt;~/.local/bin&lt;/code&gt; to your &lt;code&gt;$PATH&lt;/code&gt; in &lt;code&gt;~/.profile&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately I haven&amp;rsquo;t been able to get that to work, though I could
be doing something daft.&lt;/p&gt;
&lt;p&gt;I figured out the following (elaborate) alternative workaround for
Firefox (no luck for Chromium):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;Install Docker via Nix. Launch with &lt;code&gt;sudo dockerd&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Create a Dockerfile for Firefox&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-Dockerfile&#34; data-lang=&#34;Dockerfile&#34;&gt;&lt;span class=&#34;c&#34;&gt;# firefox in a docker container&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# the following line will start firefox in the container, thus&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# video and sound will be played on the host machine&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; alpine:edge&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;MAINTAINER&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; slade@jnanam.net&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# add testing repo + install packages + add user and group&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;http://dl-cdn.alpinelinux.org/alpine/edge/testing/&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /etc/apk/repositories &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; apk add --no-cache &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       xz &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       dbus-x11 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       ttf-dejavu &lt;span class=&#34;se&#34;&gt;\ &lt;/span&gt;         &lt;span class=&#34;c1&#34;&gt;# a bunch of fonts; you may not want all of these&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;       ttf-freefont &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       ttf-ubuntu-font-family &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-extra &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-emoji &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-oriya &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-tamil &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-avestan &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-gothic &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-myanmar &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-telugu &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-deseret &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-bengali &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-kannada &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-ethiopic &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-armenian &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-tibetan &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-sinhala &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-gurmukhi &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-malayalam &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-gujarati &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-devanagari &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-thai &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-adlam &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-nko &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-lisu &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-carian &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-buhid &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-osage &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-hebrew &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-arabic &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-chakma &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-gothic &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-khmer &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-cypriot &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-kayahli &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-mandaic &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-olchiki &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-thaana &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-georgian &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-shavian &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-cherokee &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-oldturkic &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-osmanya &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-glagolitic &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-tifinagh &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-adlamunjoined &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-nko &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       font-noto-lao &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       arc-theme &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       hunspell &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       hunspell-en &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       firefox &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       libcanberra-gtk2 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;       pulseaudio &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; rm -fr /var/cache/apk/* &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; adduser -D -u &lt;span class=&#34;m&#34;&gt;1000&lt;/span&gt; -g &lt;span class=&#34;m&#34;&gt;1000&lt;/span&gt; user&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# add user&amp;#39;s work&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WORKDIR&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; /home/user&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# switch to user&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USER&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; user&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ENTRYPOINT&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/usr/bin/firefox&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;--no-remote&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Save the above out to a file &lt;code&gt;Dockerfile&lt;/code&gt; in some directory. &lt;code&gt;cd&lt;/code&gt; to
that directory. Then create a Docker container with &lt;code&gt;docker build -t someprefix/firefox .&lt;/code&gt; (with &lt;code&gt;someprefix&lt;/code&gt; being whatever you like).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Create in &lt;code&gt;~/.local/bin/firefox&lt;/code&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Wrapper to run the Chromium built and packaged by Nix&lt;/span&gt;
xhost +local:docker@&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;docker run --rm -it -e &lt;span class=&#34;nv&#34;&gt;DISPLAY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$DISPLAY&lt;/span&gt; -v /tmp/.X11-unix/:/tmp/.X11-unix &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;-v /dev/snd:/dev/snd &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;-v /run/user/&lt;span class=&#34;nv&#34;&gt;$USER_UID&lt;/span&gt;/pulse:/run/pulse:ro &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;-v /home/&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;/.mozilla:/home/user/.mozilla &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;-v /home/&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;/.cache/mozilla:/home/user/.cache/mozilla &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;-v /tmp/Downloads:/tmp/Downloads &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;-v /home/&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;/.gtkrc-2.0:/home/user/.gtkrc-2.0 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;-v /home/&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;/.config/gtk-3.0/:/home/user/.config/gtk-3.0 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;-v /home/&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;/.nix-profile/share/fonts/truetype:/usr/share/fonts/truetype-nix &lt;span class=&#34;se&#34;&gt;\ &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# for nix fonts, if you have them here&lt;/span&gt;
-v /home/&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;/.nix-profile/share/fonts/ubuntu:/usr/share/fonts/ubuntu-nix &lt;span class=&#34;se&#34;&gt;\ &lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;# ditto&lt;/span&gt;
-v /home/&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;/.nix-profile/share/fonts/noto:/usr/share/fonts/noto-nix &lt;span class=&#34;se&#34;&gt;\ &lt;/span&gt;        &lt;span class=&#34;c1&#34;&gt;# ditto&lt;/span&gt;
-v /home/&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;/.guix-profile/share/fonts/truetype:/user/share/fonts/truetype-guix &lt;span class=&#34;se&#34;&gt;\ &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# for guix fonts, if you have them here&lt;/span&gt;
-v /home/&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;/.guix-profile/share/fonts/opentype:/usr/share/fonts/opentype-guix &lt;span class=&#34;se&#34;&gt;\ &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# ditto&lt;/span&gt;
 --shm-size 2g  --privileged someprefix/firefox  &lt;span class=&#34;c1&#34;&gt;# substitute your prefix here for &amp;#34;someprefix&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Where again &lt;code&gt;someprefix&lt;/code&gt; is whatever you chose before. &lt;code&gt;chmod +x ~/.local/bin/firefox&lt;/code&gt; and then you can run Firefox with
&lt;code&gt;firefox&lt;/code&gt;. (You&amp;rsquo;ll have to make sure &lt;code&gt;dockerd&lt;/code&gt; is running.)&lt;/p&gt;
&lt;p&gt;Perhaps this could be useful elsewhere. It has the advantage of being
a nice &lt;a href=&#34;https://alpinelinux.org/&#34;&gt;Alpine Linux&lt;/a&gt; &lt;a href=&#34;https://www.musl-libc.org/&#34;&gt;musl-libc&lt;/a&gt;/&lt;a href=&#34;https://www.libressl.org/&#34;&gt;libressl&lt;/a&gt; build of Firefox running inside
your GuixSD (or whatever you&amp;rsquo;re using).&lt;/p&gt;
&lt;p&gt;What doesn&amp;rsquo;t work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spellchecking - I don&amp;rsquo;t quite know why, hunspell should be
available. Just disable spellchecking for now (otherwise everything
will be underlined in red).&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wire.com&#34;&gt;Wire&lt;/a&gt;&amp;lsquo;s web portal.&lt;/li&gt;
&lt;li&gt;Saving or uploading from anywhere but &lt;code&gt;/tmp/Downloads&lt;/code&gt; (but this is
a feature really).&lt;/li&gt;
&lt;li&gt;If you want CJK fonts, you&amp;rsquo;ll have to install them in Nix or Guix
(Alpine doesn&amp;rsquo;t seem to have any); this is indicated in the Firefox
launch script above.&lt;/li&gt;
&lt;/ul&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/guix">guix</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/docker">docker</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/firefox">firefox</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/dockerised_firefox_guix/</guid>
                <pubDate>Sat, 15 Sep 2018 20:18:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Managing emacsclient windows in StumpWM</title>
                <link>https://babbagefiles.xyz/emacs_windows_stumpwm/</link>
                
                
                <description>&lt;p&gt;I&amp;rsquo;m still working on getting my GuixSD machine configured, including
working on getting familiar with &lt;a href=&#34;https://stumpwm.github.io/&#34;&gt;StumpWM&lt;/a&gt; – a windows manager written
in Common Lisp – which is the desktop paradigm I&amp;rsquo;ve decided upon for
this Lisp-centric machine.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m somewhat habituated to (my) &lt;a href=&#34;https://awesomewm.org/&#34;&gt;AwesomeWM&lt;/a&gt; keybindings, which involve
the Super key in combination with various other keys, including say
&lt;code&gt;s-1&lt;/code&gt; for tag/workspace 1, &lt;code&gt;s-3&lt;/code&gt; for tag/workspace 3, &amp;amp;c., and
&lt;code&gt;s-E&lt;/code&gt; (i.e. hold Super and Shift and press &lt;code&gt;e&lt;/code&gt;) to launch an
emacsclient (see below on the Emacs client/daemon
configuration). StumpWM could be configured in a somewhat similar
fashion (though it doesn&amp;rsquo;t seem to quite use tag/workspaces in the
same fashion), but the &amp;lsquo;tradition&amp;rsquo; seems to be to use a prefix, which
is by default &lt;code&gt;C-t&lt;/code&gt; (that is, hold Control and press &lt;code&gt;t&lt;/code&gt;), which
is then released and followed with another key or key combination. I
don&amp;rsquo;t really like using Control for windows management since it tends
to conflict with bindings in Emacs and elsewhere, so I&amp;rsquo;m testing out
&lt;code&gt;s-F&lt;/code&gt; (hold Super, press &lt;code&gt;f&lt;/code&gt;) as a prefix (though whether I&amp;rsquo;ll
stick with prefixed bindings or go back to single action bindings, I&amp;rsquo;m
not yet certain).&lt;/p&gt;
&lt;p&gt;From browsing other stumpwm configs, I came across a useful bit of
configuration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;run-or-raise-prefer-group&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;win-cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;If there are windows in the same class, cycle in those. Otherwise call
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;run-or-raise with group search t.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;windows&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;group-windows&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;member&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;win-cls&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;mapcar&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;window-class&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;windows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:test&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;string-equal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
	&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-or-raise&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;:class&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;win-cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
	&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-or-raise&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;:class&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;win-cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This function can then be used with specific applications, e.g.:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;defcommand&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;run-or-raise-icecat&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
	    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-or-raise-prefer-group&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;icecat&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Icecat&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above function leverages &lt;code&gt;run-or-raise-prefer-group&lt;/code&gt; to either
launch Icecat, if it is not already running, or else focus the Icecat
window, and successive calls will cycle through multiple Icecat
windows/windows if more than one Icecat window exists. This is extremely
useful as it&amp;rsquo;s much less cognitively-tasking than figuring out which
window number Icecat currently is associated with.&lt;/p&gt;
&lt;p&gt;This can then be assigned a binding(s) like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*root-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;W&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;run-or-raise-icecat&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*root-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;C-W&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;run-or-raise-icecat&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*root-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;s-W&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;run-or-raise-icecat&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This means that one first presses the prefix (&lt;code&gt;s-f&lt;/code&gt; for me) followed
by either &lt;code&gt;W&lt;/code&gt; or &lt;code&gt;C-W&lt;/code&gt; or &lt;code&gt;s-W&lt;/code&gt; (that is, &lt;code&gt;Shift+w&lt;/code&gt;,
&lt;code&gt;Control-Shift+w&lt;/code&gt; or &lt;code&gt;Super-Shift+w&lt;/code&gt;) to either launch Icecat or
focus/cycle through existing Icecat windows/windows.&lt;/p&gt;
&lt;p&gt;Now, the way I typically use Emacs is to invoke it as a daemon
(i.e. &lt;code&gt;emacs --daemon&lt;/code&gt;) and then connect Emacsclients to this daemon
(i.e. &lt;code&gt;emacsclient -c&lt;/code&gt; for the &amp;lsquo;windowed&amp;rsquo; gtk-application,
&lt;code&gt;emacsclient -t&lt;/code&gt; in the terminal). However, if we define a parallel
function for Emacs, a particular edge-case arises:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;defcommand&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;run-or-raise-emacsclient&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
		&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-or-raise-prefer-group&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacs&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Emacs&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This works rather like the Icecat one as long as at least one
Emacsclient window exists (so if there are multiple window,
successive calls of &lt;code&gt;run-or-raise-emacsclient&lt;/code&gt; will cycle through
them). &lt;strong&gt;However&lt;/strong&gt;, if no emacsclient is currently open, it will launch an
undaemon&amp;rsquo;ed Emacs (requiring loading the entire &lt;code&gt;init.el&lt;/code&gt;), even
if/though an Emacs daemon is currently running and thus could be
attached to.&lt;/p&gt;
&lt;p&gt;At least one solution to this is the following function (with
relevant keybindings):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;defcommand&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;decide-on-emacsclient&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
 &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;pgrep \&amp;#34;emacsclient\&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient -c&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-or-raise-emacsclient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*root-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;s-e&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;decide-on-emacsclient&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*root-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;C-e&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;decide-on-emacsclient&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*root-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;e&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;decide-on-emacsclient&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above function executes the shell-command &lt;code&gt;pgrep &amp;quot;emacsclient&amp;quot;&lt;/code&gt;
and evaluates whether the output of that shell-command is equal to the
empty string (which will be the case only when no emacsclient is
running). Where at least one emacsclient is running, it executes the
&lt;code&gt;run-or-raise-emacsclient&lt;/code&gt; function defined earlier,
focussing/cycling through running emacsclients. Where no emacsclient
is currently running, it executes instead &lt;code&gt;emacsclient -c&lt;/code&gt;, opening
a windowed emacsclient.  And the bindings let me press the prefix and
then either &lt;code&gt;Super+e&lt;/code&gt;, &lt;code&gt;Control+e&lt;/code&gt; or simply &lt;code&gt;e&lt;/code&gt; to execute this
new function.&lt;/p&gt;
&lt;p&gt;I also have the following definitions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;defcommand&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;emacsclient-launch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient -c&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*root-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;s-E&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient-launch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*root-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;C-E&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient-launch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;vg&#34;&gt;*root-map*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;E&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient-launch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So that if I want to launch a new emacsclient window instead of switching to an
existing one, I can do so using one of series of keybindings parallel
to the previous set, but with a capital &lt;code&gt;E&lt;/code&gt; rather than a lowercase
one.&lt;/p&gt;
&lt;p&gt;This is working well for me, and is a nice example of the power of
using Lisp-based &amp;lsquo;desktop environment&amp;rsquo;.&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/stumpwm">stumpwm</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/emacs_windows_stumpwm/</guid>
                <pubDate>Sat, 18 Aug 2018 21:36:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Guix: You are in a maze of lispy little passages, (map equal? ′(′all ′alike) ′(′all ′alike))</title>
                <link>https://babbagefiles.xyz/guix_maze_of_lispy_little_passages/</link>
                
                
                <description>&lt;p&gt;So I finally made a serious go of running &lt;a href=&#34;https://www.gnu.org/software/guix/&#34;&gt;GuixSD&lt;/a&gt;, a GNU Linux distro
which is largely built on &lt;a href=&#34;https://en.wikipedia.org/wiki/GNU_Guile&#34;&gt;GNU Guile Scheme&lt;/a&gt; (a dialect of Lisp) on one
of my machines (one I had actually put together with GuixSD in mind:
an X200 Thinkpad, which I &lt;a href=&#34;https://libreboot.org/&#34;&gt;Libreboot&lt;/a&gt;&amp;lsquo;ed and put a Atheros Wi-Fi card
in), and, to increase both the quantity and variety of Lisps involved,
am trying to use with &lt;a href=&#34;https://stumpwm.github.io/&#34;&gt;StumpWM&lt;/a&gt; (which is written in Common Lisp).&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a fascinating distro, modelled on &lt;a href=&#34;https://nixos.org/&#34;&gt;Nix&lt;/a&gt;, but implemented in
Guile. It&amp;rsquo;s not been exactly easy to get running (&lt;a href=&#34;https://www.gnu.org/software/guix/blog/2017/back-from-fosdem-2017/&#34;&gt;one of the videos on
GuixSD from Fosdem 2017&lt;/a&gt; included the line &amp;ldquo;[GuixSD] is like Gentoo for
grown ups&amp;rdquo;), in part because its architecture is rather different from what
I&amp;rsquo;ve experienced with other Linux distros, which use different package
managers perhaps and sometimes even different libc&amp;rsquo;s, but generally
follow a similar design philosophy. Rather than spreading out
configuration across lots of different pieces, GuixSD seems to largely
try to concentrate it in specific configuration files which are
transactional in that they can be rolled back (and thus the system can
be rolled back to known working states).&lt;/p&gt;
&lt;p&gt;It is a GNU-blessed distro, and does take the FSF&amp;rsquo;s hard line (and to
my eyes sometimes weird line) approach to software. So no proprietary
software is included in the Guix repos, including firmware (and it
runs on the linux-libre kernel). That by itself is fine, but it means
the state of affairs for Guix-packaged browsers is pretty poor. No
Chromium, no Firefox. IceCat 52 is essentially what&amp;rsquo;s currently
available (if IceCat were up to the latest Firefox ESR 60, it might be
easier) in terms of browsers which might be considered secure.&lt;/p&gt;
&lt;p&gt;This led me to try to use the Nix installer by itself&lt;sup&gt;&lt;a href=&#34;#org-target--0b&#34;&gt;*&lt;/a&gt;&lt;/sup&gt;&lt;span class=&#34;org-target&#34; id=&#34;org-target--0t&#34;&gt;&lt;/span&gt; to try to
install Firefox and Chromium. Sadly, I can&amp;rsquo;t get Nix&amp;rsquo;s Chromium to
work at all on GuixSD, and while Firefox works fine, I can&amp;rsquo;t get it to
see my locally installed fonts (or other fonts I&amp;rsquo;ve installed via
Nix).&lt;/p&gt;
&lt;p&gt;Hopefully at some point &lt;a href=&#34;http://next-browser.com/&#34;&gt;Next Browser&lt;/a&gt; will be packaged for Guix, to
bring in another major component written in (Common) Lisp. And when
(if?) IceCat 60 comes out, that will alleviate the pain somewhat. (I
was a long-time &lt;a href=&#34;http://conkeror.org/&#34;&gt;Conkeror&lt;/a&gt; user, and I briefly tried it again in GuixSD,
but I&amp;rsquo;m not certain of its security and uBlock Origin no long works
with it, which I believe is why I stopped using it in the first
place).&lt;/p&gt;
&lt;p&gt;Other interesting Lispy pieces include &lt;a href=&#34;https://www.gnu.org/software/mcron/&#34;&gt;mcron&lt;/a&gt;, a cron which accepts (as
well as Vixie cron style, I think) Guile config files. The &lt;a href=&#34;https://www.gnu.org/software/guix/manual/en/html_node/Scheduled-Job-Execution.html&#34;&gt;examples in
Guix manual&lt;/a&gt; I couldn&amp;rsquo;t really get to work. But via the &lt;code&gt;help-guix&lt;/code&gt;
listserv I found that one can put simple guile scripts in
&lt;code&gt;~/.config/cron/job.guile&lt;/code&gt;. Working out how to do a &amp;lsquo;run this every N
minutes&amp;rsquo; was not immediately obvious, but I figured out how to do it,
e.g.:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-guile&#34; data-lang=&#34;guile&#34;&gt;; execute run_me every 5 minutes
(job &#39;(next-minute (range 0 60 5)) &amp;quot;run_me&amp;quot;)
; run execute_me every 2 hours
(job &#39;(next-hour (range 0 24 2)) &amp;quot;execute_me&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;One of the other great things about GuixSD is that its init manager,
&lt;a href=&#34;https://www.gnu.org/software/shepherd/&#34;&gt;GNU Shepherd&lt;/a&gt;, is also written in Guile Scheme. I&amp;rsquo;ve only had a chance
to play with it a little bit, but it seems very nice and it&amp;rsquo;s good to
find other innovative init managers (I would mention here also &lt;a href=&#34;http://smarden.org/runit/&#34;&gt;runit&lt;/a&gt;
and &lt;a href=&#34;https://skarnet.org/software/s6/&#34;&gt;s6&lt;/a&gt;) which take very different approaches to &lt;a href=&#34;https://www.freedesktop.org/wiki/Software/systemd/&#34;&gt;systemd&lt;/a&gt; (another
innovative init, or perhaps init+, but one that creates more problems
than it solves in the end, in my experience).&lt;/p&gt;
&lt;p&gt;On the Guix package manager itself: I learned the hard way that
searching for packages in Guix is really only comfortable within
Emacs: so do &lt;code&gt;guix package -i guix-emacs&lt;/code&gt; and then do everything else
from guix-emacs within Emacs ( &lt;code&gt;M-x guix-search-by-name&lt;/code&gt; to search
package names by regex; and &lt;code&gt;M-x guix-search-by-regex&lt;/code&gt; to search
names+descriptions by regex). The results returned by &lt;code&gt;guix package -s ....&lt;/code&gt; in a terminal are not very browseable (though I tried valiantly
for some time). But if you&amp;rsquo;re interested in Guix, you&amp;rsquo;ll likely
interested in Emacs anyway.&lt;/p&gt;
&lt;p&gt;What I&amp;rsquo;m trying to build on this machine is something with lots of
Lisp. Of course the kernel is still a kernel written in C, as are lots
of the other pieces like the terminal &amp;amp;c., but much of the user-facing
things: the package manager, the windows manager, the init, the job
scheduler (=cron), and (most importantly perhaps) the &amp;lsquo;text editor&amp;rsquo;
(read: document composer, email interface, irc interface, twitter
interface, blog post interface, code editor &amp;hellip;) are all largely
written in and interacted with using some form of Lisp (Guile Scheme,
Common Lisp, Emacs Lisp).&lt;/p&gt;
&lt;p&gt;Guix is a bit like Emacs, I think. It&amp;rsquo;s an incredibly powerful tool
with lots of interesting possibilities, but when you start using it
you&amp;rsquo;re presented with an empty screen with little indication of what
you can do. I&amp;rsquo;ll be sticking with it, I think. Now I&amp;rsquo;ve got to get to
grips with StumpWM and figure out how to configure &lt;a href=&#34;https://github.com/jaagr/polybar&#34;&gt;polybar&lt;/a&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;[And if you&amp;rsquo;re curious about why Guix is pronounced like &amp;ldquo;geeks&amp;rdquo;, have
a look at &lt;a href=&#34;https://slade.jnanam.net/post/scheming-french-geeks-with-guile/&#34;&gt;this post over on my linguistics blog&lt;/a&gt;.]&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;#org-target--0t&#34;&gt;*&lt;/a&gt;&lt;span class=&#34;org-target&#34; id=&#34;org-target--0b&#34;&gt;&lt;/span&gt; As well as being the package managers of both of their
respective distros, both the Nix and Guix package managers can be used
&lt;strong&gt;on top of&lt;/strong&gt; other distros. Nix doesn&amp;rsquo;t have quite the same hard line
approach to software licences as Guix.&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/lisp">lisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/guix">guix</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/linux">linux</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/stumpwm">stumpwm</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/guix_maze_of_lispy_little_passages/</guid>
                <pubDate>Sat, 04 Aug 2018 21:47:00 -0500</pubDate>
            </item>
        
    </channel>
</rss>


