<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>
            
                    Posts on
                
            
            The Neo-Babbage Files</title>
        <link>https://babbagefiles.xyz/posts/</link>
        <description>Recent content  in Posts
            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/posts/index.xml" rel="self" type="application/rss&#43;xml" />
        
            
            <item>
                <title>Auto-sizing images in Kitty (if it fits it sits?)</title>
                <link>https://babbagefiles.xyz/auto-sizing-images-in-kitty-terminal/</link>
                
                
                <description>&lt;p&gt;I&amp;rsquo;ve been playing with &lt;a href=&#34;https://babbagefiles.xyz/categories/terminals/&#34;&gt;terminal emulators&lt;/a&gt; again for a while. More to
write up at some point, but here a quick note on some customisations
for displaying images in the terminal&amp;hellip;.&lt;/p&gt;
&lt;p&gt;There are a couple of terminal emulators which allow for display of
arbitrary images in the terminal (I mean, jpegs and pngs and the like,
not (just) &lt;a href=&#34;https://en.wikipedia.org/wiki/Sixel&#34;&gt;sixel&lt;/a&gt;), notably &lt;a href=&#34;https://sw.kovidgoyal.net/kitty&#34;&gt;Kitty&lt;/a&gt; and &lt;a href=&#34;https://wezterm.org&#34;&gt;WezTerm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;WezTerm with iTerm2 compatible image protocol support, and built-in
&lt;a href=&#34;https://wezterm.org/cli/imgcat.html&#34;&gt;&lt;code&gt;imgcat&lt;/code&gt; command&lt;/a&gt;, &lt;strong&gt;alongside of (experimental but seemingly working)&lt;/strong&gt;
support for &lt;a href=&#34;https://sw.kovidgoyal.net/kitty/kittens/icat/&#34;&gt;Kitty&amp;rsquo;s image display protocol&lt;/a&gt; (enable this in WezTerm by
adding to your &lt;code&gt;wezterm.lua&lt;/code&gt; config the line
&lt;code&gt;enable_kitty_graphics=true&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;I mainly use &lt;a href=&#34;https://fishshell.com&#34;&gt;Fish shell&lt;/a&gt;, and here I record a couple of notes on
convenience customisations in Fish for working with in-terminal image
display in Kitty and WezTerm. But, I have a POSIX-compatible
(including Bash) version (less well tested) included below as well.&lt;/p&gt;
&lt;p&gt;WezTerm&amp;rsquo;s command to display an image in the terminal is &lt;code&gt;wezterm imgcat &amp;lt;/path/to/image/file&amp;gt;&lt;/code&gt;, and Kitty&amp;rsquo;s is &lt;code&gt;kitten icat &amp;lt;/path/to/image/file&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m playing with both terminals, and have a hard time remembering
things, so one thing I&amp;rsquo;ve done is to alias these commands in fish to
just &lt;code&gt;icat&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;More significantly, while WezTerm seems to have a smart auto-sizing of
the image to downsize the rendering to make sure the image fits fully
within the current terminal window, Kitty only seems to guarantee
downsized display to make sure the image fits the current width of the
terminal window, but does not downsize to fit the current height of
the terminal window.&lt;/p&gt;
&lt;p&gt;Thus, in Kitty, we get things like this:&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/auto-sizing-images-in-kitty-terminal/../ox-hugo/kitty-not-autosizing-image.png&#34;/&gt; &lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;(&amp;hellip;.hmm, boots aren&amp;rsquo;t a kitty&amp;hellip;)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While in WezTerm, we get:&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/auto-sizing-images-in-kitty-terminal/../ox-hugo/wezterm-auto-sizing-image.png&#34;/&gt; &lt;/figure&gt;

&lt;p&gt;And with appropriate configuration from below added, the new
(easy-to-remember) &lt;code&gt;icat&lt;/code&gt; command works to produce in-terminal image
display as in WezTerm:&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/auto-sizing-images-in-kitty-terminal/../ox-hugo/kitty-with-new-icat-auto-sizing-image.png&#34;/&gt; &lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;(&amp;hellip;and there&amp;rsquo;s the kitty in Kitty!)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here are the relevant lines that can be added to your shell
configuration file to both make the image display command in both
Kitty and WezTerm both simply &lt;code&gt;icat&lt;/code&gt;, and also resize the display of the
image in Kitty to make sure it fits lengthwise in the current terminal
window:&lt;/p&gt;
&lt;h2 id=&#34;fish-shell&#34;&gt;Fish shell&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fish&#34; data-lang=&#34;fish&#34;&gt;&lt;span class=&#34;c&#34;&gt;#################### BEGIN image display things ######################
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;# image display things for kitty [https://sw.kovidgoyal.net/kitty/]
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#                        &amp;amp; wezterm [https://wezfurlong.org/wezterm/]
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# - use &amp;#39;icat $path/to/image&amp;#39; (in either) to display image in terminal
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# - on inner workings of the image display protocols, see:
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#   - for kitty:    https://sw.kovidgoyal.net/kitty/kittens/icat/
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#   - for wezterm:  https://wezterm.org/cli/imgcat.html
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;# if we&amp;#39;re in kitty:
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&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;$TERM&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;xterm-kitty&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;alias &lt;/span&gt;icat-full &lt;span class=&#34;s2&#34;&gt;&amp;#34;kitten icat&amp;#34;&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# alias the default kitty icat behaviour to `icat-full&amp;#39;
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;
  &lt;span class=&#34;c&#34;&gt;# function icat-auto
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; icat  &lt;span class=&#34;c&#34;&gt;# define auto-resizing version of kitty&amp;#39;s `icat&amp;#39;
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c&#34;&gt;# calculate kitty window size parameters:
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; -l kittysize &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;kitten icat --print-window-size&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# get kitty window size
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; -l kittywidth &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$kittysize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; cut -dx -f1&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# extract width of kitty window
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; -l kittyheight &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$kittysize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; cut -dx -f2&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# extract height of kitty window
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; -l argcount &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;count&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;    &lt;span class=&#34;c&#34;&gt;# count how argumnets to icat there are
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;
    &lt;span class=&#34;c&#34;&gt;# calculate target image size parameters: [requires ImageMagick!]
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; -l imagesize &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;identify -format &lt;span class=&#34;s1&#34;&gt;&amp;#39;%wx%h&amp;#39;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$argcount&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;]&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# `identify&amp;#39; is part of ImageMagick
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; -l imagewidth &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$imagesize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; cut -dx -f1&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# extract width of image
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; -l imageheight &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$imagesize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; cut -dx -f2&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# extract height of image
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; -l reducebyy 1.0  &lt;span class=&#34;c&#34;&gt;# initialise and set to &amp;#39;100%&amp;#39; [no change] y-axis reduction percentage
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; -l reducebyx 1.0  &lt;span class=&#34;c&#34;&gt;# initialise and set to &amp;#39;100%&amp;#39; [no change] x-axis reduction percentage
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;
    &lt;span class=&#34;c&#34;&gt;# test if target image is bigger than kitty window
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$imageheight&lt;/span&gt; -gt &lt;span class=&#34;nv&#34;&gt;$kittyheight&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# if it&amp;#39;s taller than the terminal window
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;                                         &lt;span class=&#34;c&#34;&gt;# divide terminal window height by image height
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;      &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; reducebyy &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;math&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$kittyheight&lt;/span&gt; / &lt;span class=&#34;nv&#34;&gt;$imageheight&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$imagewidth&lt;/span&gt; -gt &lt;span class=&#34;nv&#34;&gt;$kittywidth&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# if it&amp;#39;s widre than the terminal window
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;                                         &lt;span class=&#34;c&#34;&gt;# divide terminal window width by image width
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;      &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; reducebyx &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;math&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$kittywidth&lt;/span&gt; / &lt;span class=&#34;nv&#34;&gt;$imagewidth&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$reducebyy&lt;/span&gt; -lt &lt;span class=&#34;nv&#34;&gt;$reducebyx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# set both reducebyx, reducebyy to smallest of 2 values
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;      &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; reducebyx &lt;span class=&#34;nv&#34;&gt;$reducebyy&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
      &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; reducebyy &lt;span class=&#34;nv&#34;&gt;$reducebyx&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;c&#34;&gt;# calculate target image height and width to fit fully in terminal window
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; imageheight &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;math &lt;/span&gt;floor &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;math&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$reducebyy&lt;/span&gt; x &lt;span class=&#34;nv&#34;&gt;$imageheight&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; imagewidth &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;math &lt;/span&gt;floor &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;math&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$reducebyx&lt;/span&gt; x &lt;span class=&#34;nv&#34;&gt;$imagewidth&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;

    &lt;span class=&#34;c&#34;&gt;# call the `kitten icat&amp;#39; kitty command using the calculated image size
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;if&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;$argcount&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -gt &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# if the user has passed more args than just the target image filepath
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;                             &lt;span class=&#34;c&#34;&gt;# then pass all of those separately along with `--use-window-size&amp;#39; parameter
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;      &lt;span class=&#34;nb&#34;&gt;command &lt;/span&gt;kitten icat --use-window-size &lt;span class=&#34;nv&#34;&gt;$COLUMNS&lt;/span&gt;,&lt;span class=&#34;nv&#34;&gt;$LINES&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$imagewidth&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$imageheight&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;1..&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;math&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;count&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; - 1&lt;span class=&#34;o&#34;&gt;)]&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;count&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)]&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
      &lt;span class=&#34;nb&#34;&gt;command &lt;/span&gt;kitten icat --use-window-size &lt;span class=&#34;nv&#34;&gt;$COLUMNS&lt;/span&gt;,&lt;span class=&#34;nv&#34;&gt;$LINES&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$imagewidth&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$imageheight&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;1&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
  &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

  &lt;span class=&#34;c&#34;&gt;# if we&amp;#39;re in WezTerm, alias `icat&amp;#39; to wezterm&amp;#39;s imgcat
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&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;$TERM_PROGRAM&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;WezTerm&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;alias &lt;/span&gt;icat &lt;span class=&#34;s2&#34;&gt;&amp;#34;wezterm imgcat&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;c&#34;&gt;# NOTE: currently not sure best way of emulating kitty&amp;#39;s default image display behaviour
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c&#34;&gt;#      - mainly because I don&amp;#39;t know how to get the WezTerm window size in a
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c&#34;&gt;#        fashion that&amp;#39;s window-manager neutral and neutral between
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c&#34;&gt;#        graphical display protocol (i.e., X11 vs Wayland)
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;
    &lt;span class=&#34;c&#34;&gt;# draft version of default kitty icat-like behaviour for `imgcat&amp;#39;
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c&#34;&gt;# function icat-full
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c&#34;&gt;#   set -l imagesize (identify -format &amp;#39;%w&amp;#39; &amp;#34;$argv[$argcount]&amp;#34;)
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c&#34;&gt;# end
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# alias icat-full &amp;#34;wezterm imgcat --width 100%&amp;#34;
&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;#################### END image display things ######################
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;posix-shell--including-bash&#34;&gt;POSIX shell (including Bash)&lt;/h2&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;#################### BEGIN image display things ######################&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# image display things for kitty [https://sw.kovidgoyal.net/kitty/]&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;#                        &amp;amp; wezterm [https://wezfurlong.org/wezterm/]&lt;/span&gt;
#
&lt;span class=&#34;c1&#34;&gt;# - use &amp;#39;icat $path/to/image&amp;#39; (in either) to display image in terminal&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;# - on inner workings of the image display protocols, see:&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;#   - for kitty:    https://sw.kovidgoyal.net/kitty/kittens/icat/&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;#   - for wezterm:  https://wezterm.org/cli/imgcat.html&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# if we&amp;#39;re in kitty:&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;if&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;$TERM&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;xterm-kitty&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;alias&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;icat_full&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;kitten icat&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# alias the default kitty icat behaviour to `icat-full&amp;#39;&lt;/span&gt;

    icat &lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# define auto-resizing version of kitty&amp;#39;s `icat&amp;#39;&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;# calculate kitty window size parameters:&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;kittysize&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;kitten icat --print-window-size&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# get kitty window size&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;kittywidth&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;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$kittysize&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; cut -dx -f1&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# extract width of kitty window&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;kittyheight&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;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$kittysize&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; cut -dx -f2&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# extract height of kitty window&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;# calculate target image size parameters: [requires ImageMagick!]&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;icat_last_arg_pos&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;$#&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;}&amp;#34;&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;icat_last_arg_content&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;&lt;span class=&#34;nb&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$icat_last_arg_pos&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;identify_command&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;identify -format &amp;#39;%wx%h&amp;#39; \&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$icat_last_arg_content&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# `identify&amp;#39; is part of ImageMagick&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;imagesize&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;&lt;span class=&#34;nb&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$identify_command&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;imagewidth&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;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$imagesize&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; cut -dx -f1&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# extract width of image&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;imageheight&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;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$imagesize&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; cut -dx -f2&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# extract height of image&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;reducebyy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;100&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# initialise and set to &amp;#39;100%&amp;#39; [no change] y-axis reduction percentage&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;reducebyx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;100&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# initialise and set to &amp;#39;100%&amp;#39; [no change] x-axis reduction percentage&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;# test if target image is bigger than kitty window&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&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;$imageheight&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -gt &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$kittyheight&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# if it&amp;#39;s taller than the terminal window&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;c1&#34;&gt;# divide terminal window height by image height&lt;/span&gt;
            &lt;span class=&#34;nv&#34;&gt;reducebyy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt; kittyheight &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; imageheight &lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&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;$imagewidth&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -gt &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$kittywidth&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# if it&amp;#39;s wider than the terminal window&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;c1&#34;&gt;# divide terminal window width by image width&lt;/span&gt;
            &lt;span class=&#34;nv&#34;&gt;reducebyx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt; kittywidth &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; imagewidth &lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&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;$reducebyy&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -lt &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$reducebyx&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# set both reducebyx, reducebyy to smallest of 2 values&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;nv&#34;&gt;reducebyx&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;$reducebyy&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
            &lt;span class=&#34;nv&#34;&gt;reducebyy&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;$reducebyx&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;# calculate target image height and width to fit fully in terminal window&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;imageheight&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt; reducebyy &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; imageheight &lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;imagewidth&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt; reducebyx &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; imagewidth &lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
        kitten icat --use-window-size &lt;span class=&#34;nv&#34;&gt;$COLUMNS&lt;/span&gt;,&lt;span class=&#34;nv&#34;&gt;$LINES&lt;/span&gt;,&lt;span class=&#34;nv&#34;&gt;$imagewidth&lt;/span&gt;,&lt;span class=&#34;nv&#34;&gt;$imageheight&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;span class=&#34;o&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# if we&amp;#39;re in WezTerm, alias `icat&amp;#39; to wezterm&amp;#39;s imgcat&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;elif&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;$TERM_PROGRAM&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;WezTerm&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;alias&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;icat&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;wezterm imgcat&amp;#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;#################### END image display things ######################&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;note-about-built-in-capacity&#34;&gt;Note about built-in capacity&lt;/h2&gt;
&lt;p&gt;I confirmed with the developer, &lt;a href=&#34;https://kovidgoyal.net/&#34;&gt;Kovid Goyal&lt;/a&gt;, that currently Kitty
does not have an &amp;ldquo;autofit&amp;rdquo; option (other than it&amp;rsquo;s default autofit to
fit width), see &lt;a href=&#34;https://github.com/kovidgoyal/kitty/issues/9201&#34;&gt;GitHub issue #9201&lt;/a&gt;. But Kovid seems to have gone ahead
and added a built-it &lt;code&gt;--fit&lt;/code&gt; option for Kitty, so a built-in way of
managing image display with respect to window size should be
available natively in an upcoming Kitty release.&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/terminals">terminals</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/auto-sizing-images-in-kitty-terminal/</guid>
                <pubDate>Sat, 08 Nov 2025 21:50:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Trials and Visions of Internet Relay Chat</title>
                <link>https://babbagefiles.xyz/no-one-can-be-told-what-irc-is-you-have-to-logon-for-yourself/</link>
                
                
                <description>&lt;p&gt;This was meant to be a shortish bit on a couple of points on a decent
&lt;a href=&#34;https://en.wikipedia.org/wiki/IRC&#34;&gt;IRC (Internet Relay Chat)&lt;/a&gt; set-up, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;some sort of persistence (a &amp;ldquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/BNC_(software)#IRC&#34;&gt;bouncer&lt;/a&gt;&amp;rdquo; or the always-connected server)&lt;/li&gt;
&lt;li&gt;use with some sort of IRC client in Emacs&lt;/li&gt;
&lt;li&gt;some sort of reasonable mobile phone client&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It ended up longer than I intended.&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;tldr&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Using some of the more &lt;a href=&#34;https://ircv3.net&#34;&gt;IRCv3&lt;/a&gt; tools, particularly the cluster of
things by &lt;a href=&#34;https://emersion.fr&#34;&gt;Simon Ser&lt;/a&gt; and co (soju, goguma, gamja - see below) makes
for a much better IRC experience, and easily supports synchronised
access across multiple devices (e.g., desktop, laptops, mobile).
&lt;ul&gt;
&lt;li&gt;soju provides a very capable bouncer&lt;/li&gt;
&lt;li&gt;goguma provides an excellent mobile client&lt;/li&gt;
&lt;li&gt;gamja is a very user-friendly web-client front-end&lt;/li&gt;
&lt;li&gt;and these three things can complement each other in a complete IRC
setup system&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;we can make such a soju-based set-up work well with Emacs IRC clients&lt;/li&gt;
&lt;li&gt;soju and gamja can be self-hosted; but there are also two
paid/hosted instances currently available:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://chat.sr.ht&#34;&gt;SourceHut&amp;rsquo;s chat.sr.ht&lt;/a&gt; (on a fork of soju with a different feature-set)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://irctoday.com&#34;&gt;IRC Today&amp;rsquo;s service&lt;/a&gt; (I think closer to mainline soju, but not certain)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;we can leverage some of the IRCv3 functions nicely in Emacs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The most useful bits here may be notes on how to set up clients to
work with &lt;a href=&#34;https://sourcehut.org/blog/2021-11-29-announcing-the-chat.sr.ht-public-beta&#34;&gt;SourceHut&amp;rsquo;s chat.sr.ht&lt;/a&gt;, particularly Goguma and Emacs/ERC,
and some of the cool features of IRCv3 things [modernising IRC], like
the soju bouncer (which is used by chat.sr.ht), for which see the
section below &amp;ldquo;&lt;a href=&#34;https://babbagefiles.xyz/no-one-can-be-told-what-irc-is-you-have-to-logon-for-yourself/#smooth-and-modern-irc-implementation-and-practice--mobile-emacs&#34;&gt;Smooth &amp;amp; Modern IRC Implementation &amp;amp; Practice
(mobile, Emacs)&lt;/a&gt;&amp;quot;, which you might jump to if you don&amp;rsquo;t want to read a
bunch of preamble.&lt;/p&gt;
&lt;h2 id=&#34;history-theory-background&#34;&gt;History, theory, background&lt;/h2&gt;
&lt;h3 id=&#34;pre-history-wee-chats-in-musl-pies&#34;&gt;Pre-history: wee chats in musl pies&lt;/h3&gt;
&lt;p&gt;Long ago now I spent a while setting up a RaspberryPi 3b (running &lt;a href=&#34;https://docs.voidlinux.org/installation/musl.html&#34;&gt;musl
flavoured Void Linux&lt;/a&gt;) as a &lt;a href=&#34;https://weechat.org/&#34;&gt;Weechat&lt;/a&gt; Server/Bouncer in order to make
using IRC less painful. This involved a lot of steps, including
setting up a &lt;a href=&#34;https://www.noip.com/&#34;&gt;NoIP&lt;/a&gt; script and SSL certs with &lt;a href=&#34;https://letsencrypt.org/&#34;&gt;Let&amp;rsquo;s Encrypt&lt;/a&gt;, and setting
up scripts to auto-fetch new certs. But once up, it worked well
(unless my home internet went out), and Weechat had a nice mobile app,
so I could connect both on desktop/laptop with an &lt;a href=&#34;https://github.com/the-kenny/weechat.el&#34;&gt;Emacs IRC client&lt;/a&gt; and
also had a pocket connection via my mobile
phone &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;. This gave me a persistent connection and
log history and all that.&lt;/p&gt;
&lt;p&gt;Then I started using &lt;a href=&#34;https://matrix.org&#34;&gt;Matrix&lt;/a&gt; (=a modern, but heavy, &amp;ldquo;IRC replacement&amp;rdquo;,
itself theoretically a Slack, Discord, &amp;amp;c. competitor) more, (in part) since some projects have
chosen it as a more modern/capable alternative to IRC, and, soon
after, it was the case that most of the IRC rooms I was in were
bridged to Matrix anyway. And then it seemed perhaps more convenient
just to access everything in one place, since some things were only
Matrix and not on IRC, it made sense for that to be Matrix.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://libera.chat/news/matrix-bridge-disabled-retrospective&#34;&gt;And then the Matrix bridges mostly shut down.&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;path-of-the-prodircal-son&#34;&gt;Path of the prodIRCal son&lt;/h3&gt;
&lt;p&gt;I toyed off and on with getting re-set up on IRC, but there has been a
lot of other things going on in life, and I didn&amp;rsquo;t feel like trying to
set up my rpi mini-server IRC bouncer again.&lt;/p&gt;
&lt;p&gt;I tried some other hosted IRC bouncer services. But some of these
wouldn&amp;rsquo;t let me connect with on a VPN.&lt;/p&gt;
&lt;p&gt;I found one good free (as in freedom and free as in no paisa) &lt;a href=&#34;https://en.wikipedia.org/wiki/ZNC&#34;&gt;ZNC&lt;/a&gt;
bouncer service, which is FreeIRC.org &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;&lt;/p&gt;
&lt;p&gt;The ZNC bouncer worked fine on Emacs (with &lt;a href=&#34;https://www.gnu.org/software/emacs/erc.html&#34;&gt;ERC&lt;/a&gt;; I&amp;rsquo;ve gone back and
forth between ERC and &lt;a href=&#34;https://www.nongnu.org/circe/&#34;&gt;Circe&lt;/a&gt;, but this time I was trying ERC
again).&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; And I eventually figured out how to connect to multiple
networks through the ZNC bouncer.&lt;/p&gt;
&lt;p&gt;But the best thing I could find on mobile was the &lt;a href=&#34;https://github.com/MCMrARM/revolution-irc&#34;&gt;Revolution IRC
client&lt;/a&gt;, and, while it&amp;rsquo;s a nice enough front-end, it struggled with
maintaining a connection to the ZNC bouncer I was using. (I asked
about this in an IRC room, and the general consensus was that mobile&amp;rsquo;s
just not a good place to try to do IRC, but I remembered that via the
&lt;a href=&#34;https://github.com/ubergeek42/weechat-android&#34;&gt;Weechat android app&lt;/a&gt; or through &lt;a href=&#34;https://glowing-bear.org/&#34;&gt;Glowing Bear&lt;/a&gt; I&amp;rsquo;d had a good mobile IRC
experience years ago.)&lt;/p&gt;
&lt;h3 id=&#34;ircv3-and-other-korean-tubers&#34;&gt;IRCv3, and other Korean tubers&lt;/h3&gt;
&lt;p&gt;I also came across another IRC mobile app, &lt;a href=&#34;https://codeberg.org/emersion/goguma&#34;&gt;Goguma&lt;/a&gt;, but couldn&amp;rsquo;t get it
work. But, frustrated with the situation, I wanted to see if, assuming
I &lt;em&gt;could&lt;/em&gt; somehow get it work, Goguma might be a better mobile
solution.&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;I ultimately ended up stumbling across an &lt;a href=&#34;https://lobste.rs/s/wy2jgl/goguma_irc_client_for_mobile_devices&#34;&gt;interesting lobste.rs
discussion of Goguma&lt;/a&gt; which pointed to it being part of a set of
&lt;a href=&#34;https://ircv3.net&#34;&gt;IRCv3&lt;/a&gt;-aware software, including an IRC bouncer &lt;a href=&#34;https://soju.im&#34;&gt;soju&lt;/a&gt;, which a number of
the commenters on the lobste.rs thread comparing the experience
favourably against using ZNC.&lt;/p&gt;
&lt;p&gt;A cluster of IRCv3 things:&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;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://codeberg.org/emersion/goguma&#34;&gt;Goguma&lt;/a&gt; (Korean 고구마 &lt;em&gt;goguma&lt;/em&gt; &amp;ldquo;sweet potato&amp;rdquo;): IRC mobile client written in Flutter by Simon Ser&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://codeberg.org/emersion/gamja&#34;&gt;Gamja&lt;/a&gt; (Korean 감자 &lt;em&gt;gamja&lt;/em&gt; &amp;ldquo;potato&amp;rdquo;): simple IRC web client written in Javascript by Simon Ser&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://soju.im&#34;&gt;Soju&lt;/a&gt; (Korean 소주 &lt;em&gt;soju&lt;/em&gt; &amp;ldquo;a distilled alcoholic beverage&amp;rdquo;): IRC bouncer written in Go by Simon Ser&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://git.sr.ht/~delthas/senpai/&#34;&gt;Senpai&lt;/a&gt; (Japanese 先輩 &lt;em&gt;sèńpáí&lt;/em&gt; &amp;ldquo;senior in social standing or level of education/skill; an elder&amp;rdquo;): a modern terminal IRC written in Go, started by &amp;lsquo;&lt;a href=&#34;https://sr.ht/~taiite/&#34;&gt;taiite&lt;/a&gt;&#39;, who handed development over to &amp;lsquo;&lt;a href=&#34;https://delthas.fr&#34;&gt;delthas&lt;/a&gt;&#39;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ergochat/ergo&#34;&gt;Ergo&lt;/a&gt; (a play on ergonomic [and &amp;ldquo;&lt;a href=&#34;https://github.com/jlatt/ergonomadic&#34;&gt;ergonomadic&lt;/a&gt;&amp;quot;] and Go(lang), so I suppose ultimately from Ancient Greek ἔργον &lt;em&gt;érgon&lt;/em&gt; &amp;ldquo;work&amp;rdquo;, but not sure that&amp;rsquo;s relevant): a modern IRC server written in Go [&lt;a href=&#34;https://github.com/jlatt&#34;&gt;Jeremy Latt&lt;/a&gt;, &lt;a href=&#34;https://danieloaks.net&#34;&gt;Daniel Oaks&lt;/a&gt;, &lt;a href=&#34;https://cs.stanford.edu/people/slingamn&#34;&gt;Shivaram Lingamneni&lt;/a&gt;] implementing bleeding-edge IRCv3 features/support&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first three things are the most relevant for us (well, me). Ergo
sounds great, but I&amp;rsquo;m not &lt;em&gt;running&lt;/em&gt; an IRC server myself at the moment;
and I&amp;rsquo;ve got a whole wealth of choices of Emacs IRC clients if I&amp;rsquo;m on
desktop/laptop, so Senpai doesn&amp;rsquo;t seem relevant either for my use
case.&lt;/p&gt;
&lt;h3 id=&#34;trains-wayland-and-things-that-go&#34;&gt;Trains, Wayland, and Things that Go&lt;/h3&gt;
&lt;p&gt;The first three of the IRCv3-looking things are all by &lt;a href=&#34;https://emersion.fr&#34;&gt;Simon Ser&lt;/a&gt;, who
was lately at &lt;a href=&#34;https://drewdevault.com&#34;&gt;Drew DeVault&lt;/a&gt;&amp;lsquo;s &lt;a href=&#34;https://sourcehut.org&#34;&gt;SourceHut&lt;/a&gt;, but seems to have left
sometime in 2024&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; and now works at &lt;a href=&#34;https://osrd.fr/&#34;&gt;Open
Source Railway Designer&lt;/a&gt; (something to do with making tools for railway
infrastructure simulation, which sounds quite cool: open source
trains). Ser obviously works a good bit on IRC-related software, and
also a lot of things in Go, and has been involved with &lt;a href=&#34;https://wayland.freedesktop.org/&#34;&gt;Wayland&lt;/a&gt;-related
projected (taking over maintainership of &lt;a href=&#34;https://swaywm.org&#34;&gt;Sway&lt;/a&gt; (a Wayland window
manager) and &lt;a href=&#34;https://gitlab.freedesktop.org/wlroots/wlroots/&#34;&gt;wlroots&lt;/a&gt; (Wayland general purpose compositor underlying
Sway and other things) from DeVault &lt;a href=&#34;https://drewdevault.com/2020/10/23/Im-handing-wlroots-and-sway-to-Simon.html&#34;&gt;some years back&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s Thomas Flament &amp;amp; Simon Ser talking about IRCv3 and soju,
senpai, gamja, goguma at FOSDEM &amp;lsquo;25 in Brussels:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://fosdem.org/2025/schedule/event/fosdem-2025-6407-chatting-on-irc-in-2025-grandpa-what-s-up-/&#34;&gt;Chatting on IRC in 2025: grandpa, what&amp;rsquo;s up?&lt;/a&gt; [video link with captions]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In any case, one of the paid-only features that SourceHut offers is
via &lt;a href=&#34;https://man.sr.ht/chat.sr.ht/&#34;&gt;chat.sr.ht&lt;/a&gt;, an IRC bouncer, which is running on a &lt;a href=&#34;https://git.sr.ht/~bitfehler/soju&#34;&gt;fork of soju&lt;/a&gt;,
with a web-client based on gamja.&lt;/p&gt;
&lt;p&gt;As far as I can tell, Sourcehut&amp;rsquo;s servers are now (all? mainly?) in
Amsterdam.&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;&lt;/p&gt;
&lt;p&gt;chat.sr.ht isn&amp;rsquo;t the only hosted IRC bouncer service which runs some
version of the soju bouncer, there is also &lt;a href=&#34;https://irctoday.com&#34;&gt;IRC Today&lt;/a&gt; [&lt;a href=&#34;https://lobste.rs/s/zc0xh7/irc_today_hosted_irc_bouncer&#34;&gt;discussed also
on lobste.rs&lt;/a&gt;], which is hosted in Paris on &lt;a href=&#34;https://www.scaleway.com&#34;&gt;Scaleway&lt;/a&gt;
servers.&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;So, there are at least two apparently EU-based hosted &amp;ldquo;IRCv3-forward&amp;rdquo;
bouncers.&lt;/p&gt;
&lt;h2 id=&#34;smooth-and-modern-irc-implementation-and-practice--mobile-emacs&#34;&gt;Smooth &amp;amp; Modern IRC Implementation &amp;amp; Practice (mobile, Emacs)&lt;/h2&gt;
&lt;h3 id=&#34;how-to-manage-to-drink-rice-liquor-in-a-hut-preliminaries&#34;&gt;How to manage to drink rice liquor in a hut: preliminaries&lt;/h3&gt;
&lt;p&gt;In any case, I signed up for the SourceHut offering at chat.sr.ht,
which uses their fork of soju.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what I did to get it set up for mobile and in Emacs (it seemed
worth documenting, in what was meant to be a short post&amp;hellip;.):&lt;/p&gt;
&lt;p&gt;The main things one needs to know are in the &lt;a href=&#34;https://man.sr.ht/chat.sr.ht/&#34;&gt;chat.sr.hut &amp;lsquo;manpages&amp;rsquo;&lt;/a&gt;,
especially the &lt;a href=&#34;https://man.sr.ht/chat.sr.ht/quickstart.md&#34;&gt;&amp;lsquo;quickstart guide&amp;rsquo;&lt;/a&gt;. But here are a few more notes for
specific set-up on Goguma and Emacs.&lt;/p&gt;
&lt;p&gt;The first thing one needs to do for any &amp;ldquo;third-party&amp;rdquo; client (this
includes Goguma or any Emacs IRC client) is &lt;a href=&#34;https://meta.sr.ht/oauth2/personal-token?grants=meta.sr.ht/PROFILE:RO&#34;&gt;generate an OAuth 2.0
personal access token in your SourceHut account&lt;/a&gt;. This will be
effectively your &amp;ldquo;password&amp;rdquo; (with your SourceHut login name as your
username).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nb&lt;/strong&gt;: on mobile, you have to be careful to actually manage to copy the
entire token with &amp;ldquo;Select all&amp;rdquo; or the like - I was stuck for a long
time not being able to make Goguma work because I&amp;rsquo;d not managed to
copy the entire token, and this wasn&amp;rsquo;t at all obvious in a mobile
browser. On desktop, it&amp;rsquo;s not an issue.&lt;/p&gt;
&lt;h3 id=&#34;goguma--mobile--one-potato-two-potato-sweet-potato&#34;&gt;Goguma (mobile): One potato, two potato, sweet potato&lt;/h3&gt;
&lt;p&gt;For Goguma, you&amp;rsquo;re just going to put in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Server: &lt;code&gt;chat.sr.ht&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Nickname: &amp;lt;your SourceHut username&amp;gt;&lt;/li&gt;
&lt;li&gt;Password: &amp;lt;an OAuth2.0 token you generated as above&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And you&amp;rsquo;re in. And here&amp;rsquo;s what it looks like:&lt;/p&gt;



&lt;figure&gt;
    &lt;a href=&#34;https://babbagefiles.xyz/ox-hugo/goguma-sr.ht.png&#34;&gt;
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/goguma-sr.ht.png&#34; alt=&#34;Figure 1: Goguma with normal &amp;ldquo;bubble&amp;rdquo; display mode in #sr.ht@libera.chat&#34;/&gt; &lt;/a&gt;&lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 1: &lt;/span&gt;Goguma with normal &amp;ldquo;bubble&amp;rdquo; display mode in #sr.ht@libera.chat
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;And there&amp;rsquo;s a setting in Goguma (&amp;ldquo;Compact message list&amp;rdquo;) to make it
look less like a mobile messaging app and just have plain text if you
prefer that:&lt;/p&gt;



&lt;figure&gt;
    &lt;a href=&#34;https://babbagefiles.xyz/ox-hugo/goguma-sr.ht_compact.png&#34;&gt;
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/goguma-sr.ht_compact.png&#34; alt=&#34;Figure 2: Goguma in &amp;ldquo;compact message list&amp;rdquo; display mode in #sr.ht@libera.chat&#34;/&gt; &lt;/a&gt;&lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 2: &lt;/span&gt;Goguma in &amp;ldquo;compact message list&amp;rdquo; display mode in #sr.ht@libera.chat
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;And you can have Goguma show you notifications if someone mentions
your nick. Here is an example showing on a Pebble watch:&lt;/p&gt;



&lt;figure&gt;
    &lt;a href=&#34;https://babbagefiles.xyz/ox-hugo/goguma-pebble-notification.jpg&#34;&gt;
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/goguma-pebble-notification.jpg&#34; alt=&#34;Figure 3: Goguma nick mention notification displaying on Pebble watch&#34;/&gt; &lt;/a&gt;&lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 3: &lt;/span&gt;Goguma nick mention notification displaying on Pebble watch
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;(IRC on one&amp;rsquo;s wrist; it truly is 2025.)&lt;/p&gt;
&lt;h3 id=&#34;emacs-machines-and-authority-tokens-what-to-put-in-your-authinfo-dot-gpg-and-init-dot-el&#34;&gt;Emacs machines and authority tokens: what to put in your authinfo.gpg and init.el&lt;/h3&gt;
&lt;p&gt;In your &lt;code&gt;~/.authinfo.gpg&lt;/code&gt; file, add a line like this (with &amp;lt;&amp;gt;&amp;lsquo;ed items
to be replaced fully; don&amp;rsquo;t actually include any &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;&#39;s here or above or
elsewhere; where &lt;code&gt;&amp;quot;my-sourcehut-id&amp;quot;&lt;/code&gt; is your actual sourcehut login id
in quotes):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;machine chat.sr.ht login &amp;quot;my-sourcehut-id&amp;quot; password &amp;quot;&amp;lt;one of your OAuth 2.0 tokens generated at SourceHut meta&amp;gt;&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And then in your &lt;code&gt;~.emacs.d/init.el&lt;/code&gt;, assuming you&amp;rsquo;re using ERC and have
that configured otherwise to your liking, make a user-function for
each actual IRC server you want to connect with via chat.sr.ht/soju,
like this (assuming your user-id is &lt;code&gt;&amp;quot;my-sourcehut-id&amp;quot;&lt;/code&gt;: replace
appropriately— and you might have different &lt;code&gt;:nick&lt;/code&gt;&#39;s (&amp;ldquo;nicknames&amp;rdquo; ≈
user-handles/user-names/identities) on different servers, of course,
so adjust those as well; but your &lt;code&gt;:username&lt;/code&gt; is going to be
consistently your SourceHut username followed by
&amp;ldquo;/&amp;lt;the-particular-irc-server-address&amp;gt;&amp;quot;):&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;;; just so we don&amp;#39;t have to type it each time, a wrapping `let&amp;#39;,&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; and so after this our `server&amp;#39;, `port&amp;#39;, &amp;amp; `passwd&amp;#39; will be thus defined&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; (you could do `:nick&amp;#39; like this too if it&amp;#39;s the same everywhere)&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;server&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;chat.sr.ht&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;port&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6697&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;passwd&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cadr&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;auth-source-user-and-password&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;chat.sr.ht&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;my-sourcehut-id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; `auth-source-user-and-password&amp;#39; returns a list of `login&amp;#39; and `password&amp;#39;&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; from your .authinfo.gpg; but we just need the second, so `cadr&amp;#39; (= return&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; the `car&amp;#39; of the `cdr&amp;#39;), because since the list is going to be something&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; like `(mylogin mypassword)&amp;#39;, will give us just the atomic `mypassword&amp;#39;,&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; which is what we want [because the `cdr&amp;#39; of `(mylogin mypassword)&amp;#39; will be&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; `(mypassword)&amp;#39; and the `car&amp;#39; of `(mypassword)&amp;#39; will be just `mypassword&amp;#39;].)&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;erc-libera&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;s&#34;&gt;&amp;#34;Connect to Libera.Chat IRC server.&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&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;erc-tls&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:nick&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsuser007&amp;#34;&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:server&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;server&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:port&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;port&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:user&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;my-sourcehut-id/irc.libera.chat&amp;#34;&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:password&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;passwd&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;erc-oftc&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;s&#34;&gt;&amp;#34;Connect to OFTC IRC server.&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&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;erc-tls&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:nick&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsuser007&amp;#34;&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:server&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;server&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:port&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;port&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:user&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;my-sourcehut-id/irc.oftc.net&amp;#34;&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:password&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;passwd&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;erc-ircnow&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;s&#34;&gt;&amp;#34;Connect to IRCNow IRC server.&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&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;erc-tls&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:nick&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsuser007&amp;#34;&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:server&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;server&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:port&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;port&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:user&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;my-sourcehut-id/irc6.ircnow.org&amp;#34;&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:password&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;passwd&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;erc-ergo&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;s&#34;&gt;&amp;#34;Connect to IRCv3-forward Ergo IRC server.&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&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;erc-tls&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:nick&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsuser007&amp;#34;&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:server&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;server&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:port&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;port&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:user&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;my-sourcehut-id/irc.ergo.chat&amp;#34;&lt;/span&gt;
     &lt;span class=&#34;nb&#34;&gt;:password&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;passwd&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;Here we&amp;rsquo;re making connections for &lt;a href=&#34;https://libera.chat&#34;&gt;Libera&lt;/a&gt;, &lt;a href=&#34;https://www.oftc.net/&#34;&gt;OFTC&lt;/a&gt;, &lt;a href=&#34;https://ircnow.org&#34;&gt;IRCNow&lt;/a&gt;, and &lt;a href=&#34;https://ergo.chat/about-network&#34;&gt;Ergo&lt;/a&gt;, the
IRCv3-forward server implemented in Go we mentioned above.&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;/p&gt;
&lt;p&gt;But you can add lots of different servers to your bouncer, and both in
Goguma and Emacs/ERC (just make a new &lt;code&gt;erc-&amp;lt;server&amp;gt;&lt;/code&gt; function as above),
you&amp;rsquo;ll just be able to get to all of the different rooms in one place
and don&amp;rsquo;t necessary need to worry about which server a particular
thing is on after getting it set up.&lt;/p&gt;
&lt;p&gt;And then you can make a &amp;ldquo;connect to all the things function&amp;rdquo; 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;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;erc-connect-all&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Connect to all IRC servers above.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; we&amp;#39;re just calling all of the functions we defined above here:&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;erc-libera&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;erc-oftc&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;erc-ircnow&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;erc-ergo&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 what it looks like (well, it looks like however you&amp;rsquo;ve configured
ERC or whatever Emacs IRC client you&amp;rsquo;re using, but, in case you want
to see a possible way it could look):&lt;/p&gt;



&lt;figure&gt;
    &lt;a href=&#34;https://babbagefiles.xyz/ox-hugo/erc-sr.ht.png&#34;&gt;
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/erc-sr.ht.png&#34; alt=&#34;Figure 4: in ERC on chat.sr.ht visiting #sr.ht@libera.chat&#34;/&gt; &lt;/a&gt;&lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 4: &lt;/span&gt;in ERC on chat.sr.ht visiting #sr.ht@libera.chat
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;If you get knocked offline momentarily, ERC will try to reconnect to
the bouncer. If you are knocked off or close Emacs for a while, you
might want to catch up on what you missed recently. And there&amp;rsquo;s a nice
IRCv3 feature implemented in soju (and in chat.sr.ht) for this, as
discussed in the next section.&lt;/p&gt;
&lt;h3 id=&#34;leveraging-ircv3-features-in-emacs&#34;&gt;Leveraging IRCv3 features in Emacs&lt;/h3&gt;
&lt;p&gt;We can also do another convenient thing for our Emacs IRC
configuration now. IRCv3 defines a &amp;ldquo;chathistory&amp;rdquo; extension, as an easy
way of retrieving earlier IRC room content. This doesn&amp;rsquo;t work most
places, but it works on any bouncers based on soju (see notes below),
the syntax being &lt;code&gt;/quote CHATHISTORY LATEST &amp;lt;channelname&amp;gt; * &amp;lt;number-of-lines-to-fetch&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can make this more user-friendly in Emacs with something like
this, an interactive command that fetches history for whatever IRC
room it&amp;rsquo;s called in (a 100 lines by default; prefix &lt;code&gt;C-u&lt;/code&gt; to enter a
different number):&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;erc-chatsrht-give-me-more-irc-history&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Get more history for current IRC buffer (IRCv3 only).
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Defaults to 100 lines of history; when C-u prefixed, asks user for
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;number of lines to fetch.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;If using an IRCv3 capable server/bouncer (like chat.sr.ht), fetch the
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;chat history via the IRCv3 chathistory extension. (Currently, only
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;soju-based servers implement this feature; see:
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;https://ircv3.net/software/clients)
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;For more on chathistory, see:
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; - https://man.sr.ht/chat.sr.ht/bouncer-usage.md#chat-history-logs
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; - https://ircv3.net/specs/extensions/chathistory
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; - https://soju.im/doc/soju.1.html&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&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;nv&#34;&gt;not&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;with-current-buffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;current-buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
              &lt;span class=&#34;nv&#34;&gt;major-mode&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;nv&#34;&gt;erc-mode&lt;/span&gt;
              &lt;span class=&#34;nv&#34;&gt;circe-mode&lt;/span&gt;
              &lt;span class=&#34;nv&#34;&gt;rcirc-mode&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;message&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;not an IRC buffer; ignoring&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;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;lines&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&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;channel&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;buffer-name&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;nv&#34;&gt;current-prefix-arg&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;progn&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;lines&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;read-number&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;How many lines to fetch: &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;lines&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;erc-send-input&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;concat&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;/quote CHATHISTORY LATEST &amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;channel&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;nf&#34;&gt;number-to-string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;lines&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then you can just call &lt;code&gt;erc-chatsrht-give-me-more-irc-history&lt;/code&gt; in an IRC
buffer (you might find a convenient keybinding for it) to get prior
IRC chat in that buffer.&lt;/p&gt;
&lt;p&gt;This sort of thing makes Emacs a very pleasant environment to manage
IRC in.&lt;/p&gt;
&lt;p&gt;Now, for actually adding servers to your chat.sr.ht bouncer in the
first place, you might try out the gamja web client (see &lt;a href=&#34;https://babbagefiles.xyz/no-one-can-be-told-what-irc-is-you-have-to-logon-for-yourself/#web-client-the-sweetness-of-non-sweet-potatoes-on-the-web&#34;&gt;below&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&#34;inline-images-and-files-in-goguma-and-emacs&#34;&gt;Inline images and files in Goguma and Emacs&lt;/h3&gt;
&lt;p&gt;Oh. Gamja (as least as implemented by chat.sr.ht) doesn&amp;rsquo;t seem to do it, but
Goguma fetches image links and displays a preview:&lt;/p&gt;



&lt;figure&gt;
    &lt;a href=&#34;https://babbagefiles.xyz/ox-hugo/irc-df-image-goguma.jpg&#34;&gt;
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/irc-df-image-goguma.jpg&#34; alt=&#34;Figure 5: in the goguma mobile client, an image preview in #dwarffortress@libera.chat&#34;/&gt; &lt;/a&gt;&lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 5: &lt;/span&gt;in the goguma mobile client, an image preview in #dwarffortress@libera.chat
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;[Note: chat.sr.ht&amp;rsquo;s soju fork doesn&amp;rsquo;t currently offer direct
file-upload and is perhaps unlikely to, but this seems to be
implemented in upstream soju and maybe on IRC Today.]&lt;/p&gt;
&lt;p&gt;Additional note: Goguma doesn&amp;rsquo;t do this by default; you need to go
into the main &amp;ldquo;Settings&amp;rdquo; menu and enable &amp;ldquo;Display link previews&amp;rdquo;. (I
also have &amp;ldquo;Send &amp;amp; display typing indicators&amp;rdquo; turned on here.)&lt;/p&gt;
&lt;p&gt;And you can make ERC do similarly, with respect to fetching posted
image links, with the &lt;a href=&#34;https://melpa.org/#/erc-image&#34;&gt;erc-image package from MELPA&lt;/a&gt;. I have a
&lt;code&gt;use-package&lt;/code&gt; definition 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;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;erc-image&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:after&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;erc&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&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;erc-image-inline-rescale&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; maybe set bigger&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-to-list&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;erc-modules&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;image&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 then you&amp;rsquo;ll see something like this if you post an image link in ERC:&lt;/p&gt;



&lt;figure&gt;
    &lt;a href=&#34;https://babbagefiles.xyz/ox-hugo/irc-df-image-erc.png&#34;&gt;
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/irc-df-image-erc.png&#34; alt=&#34;Figure 6: in ERC, an image preview in #dwarffortress@libera.chat&#34;/&gt; &lt;/a&gt;&lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 6: &lt;/span&gt;in ERC, an image preview in #dwarffortress@libera.chat
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;I&amp;rsquo;d like to figure out how one might better manage it, but — in terms
of handling posting local files — there&amp;rsquo;s a (not-on-MELPA) package
&lt;a href=&#34;https://github.com/ecraven/imgbb.el/&#34;&gt;imgbb.el&lt;/a&gt; which will upload images in Emacs (when passed a file-path or
interactively from a file-chooser) to &lt;a href=&#34;https://imgbb.com/&#34;&gt;ImgBB&lt;/a&gt;, and then put the link in
the clipboard.&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;p&gt;[Note: For better or worse, &lt;code&gt;erc-image&lt;/code&gt; will pull images from http as
well as https addresses; while Goguma seems only to do the latter.]&lt;/p&gt;
&lt;h3 id=&#34;web-client-the-sweetness-of-non-sweet-potatoes-on-the-web&#34;&gt;Web-client: The sweetness of non-sweet potatoes on the web&lt;/h3&gt;
&lt;p&gt;The web interface for chat.sr.ht (at &lt;a href=&#34;https://chat.sr.ht&#34;&gt;https://chat.sr.ht&lt;/a&gt;) is, again,
based on gamja (&amp;ldquo;potato&amp;rdquo;) (discussed above) and gamja is a nice
interface indeed.&lt;/p&gt;



&lt;figure&gt;
    &lt;a href=&#34;https://babbagefiles.xyz/ox-hugo/gamja-sr.ht.png&#34;&gt;
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/gamja-sr.ht.png&#34; alt=&#34;Figure 7: in the gamja web-client at chat.sr.ht visiting #sr.ht@libera.chat&#34;/&gt; &lt;/a&gt;&lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 7: &lt;/span&gt;in the gamja web-client at chat.sr.ht visiting #sr.ht@libera.chat
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;And, for making your initial connections to different IRC servers, it
may be easier just to use this web interface, especially if you&amp;rsquo;ve
already got accounts set up on any of the servers, as for most of them
you&amp;rsquo;ll be able to enter your username and password and so on in the
&amp;ldquo;Add server&amp;rdquo; interface and not have to do all of the &lt;code&gt;/msg NickServ ....&lt;/code&gt; stuff one usually does. (If you don&amp;rsquo;t have an account already,
you&amp;rsquo;ll have to register in someway, maybe by messaging Nick).&lt;/p&gt;
&lt;p&gt;Looks like this:&lt;/p&gt;



&lt;figure&gt;
    &lt;a href=&#34;https://babbagefiles.xyz/ox-hugo/gamja-add-network.png&#34;&gt;
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/gamja-add-network.png&#34; alt=&#34;Figure 8: in the gamja web-client at chat.sr.ht in the server-add menu&#34;/&gt; &lt;/a&gt;&lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 8: &lt;/span&gt;in the gamja web-client at chat.sr.ht in the server-add menu
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;In fact, even for signing in/up on a brand new server, at least on some
servers, gamja lets you click on &amp;ldquo;login&amp;rdquo; or &amp;ldquo;register&amp;rdquo; and pulls up a
pop-up box to fill in password, email, &amp;amp;c. So it&amp;rsquo;s quite convenient
(and you may not have to message Nick manually).&lt;/p&gt;
&lt;h2 id=&#34;wrap-up-and-evaluation&#34;&gt;Wrap-up &amp;amp; evaluation&lt;/h2&gt;
&lt;p&gt;There are interesting IRC things still going on, both in terms of
active IRC communities (though this varies; #emacs is quite active,
#dwarffortress isn&amp;rsquo;t; Discord has eaten into some spaces), and
innovations in IRC technologies and tools.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not sure what the best thing is terms of choice of a soju/gajma
ecosystem. chat.sr.ht seems to be the cheapest hosted option; IRC
Today is more expensive but may currently be more
featureful. SourceHut has had trouble with being DDOS&amp;rsquo;ed/going
off-line (see, e.g., &lt;a href=&#34;https://sourcehut.org/blog/2024-01-19-outage-post-mortem/&#34;&gt;SourceHut network outage
post-mortem&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Self-hosted set-ups are another option, but are likely to be more
fiddly/effort to run/maintain than a &amp;ldquo;professional&amp;rdquo; service. But here
are a few links to descriptions of people&amp;rsquo;s self-hosted soju setups:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;self-hosting on &lt;a href=&#34;#d41d8c&#34;&gt;Alpine Linux&lt;/a&gt;: &lt;a href=&#34;https://wiredspace.de/blog/self-hosting-soju/&#34;&gt;Self-Hosting Soju&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;self-hosting on &lt;a href=&#34;#d41d8c&#34;&gt;OpenBSD&lt;/a&gt;: &lt;a href=&#34;https://whynothugo.nl/journal/2024/01/12/setting-up-an-irc-bouncer-soju-on-openbsd/&#34;&gt;Setting up an IRC bouncer (soju) on OpenBSD · Hugo&amp;rsquo;s weblog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;more self-hosting on &lt;a href=&#34;#d41d8c&#34;&gt;Alpine Linux&lt;/a&gt;: &lt;a href=&#34;https://isaacganoung.com/posts/2024/03/setting-up-self-hosted-soju/&#34;&gt;Self-Hosted IRC with Soju &amp;amp; Senpai | Isaac Ganoung&amp;rsquo;s Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;self-hosting on &lt;a href=&#34;#d41d8c&#34;&gt;IRCNow&lt;/a&gt;: &lt;a href=&#34;https://wiki.ircnow.org/pmwiki.php?n=Soju.Guide&#34;&gt;IRCNow | Soju / Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Currently, chat.sr.ht is working well for me, even if it may be behind
on some mainline soju features.&lt;/p&gt;
&lt;h2 id=&#34;appendix-etymologies&#34;&gt;Appendix: etymologies&lt;/h2&gt;
&lt;p&gt;You probably don&amp;rsquo;t need to know any of this. It&amp;rsquo;s not going to help
you log into Goguma or make your Emacs config work.&lt;/p&gt;
&lt;p&gt;But the naming of a lot of the IRC things above is strange and I&amp;rsquo;m a
linguist by trade and it&amp;rsquo;s hard for me to avoid paying a lot of
attention to words and meanings of words and connections of words.&lt;/p&gt;
&lt;p&gt;(While on the topic of mostly irrelevant things: I have some
other-language interference (Hindi here) with the Korean names of some
of the software discussed here. Specifically, &lt;em&gt;gamja&lt;/em&gt; makes me think
either गंजा &lt;em&gt;ganjā&lt;/em&gt; &amp;ldquo;bald&amp;rdquo; or गाँजा &lt;em&gt;gā̃jā&lt;/em&gt; &amp;ldquo;ganja, cannabis&amp;rdquo;; and &lt;em&gt;soju&lt;/em&gt; keeps
making me think of an elided version of सो जाऊं &lt;em&gt;so jāū̃&lt;/em&gt; &amp;ldquo;shall I go to
sleep?&amp;rdquo; [&amp;ldquo;नहीं! आप आई॰आर॰सी॰ बाउंसर हैं, आपको सो नहीं जाना चाहिए! No!
You&amp;rsquo;re an IRC bouncer: you should not go to sleep!&amp;quot;])&lt;/p&gt;
&lt;p&gt;At any rate, here are, unasked for, etymological notes on the four IRCv3
things with Korean or Japanese names, largely sourced from Wiktionary,
as indicated, with some connecting text:&lt;/p&gt;
&lt;h3 id=&#34;goguma&#34;&gt;Goguma&lt;/h3&gt;
&lt;p&gt;[mainly sourced from:
&lt;a href=&#34;https://en.wiktionary.org/wiki/%EA%B3%A0%EA%B5%AC%EB%A7%88&#34;&gt;https://en.wiktionary.org/wiki/%EA%B3%A0%EA%B5%AC%EB%A7%88&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Named apparently after Korean 고구마 &lt;em&gt;goguma&lt;/em&gt; &amp;ldquo;sweet potato&amp;rdquo; (cp. the
web client by the same team, gamja &amp;ldquo;potato&amp;rdquo;). First attested in the
&lt;em&gt;Mulmyeonggo&lt;/em&gt; (물명고 / 物名考), 1824, as Early Modern Korean &lt;em&gt;고금아&lt;/em&gt;
(Yale: &lt;em&gt;kokuma&lt;/em&gt;), borrowed from Japanese &lt;em&gt;孝行芋&lt;/em&gt; (&lt;em&gt;kōkō imo&lt;/em&gt;), a term used
in the Tsushima dialect. Some earlier attestations are known, but they
are in the context of quoting the dialectal Japanese word, not in a
Korean context.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also apparently a recent &amp;ldquo;Internet slang&amp;rdquo; sense: &amp;ldquo;a plot
development which frustrates the reader (e.g. the protagonist fails to
achieve their goal)&amp;rdquo; [from c. 2012].&lt;/p&gt;
&lt;p&gt;The Japanese word &lt;em&gt;孝行芋&lt;/em&gt; (&lt;em&gt;kōkō imo&lt;/em&gt;) from which Korean 고구마 &lt;em&gt;goguma&lt;/em&gt; is
borrowed is apparently 孝行 (&lt;em&gt;kōkō&lt;/em&gt;) [? &amp;ldquo;dutiful&amp;rdquo;??] + 芋 (&lt;em&gt;imo&lt;/em&gt;) from Old
Japanese, attested in the Nihon Shoki of 720, referring to &amp;ldquo;edible
tubers&amp;rdquo;. May be a shift from older form うも (&lt;em&gt;umo&lt;/em&gt;), ultimately from
Proto-Japonic *umo. Cognate with Okinawan 芋 (&lt;em&gt;&amp;lsquo;nmu&lt;/em&gt;). [see:
&lt;a href=&#34;https://en.wiktionary.org/wiki/%E5%AD%9D%E8%A1%8C%E8%8A%8B#Japanese&#34;&gt;https://en.wiktionary.org/wiki/%E5%AD%9D%E8%A1%8C%E8%8A%8B#Japanese&lt;/a&gt;
&lt;a href=&#34;https://en.wiktionary.org/wiki/%E8%8A%8B#Japanese&#34;&gt;https://en.wiktionary.org/wiki/%E8%8A%8B#Japanese&lt;/a&gt; ]&lt;/p&gt;
&lt;p&gt;The Japanese word 芋 (&lt;em&gt;imo&lt;/em&gt;) is connected to Chinese 芋 [Old &lt;em&gt;*ɢʷas&lt;/em&gt;,
Modern Mandarin &lt;em&gt;yù&lt;/em&gt; ] &amp;ldquo;taro&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Seemingly a phono-semantic compound (形聲 / 形声, OC *ɢʷa, *ɢʷas):
semantic 艸 (“grass; plant”) + phonetic 于 (OC *ɢʷa) – &amp;ldquo;taro&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Compare Proto-Hmong-Mien &lt;em&gt;*wouH&lt;/em&gt; (“taro”), Burmese &lt;em&gt;ဝ&lt;/em&gt; (&lt;em&gt;wa.&lt;/em&gt;, “elephant
foot yam”), Tibetan གྲོ་མ (&lt;em&gt;gro ma&lt;/em&gt;, “ &lt;em&gt;Argentina anserina&lt;/em&gt; (syn. &lt;em&gt;Potentilla
anserina&lt;/em&gt;), a plant with small edible tubers”).&lt;/p&gt;
&lt;p&gt;There are various theories on how all these words are related:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Schuessler (2007) considers it to be an areal word, comparing it to
the Hmong-Mien and Burmese words. Schuessler (2015) does not
consider the Tibetan word to be cognate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Blench (2012) suggests that the Chinese word is borrowed from
Proto-Hmong-Mien and that the Burmese word may be a late loan from
Old Chinese.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;STEDT reconstructs Proto-Sino-Tibetan &lt;em&gt;*g/s-rwa&lt;/em&gt; (“taro; yam; tuber”),
whence the Tibetan word. This etymon is regarded as allofamically
related this word and 薯 (&lt;em&gt;OC *djas&lt;/em&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Gong Hwang-cherng (2002) and Baxter and Sagart (2017) also suggest
that this word is related to the Tibetan word.&lt;/p&gt;
&lt;p&gt;[on the Chinese, see: &lt;a href=&#34;https://en.wiktionary.org/wiki/%E8%8A%8B&#34;&gt;https://en.wiktionary.org/wiki/%E8%8A%8B&lt;/a&gt;]&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;gamja&#34;&gt;Gamja&lt;/h3&gt;
&lt;p&gt;[sourced from: &lt;a href=&#34;https://en.wiktionary.org/wiki/%EA%B0%90%EC%9E%90&#34;&gt;https://en.wiktionary.org/wiki/%EA%B0%90%EC%9E%90&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Seemingly named from Korean 감자 &lt;em&gt;gamja&lt;/em&gt; &amp;ldquo;potato&amp;rdquo;, which is a
nativisation of the Sino-Korean term 감저 (甘藷, &lt;em&gt;gamjeo&lt;/em&gt;, “lesser yam
(&lt;em&gt;Dioscorea esculenta&lt;/em&gt;)”). First attested 1766 in Korea, then referring
to the sweet potato (&lt;em&gt;Ipomoea batatas&lt;/em&gt;). The word came to refer to both
&amp;ldquo;potato&amp;rdquo; and &amp;ldquo;sweet potato&amp;rdquo; in the nineteenth century, and later lost
its original meaning. (So &lt;em&gt;gamja&lt;/em&gt; meant &amp;ldquo;sweet potato&amp;rdquo; first; but
partially supplanted by &lt;em&gt;goguma&lt;/em&gt;.)&lt;/p&gt;
&lt;p&gt;With 甘藷, &lt;em&gt;gamjeo&lt;/em&gt; apparently borrowed from Early Modern Korean 감져
(&lt;em&gt;kamcye&lt;/em&gt;), itself from 甘藷
[&lt;a href=&#34;https://en.wiktionary.org/wiki/%E7%94%98%E8%97%B7&#34;&gt;https://en.wiktionary.org/wiki/%E7%94%98%E8%97%B7&lt;/a&gt;].&lt;/p&gt;
&lt;p&gt;[There&amp;rsquo;s also homophonous verbal form: 감자 (gamja) (&lt;em&gt;plain hortative of&lt;/em&gt; 감다)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;let&amp;rsquo;s close (our eyes)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;let&amp;rsquo;s wash&lt;/p&gt;
&lt;p&gt;which is presumably unrelated.]&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;soju&#34;&gt;Soju&lt;/h3&gt;
&lt;p&gt;[source: &lt;a href=&#34;https://en.wikipedia.org/wiki/Soju&#34;&gt;https://en.wikipedia.org/wiki/Soju&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Seemingly named for Korean &lt;em&gt;Soju&lt;/em&gt; (소주; 燒酒), which means &amp;ldquo;burned
liquor&amp;rdquo;: with the first syllable, &lt;em&gt;so&lt;/em&gt; (소; 燒; &amp;ldquo;burn&amp;rdquo;), referring to
the heat of distillation and the second syllable, &lt;em&gt;ju&lt;/em&gt; (주; 酒), meaning
&amp;ldquo;alcoholic drink&amp;rdquo;. Etymological dictionaries record that China&amp;rsquo;s
&lt;em&gt;shaozhou&lt;/em&gt; (&lt;em&gt;shāojiǔ&lt;/em&gt;, 烧酒), Japan&amp;rsquo;s &lt;em&gt;shochu&lt;/em&gt; (&lt;em&gt;shōchū&lt;/em&gt;, 焼酎), and Korea&amp;rsquo;s
&lt;em&gt;soju&lt;/em&gt; (&lt;em&gt;soju&lt;/em&gt;, 燒酒) have the same etymology. [A Wikipedian has here
added a note about unreliable sources(?).]&lt;/p&gt;
&lt;p&gt;Another name for soju is &lt;em&gt;noju&lt;/em&gt; (노주; 露酒; &amp;ldquo;dew liquor&amp;rdquo;), with its
first syllable, &lt;em&gt;no/ro&lt;/em&gt; (노/로; 露; &amp;ldquo;dew&amp;rdquo;), likening the droplets of the
collected alcohol during the distilling process to dewdrops.&lt;/p&gt;
&lt;p&gt;The origin of soju dates back to 13th-century Goryeo. The &lt;a href=&#34;https://en.wikipedia.org/wiki/Yuan_dynasty&#34;&gt;Yuan Mongols&lt;/a&gt;
[the imperial dynasty of China founded by Kublai Khan, grandson of
Genghis Khan] acquired the technique of distilling &lt;em&gt;arak&lt;/em&gt; from the
Persians during their invasions of the Levant, Anatolia, and Persia,
and in turn introduced it to the Korean Peninsula during the Mongol
invasions of Korea (1231–1259). Distilleries were set up around the
city of Gaegyeong, the then-capital (current Kaesong). In the areas
surrounding Kaesong, soju is still called &lt;em&gt;arak-ju&lt;/em&gt; (아락주). &lt;em&gt;Andong&lt;/em&gt;
soju, the direct root of modern South Korean soju varieties, started
as the home-brewed liquor developed in the city of Andong, where the
Yuan Mongols&amp;rsquo; logistics base was located during this era.&lt;/p&gt;
&lt;h3 id=&#34;senpai&#34;&gt;Senpai&lt;/h3&gt;
&lt;p&gt;[source: &lt;a href=&#34;https://en.wiktionary.org/wiki/%E5%85%88%E8%BC%A9#Japanese&#34;&gt;https://en.wiktionary.org/wiki/%E5%85%88%E8%BC%A9#Japanese&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Obviously named for Japanese 先輩 &lt;em&gt;senpai&lt;/em&gt; &amp;ldquo;senior/superior in social
standing or education or skill; an elder&amp;rdquo; (the homepage has a tagline
&amp;ldquo;Your everyday IRC student&amp;rdquo; and also &amp;ldquo;Welcome home, desune~&amp;rdquo; and also a smiling anime-ish cat-ish logo).&lt;/p&gt;
&lt;p&gt;The Japanese word was borrowed from the Middle Chinese 先輩 (&lt;em&gt;sen
pwojH&lt;/em&gt;). A doublet of ソンベ (&lt;em&gt;sonbe&lt;/em&gt;) [With Japanese &lt;em&gt;sonbe&lt;/em&gt; being itself
borrowed from Korean 선배(先輩) (&lt;em&gt;seonbae&lt;/em&gt;), which means &amp;ldquo;(chiefly in
Korean media) &lt;em&gt;sunbae&lt;/em&gt; (upperclassman or senior, in the context of
Korea)&amp;quot;].&lt;/p&gt;
&lt;p&gt;Both ultimately from Chinese 先輩 [ &lt;em&gt;xiānbèi&lt;/em&gt; ] &amp;ldquo;older generation;
senior; elder; ancestor; predecessor&amp;rdquo;.&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;See: &lt;a href=&#34;https://weechat.org/about/interfaces/&#34;&gt;https://weechat.org/about/interfaces/&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;See &lt;a href=&#34;https://wiki.ircnow.org/index.php?n=FreeIRC.About&#34;&gt;https://wiki.ircnow.org/index.php?n=FreeIRC.About&lt;/a&gt;;
freeirc.org is part of the &lt;a href=&#34;https://ircnow.org&#34;&gt;IRCNow network&lt;/a&gt;:— a group/community with a
lot of useful free and paid services of various sorts, including shell
accounts and VPSes and such, and a lot of freely accessible
Unix/OpenBSD &lt;a href=&#34;https://wiki.ircnow.org/index.php?n=Adminforces.Training&#34;&gt;server admin tutorials&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also thought about the &lt;a href=&#34;http://sdf.org&#34;&gt;SDF Public Access Unix System[sdf.org]​&lt;/a&gt;, which
has shell accounts and an IRC bouncer, but didn&amp;rsquo;t end up trying their
bouncer. &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;Alongside of &lt;a href=&#34;https://en.wikipedia.org/wiki/ERC_(software)&#34;&gt;ERC&lt;/a&gt; and &lt;a href=&#34;https://github.com/emacs-circe/circe&#34;&gt;Circe&lt;/a&gt;, another popular Emacs
IRC client is &lt;a href=&#34;https://en.wikipedia.org/wiki/Rcirc&#34;&gt;rcirc&lt;/a&gt;. But the Emacswiki &lt;a href=&#34;https://www.emacswiki.org/emacs?action=browse;oldid=IRC;id=InternetRelayChat&#34;&gt;lists at least nine different
Emacs IRC clients&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;Goguma exists in an official version for Android
on F-Droid [on the &lt;a href=&#34;https://f-droid.org/packages/fr.emersion.goguma/&#34;&gt;official F-Droid respository&lt;/a&gt;; and a &amp;lsquo;nightly&amp;rsquo;
version on &lt;a href=&#34;https://fdroid.emersion.fr/#goguma-nightly&#34;&gt;Goguma&amp;rsquo;s own F-Droid repository&lt;/a&gt;]; with unofficial/community
versions on &lt;a href=&#34;https://play.google.com/store/apps/details?id=fr.emersion.goguma.play&#34;&gt;Google Play for Android&lt;/a&gt; and on the &lt;a href=&#34;https://apps.apple.com/us/app/goguma-irc/id6470394620&#34;&gt;App Store for iOS&lt;/a&gt;. At
the moment I&amp;rsquo;d recommend the official F-Droid version; I had some
issues with missing messages on the &amp;lsquo;nightly&amp;rsquo; version. &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;I&amp;rsquo;m not entirely sure why Goguma is named after the
Korean word for &amp;ldquo;sweet potato&amp;rdquo;. Though &lt;a href=&#34;https://en.wiktionary.org/wiki/%EA%B3%A0%EA%B5%AC%EB%A7%88&#34;&gt;Wiktionary does report&lt;/a&gt; there&amp;rsquo;s
also apparently a recent &amp;ldquo;Internet slang&amp;rdquo; sense of the word: &amp;ldquo;a plot
development which frustrates the reader (e.g. the protagonist fails to
achieve their goal)&amp;rdquo; [from c. 2012]; that may be a red herring.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s obviously connected to one of Ser&amp;rsquo;s other IRC applications,
gamja, and maybe it&amp;rsquo;s just wanting to name things after Korean words
for root vegetables for some reason. I would have said it was a play
on Go, but Goguma isn&amp;rsquo;t written in Go.&lt;/p&gt;
&lt;p&gt;Though soju (which is written in Go), while also a Korean word,
doesn&amp;rsquo;t fit quite the root vegetable pattern. (Nor does &lt;em&gt;senpai&lt;/em&gt;, but
that&amp;rsquo;s by different authors [though Korean 先輩 (in hangeul 선배)
&lt;em&gt;seonbae&lt;/em&gt; &amp;ldquo;upperclassman, senior&amp;rdquo; exists too, and is cognate with
&lt;em&gt;senpai&lt;/em&gt;, both ultimately borrowed from Middle Chinese 先輩(&lt;em&gt;sen pwojH&lt;/em&gt;)
&amp;ldquo;elder, senior, ancestor&amp;rdquo;]. Well, see more of this &lt;a href=&#34;https://babbagefiles.xyz/no-one-can-be-told-what-irc-is-you-have-to-logon-for-yourself/#appendix-etymologies&#34;&gt;in the appendix&lt;/a&gt;, if
it&amp;rsquo;s your sort of thing. &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;I think this is what is referred to in the &lt;a href=&#34;https://sourcehut.org/blog/2024-06-04-status-and-plans/&#34;&gt;June 2024
SourceHut blog post&lt;/a&gt;, &amp;ldquo;&amp;hellip;You may have heard that we also had to part
ways with one of our staff members recently. This reduces our
headcount to two. For the time being we will not be hiring a
replacement, but our near-future plans are achievable with our current
headcount. Though we usually aim for transparency to the maximum
extent possible, we will not be sharing further details about this
departure, as a matter of reasonable privacy.&amp;rdquo; &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 &lt;a href=&#34;https://sourcehut.org/blog/2024-06-04-status-and-plans&#34;&gt;2024-06-04 blog report &amp;ldquo;The state of SourceHut and our
plans for the future&amp;rdquo;&lt;/a&gt;, where DeVault says &amp;ldquo;Also, as a happy
side-effect of our surprise move to Amsterdam, SourceHut’s datacenter
installation is now entirely powered by renewable energy sources. We
have also finally rolled out IPv6 support for most SourceHut services
as part of our migration!&amp;rdquo; &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;In the &amp;ldquo;Who is behind IRC Today&amp;rdquo; &lt;a href=&#34;https://web.archive.org/web/20250114235137/https://irctoday.com/faq&#34;&gt;FAQ&lt;/a&gt;, they say &amp;ldquo;We have
co-developed the open source piece of software used in our service,
soju.&amp;rdquo; I suspect this &amp;ldquo;we&amp;rdquo; includes at least, &lt;a href=&#34;https://github.com/delthas&#34;&gt;delthas&lt;/a&gt; (the current
developer of senpai mentioned above, who also has a number of commits
to the soju repo, and who is in France), and Thomas Flament.&lt;/p&gt;
&lt;p&gt;(For whatever reason, there seem to be at least two open source
developers who are both (a) French, and with interests in (b) IRCv3
and (c) Golang and (d) Korean or Japanese foodstuffs/culture.) &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;If you&amp;rsquo;re on IRC at all, you probably want to be on
Libera (which is where the main body of &lt;a href=&#34;https://en.wikipedia.org/wiki/Freenode&#34;&gt;Freenode&lt;/a&gt; went after Freenode
was bought by the founder of &lt;a href=&#34;https://en.wikipedia.org/wiki/Private_Internet_Access&#34;&gt;Private Internet Access VPN&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/Andrew_Lee_(entrepreneur)&#34;&gt;Andrew Lee&lt;/a&gt;,
&lt;a href=&#34;https://en.wikipedia.org/wiki/Pretender&#34;&gt;pretender&lt;/a&gt; to the defunct throne of &lt;a href=&#34;https://en.wikipedia.org/wiki/Joseon&#34;&gt;Joseon&lt;/a&gt; and the &lt;a href=&#34;https://en.wikipedia.org/wiki/Korean_Empire&#34;&gt;Korean Empire&lt;/a&gt;; Korea
seems tied up in strange ways to IRC), and lots of free software
projects which aren&amp;rsquo;t on Libera are on OFTC [=Open and Free Technology
Community] (e.g., &lt;a href=&#34;https://irclogs.alpinelinux.org/&#34;&gt;Alpine Linux&lt;/a&gt;). &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;With Elpaca I use the following:&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;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;imgbb&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;:host&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;github&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:repo&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;ecraven/imgbb.el&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;With Emacs 30+&#39;s vc-package you should be able to do something like:&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;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;imgbb&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:vc&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;imgbb&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:url&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;https://github.com/ecraven/imgbb.el&amp;#34;&lt;/span&gt;
                    &lt;span class=&#34;nb&#34;&gt;:branch&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&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;We might try to make something a bit better/more integrated, but it
works well enough for now. &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;/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/emacs">emacs</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/irc">irc</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/no-one-can-be-told-what-irc-is-you-have-to-logon-for-yourself/</guid>
                <pubDate>Fri, 28 Mar 2025 13:15:00 -0500</pubDate>
            </item>
        
            
            <item>
                <title>C-c-c-conjecturing, and dealing with recursion in Emacs (more excursus)</title>
                <link>https://babbagefiles.xyz/c-conjecturing-and-practical-considerations-of-recursion-in-emacs/</link>
                
                
                <description>&lt;p&gt;I&amp;rsquo;m not putting this in the &lt;a href=&#34;https://babbagefiles.xyz/categories/lambdacalculus/&#34;&gt;lambda-calculus&lt;/a&gt; series, though it touches
on issues from the &lt;a href=&#34;https://babbagefiles.xyz/lambda-calculus-and-lisp-02-recursion/&#34;&gt;last post&lt;/a&gt; in the series, but specifically issues of
recursion. I was curious to go back and recall how &lt;em&gt;&lt;a href=&#34;https://web.archive.org/web/20150426092105/http://www.ccs.neu.edu/home/matthias/BTLS/&#34;&gt;The Little Schemer&lt;/a&gt;&lt;/em&gt;
dealt with problems of recursion (and the Y Combinator (which we still
haven&amp;rsquo;t got properly to yet, but we will, I promise)).&lt;/p&gt;
&lt;p&gt;In Chapter 9 of &lt;em&gt;The Little Schemer&lt;/em&gt; (&amp;ldquo;and Again, and Again, and
Again,&amp;hellip;&amp;quot;), it starts off by querying the reader if they want caviar
and how to find it in a list, and then essentially gets (from caviar
and grits) into issues around the halting problem.&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/bibby-again-again-again-little-schemer-ch9.png&#34; alt=&#34;Figure 1: Duane Bibby illustration heading Chapter 9 of &amp;ldquo;The Little Schemer&amp;rdquo;&#34;/&gt; &lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 1: &lt;/span&gt;&lt;a href=&#34;https://wiki.c2.com/?DuaneBibby&#34;&gt;Duane Bibby&lt;/a&gt; illustration heading Chapter 9 of &amp;ldquo;The Little Schemer&amp;rdquo;
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;But a number of pages into this chapter the book queries of a
particular function: &amp;ldquo;Is this function total?&amp;rdquo;  and presents the
following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;define &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;k&#34;&gt;lambda &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#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;nf&#34;&gt;cond&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;one?&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;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;nf&#34;&gt;else&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cond&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;even? &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;nf&#34;&gt;C&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;n&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;C&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;add1&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;3&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;/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 function puzzle from &#34;The Little Schemer&#34; (p.155)
&lt;/div&gt;
&lt;p&gt;I didn&amp;rsquo;t know what &lt;em&gt;C&lt;/em&gt; was (a number of readers probably have recognised
it already, but please don&amp;rsquo;t spoil it for the others just yet).&lt;/p&gt;
&lt;p&gt;But whether we get the point of the function or not,we can implement
it in Emacs Lisp, translating from the Scheme into Emacs Lisp (defining an
equivalent of &lt;code&gt;even?&lt;/code&gt; as an Emacs Lisp &lt;code&gt;evenp&lt;/code&gt; first) 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;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;evenp&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;Returns &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`t&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; if &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; is even.&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;=&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;n&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;mi&#34;&gt;0&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;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;C&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;Function C from Little Schemer p.155.&amp;#34;&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;=&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;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;evenp&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;nv&#34;&gt;C&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;n&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;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;nv&#34;&gt;C&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;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;nv&#34;&gt;n&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;
  translation of the The Little Schemer &#39;C&#39; function into Elisp
&lt;/div&gt;
&lt;p&gt;And we can try running this on various numbers:&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;C&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;; 1&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;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; 1&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;mi&#34;&gt;108&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; 1&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;mi&#34;&gt;837799&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; 1&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;mi&#34;&gt;8400511&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; 1&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;mi&#34;&gt;63728126&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is, for all of these numbers it just outputs &lt;code&gt;1&lt;/code&gt;. Well, we can try
a couple of other values:&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;C&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;c1&#34;&gt;; cl-prin1: (error &amp;#34;Lisp nesting exceeds ‘max-lisp-eval-depth’&amp;#34;)&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;mi&#34;&gt;63728127&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; cl-prin1: (error &amp;#34;Lisp nesting exceeds ‘max-lisp-eval-depth’&amp;#34;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So &lt;code&gt;C&lt;/code&gt; fails for &lt;code&gt;0&lt;/code&gt; and numbers above &lt;code&gt;63728126&lt;/code&gt;, with a &amp;ldquo;excessive lisp
nesting&amp;rdquo;-type issue.&lt;/p&gt;
&lt;p&gt;But since the only non-error result we&amp;rsquo;re getting is &lt;code&gt;1&lt;/code&gt;, we could write
a much simpler function.&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;/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;ersatz-C&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;Returns 1 if &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; is 1;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;enter an infinite nesting loop
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;if &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; is 0 or above 63728126;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for any other integer value,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;pause briefly for sake of plausibly,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;and then return 1.&amp;#34;&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;=&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;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;nf&#34;&gt;=&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;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ersatz-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;nf&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;63728126&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;ersatz-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;no&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;progn&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;sleep-for&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.005&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;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 simpler function to return &#34;1&#34;
&lt;/div&gt;
&lt;p&gt;But obviously function &lt;code&gt;C&lt;/code&gt; is doing something more interesting. So, let&amp;rsquo;s make it
actually show us what it&amp;rsquo;s doing:&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;C-verbose&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;kp&#34;&gt;&amp;amp;optional&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;For a number &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;, return &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`1&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; if it&amp;#39;s &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`1&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;; otherwise,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;if it&amp;#39;s even, run the same function on half of &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;else, run the same function on one more than three times
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&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;count&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;nv&#34;&gt;count&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;nf&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Step %s: %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;count&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;count&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;count&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;=&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;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;evenp&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;nv&#34;&gt;C-verbose&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;n&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;nv&#34;&gt;count&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;no&#34;&gt;t&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;C-verbose&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;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;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;count&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;C-verbose&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; =&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 0: 7&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 1: 22&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 2: 11&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 3: 34&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 4: 17&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 5: 52&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 6: 26&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 7: 13&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 8: 40&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 9: 20&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 10: 10&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 11: 5&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 12: 16&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 13: 8&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 14: 4&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 15: 2&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 16: 1&amp;#34;&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;C-verbose&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; =&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 0: 9&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 1: 28&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 2: 14&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 3: 7&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 4: 22&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 5: 11&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 6: 34&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 7: 17&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 8: 52&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 9: 26&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 10: 13&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 11: 40&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 12: 20&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 13: 10&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 14: 5&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 15: 16&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 16: 8&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 17: 4&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 18: 2&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 19: 1&amp;#34;&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;
  Write `C&#39; to make it show us what it&#39;s doing; with some examples of use
&lt;/div&gt;
&lt;p&gt;Perhaps not surprisingly, we see that setting &lt;code&gt;n=9&lt;/code&gt; makes the function
take more steps to reach 1 than setting &lt;code&gt;n=7&lt;/code&gt;. But it&amp;rsquo;s not actually a
direct linear relation, because if we set &lt;code&gt;n=10&lt;/code&gt;, it&amp;rsquo;s a much shorter
path:&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;C-verbose&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; =&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 0: 10&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 1: 5&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 2: 16&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 3: 8&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 4: 4&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 5: 2&amp;#34;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; &amp;#34;Step 6: 1&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So we might still wonder about exactly what&amp;rsquo;s going on with function
&lt;code&gt;C&lt;/code&gt;, how it works, and what&amp;rsquo;s the point of it anyway.&lt;/p&gt;
&lt;h2 id=&#34;conjectures-about-simple-arithmetic-operations-and-integer-pathways&#34;&gt;Conjectures about simple arithmetic operations and integer pathways&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;The Little Schemer&lt;/em&gt; does give a clue about what &lt;code&gt;C&lt;/code&gt; is, referring to the
question of whether it&amp;rsquo;s a total function or not:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It doesn&amp;rsquo;t yield a value for 0, but otherwise nobody knows. Thank you,
Lothar Collatz (1910–1990).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A bit of research and we can find quite a bit about &lt;code&gt;C&lt;/code&gt;: it turns out to
be the &lt;strong&gt;Collatz conjecture&lt;/strong&gt;: one of the most famous unsolved problems in
mathematics.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://en.wikipedia.org/wiki/Collatz_conjecture&#34;&gt;Wikipedia page on the Collatz conjecture&lt;/a&gt; is useful here in laying
out basics. As well, &lt;a href=&#34;http://www.ericr.nl&#34;&gt;Eric Roosendaal&lt;/a&gt;&amp;lsquo;s &lt;a href=&#34;http://www.ericr.nl/wondrous/index.html&#34;&gt;&amp;ldquo;On the 3x + 1 problem&amp;rdquo;&lt;/a&gt;. And
Quantamagazine&amp;rsquo;s &lt;a href=&#34;https://www.quantamagazine.org/why-mathematicians-still-cant-solve-the-collatz-conjecture-20200922/&#34;&gt;&amp;ldquo;The Simple Math Problem We Still Can’t Solve&amp;rdquo;&lt;/a&gt;
presents a fairly accessible overview, including recent developments.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s some very interesting visualisations of the Collatz Functions
paths as a Collatz tree, which is a rather aesthetically-appealling
visual object. Here&amp;rsquo;s Algoritmarte&amp;rsquo;s 3D live render, based on a
discussion from the &lt;a href=&#34;https://www.youtube.com/@numberphile&#34;&gt;Numberphile channel&lt;/a&gt; (for Numberphile&amp;rsquo;s original video, done by hand, see the fn):&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;&lt;/p&gt;
&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube-nocookie.com/embed/4Z1MqCvMskI?si=tWIPRsVnYOwt2AuB&#34; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; allowfullscreen&gt;&lt;/iframe&gt;
&lt;center/&gt;&lt;a href=&#34;https://www.algoritmarte.com/the-collatz-tree/&#34;&lt;/&gt;Algoritmarte&#39;s Collatz Tree visualisation&lt;/a&gt;&lt;/center&gt;&lt;br/&gt;
&lt;p&gt;But Collatz conjecture is an unsolved problem that looks like it
should certainly be solvable. It seems quite trivial in some sense:
inductive logic would seem to suggest that the same basic patterns
would repeat, even if there are more of them, or they are longer,
given that every number that&amp;rsquo;s been tested has converged to 1 (or,
more precisely, fallen into the &amp;ldquo;4-2-1&amp;rdquo; loop) and so this tempts
people in trying to solve it. But Paul Erdős said of it &amp;ldquo;Mathematics
may not be ready for such problems&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;&lt;/p&gt;



&lt;figure&gt;
    
        
            &lt;img src=&#34;https://imgs.xkcd.com/comics/collatz_conjecture.png&#34; alt=&#34;Figure 2: https://xkcd.com/710/ [see: https://www.explainxkcd.com/wiki/index.php/710:_Collatz_Conjecture ]&#34;/&gt; &lt;figcaption&gt;
                
                &lt;p&gt;
                    &lt;span class=&#34;figure-number&#34;&gt;Figure 2: &lt;/span&gt;&lt;a href=&#34;https://xkcd.com/710/&#34;&gt;https://xkcd.com/710/&lt;/a&gt; [see: &lt;a href=&#34;https://www.explainxkcd.com/wiki/index.php/710:_Collatz_Conjecture&#34;&gt;https://www.explainxkcd.com/wiki/index.php/710:_Collatz_Conjecture&lt;/a&gt; ]
                    
                        
                        &lt;/p&gt;
                
            &lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Well, we&amp;rsquo;ll not try to solve it, but rather use it for thinking about
issues of recursion and long calculations in Emacs Lisp, and doing
some practical engineering-type testing of different methods of
dealing with such functions.&lt;/p&gt;
&lt;p&gt;One thing we might note, as a sort of aside, is that &lt;em&gt;The Little
Schemer&lt;/em&gt;&amp;lsquo;s &lt;code&gt;C&lt;/code&gt; isn&amp;rsquo;t properly the Collatz function. The conjecture is
really about whether the process will ever reach the repeating &amp;ldquo;4-2-1&amp;rdquo;
loop, because the process of dividing even numbers by 2 and multiple
odd numbers and adding 1 to them would actually mean that once we&amp;rsquo;ve
reached 1, we need to multiple it by 3 and add 1, which means we&amp;rsquo;re
back at 4, which is even, so we&amp;rsquo;ll divide by 2 and get 2, which is
even, so we divide by 2 and get 1, which is odd, so we&amp;hellip;. And so on.&lt;/p&gt;
&lt;p&gt;We can write this &amp;ldquo;real Collatz&amp;rdquo; function:&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;real-collatz&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;For an integer &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;, if it&amp;#39;s evan, divide it by 2;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;if it&amp;#39;s odd, multiple it by 3 and add 1.&amp;#34;&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;/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;
  the real basic Collatz operations
&lt;/div&gt;
&lt;p&gt;If we now try to feed it 9, we&amp;rsquo;ll hit the lisp-nesting error, but if we turn on
&lt;code&gt;toggle-debug-on-error&lt;/code&gt;, we can inspect what&amp;rsquo;s going on, and it&amp;rsquo;s
exactly the &amp;ldquo;4-2-1&amp;rdquo; loop we predicted:&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;real-collatz&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; cl-prin1: (error &amp;#34;Lisp nesting exceeds ‘max-lisp-eval-depth’&amp;#34;)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; DEBUG:&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;....&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&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;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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&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;nb&#34;&gt;cond&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;40&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;13&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;26&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;52&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;17&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;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;cond&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;11&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;22&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;28&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;evenp&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;nv&#34;&gt;real-collatz&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;n&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;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;nv&#34;&gt;real-collatz&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;real-collatz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;9&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;nv&#34;&gt;real-collatz&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9&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;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nv&#34;&gt;elisp--eval-last-sexp&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;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;p&gt;We&amp;rsquo;ll make use of it later on though, somewhat (essentially with the
&lt;code&gt;n=1&lt;/code&gt; condition displaced.)&lt;/p&gt;
&lt;h2 id=&#34;dealing-with-long-winding-paths-through-hailstorms&#34;&gt;Dealing with long winding paths, through hailstorms&lt;/h2&gt;
&lt;p&gt;Ok, so two things. One, let&amp;rsquo;s not just print things (longer paths are
going to make his quite messy), but return a list of the steps our
function goes through and a count of them. We do still want to be able
to inspect the path patterns. (Wikipedia notes on this &amp;ldquo;[t]he sequence
of numbers involved [in the paths] is sometimes referred to as the
hailstone sequence, hailstone numbers or hailstone numerals (because
the values are usually subject to multiple descents and ascents like
hailstones in a cloud)&amp;quot;.)&lt;/p&gt;
&lt;p&gt;And, two, let&amp;rsquo;s use the &lt;code&gt;cl-labels&lt;/code&gt; trick from last time to get
tail-call optimisation in Emacs.&lt;/p&gt;
&lt;p&gt;(And a minor thing: not bother with a separate &lt;code&gt;evenp&lt;/code&gt; function; just
use the calculation directly.)&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;collatz-cllabels-tco&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;Calculates the &amp;#39;Collatz path&amp;#39; for &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;return a list of all of the steps cons&amp;#39;ed
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;with count of the steps in the path.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[Uses &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`cl-labels&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; to get tail-call optimisation.]&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;collatz*&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;r&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;r&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;n&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;r&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;=&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;r&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;n&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;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;nv&#34;&gt;collatz*&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;n&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;nv&#34;&gt;r&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;no&#34;&gt;t&lt;/span&gt;
                        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;collatz*&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;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;nv&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;r&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;clst&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;collatz*&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;n&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;nv&#34;&gt;clngth&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;clst&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nreverse&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;clst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;clngth&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 6:&lt;/span&gt;
  A tail-call optimising implementation of a recursive Collatz function
&lt;/div&gt;
&lt;p&gt;Here you will note that we&amp;rsquo;ve got our &lt;code&gt;collatz*&lt;/code&gt; function (defined in
&lt;code&gt;cl-labels&lt;/code&gt;) being self-recursive only properly in tail positions, so it
can be tail-call optimised. We start by calling &lt;code&gt;collatz*&lt;/code&gt; with
arguments &lt;code&gt;n&lt;/code&gt; (whatever value we passed for &lt;code&gt;n&lt;/code&gt;) and &lt;code&gt;nil&lt;/code&gt;, with &lt;code&gt;collatz*&lt;/code&gt;
taking two arguments, &lt;code&gt;n&lt;/code&gt; and &lt;code&gt;r&lt;/code&gt; and setting &lt;code&gt;r&lt;/code&gt; to the &lt;code&gt;cons&lt;/code&gt; of &lt;code&gt;n&lt;/code&gt; with &lt;code&gt;r&lt;/code&gt;
(we&amp;rsquo;ll pass this value on, collecting the steps), and then
implementing the rest of the Collatz function in the same way as
previously, except passing along the &lt;code&gt;r&lt;/code&gt; value as our collector. At the
end, we&amp;rsquo;ll count the steps and &lt;code&gt;cons&lt;/code&gt; the list of the steps themselves,
using &lt;code&gt;nreverse&lt;/code&gt; to flip the list over (because it&amp;rsquo;ll have the last
results on the &amp;ldquo;outer&amp;rdquo; left and the first results on the &amp;ldquo;inner&amp;rdquo;
right), with the step count.&lt;/p&gt;
&lt;p&gt;Some examples:&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;collatz-cllabels-tco&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; ((9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1) . 20)&lt;/span&gt;
                &lt;span class=&#34;c1&#34;&gt;; path from 9 to 1; 20 steps&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;collatz-cllabels-tco&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; ((21 64 32 16 8 4 2 1) . 8)&lt;/span&gt;
                 &lt;span class=&#34;c1&#34;&gt;; path from 21 to 1; 8 steps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Excellent, but what about &amp;ldquo;63728127&amp;rdquo;?:— the number that tripped us up
before:&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;nv&#34;&gt;collatz-cllabels-tco&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;63728127&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; it works!&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; ...but the result is quite long, you can try it yourself;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; use setq to be able to see all of it, e.g.,&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; (setq c-result (collatz-cllabels-tco 63728127)).&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; for, let&amp;#39;s just see how many steps it is:&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;collatz-return-steps&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;Output just the number of steps that
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; takes to reach 1.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;%s takes %s steps to reach 1&amp;#34;&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;nf&#34;&gt;cdr&lt;/span&gt;
           &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;collatz-cllabels-tco&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;nv&#34;&gt;collatz-return-steps&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;63728127&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; =&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;&amp;#34;63728127 takes 949 steps to reach 1&amp;#34;&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;
  simple counting of Collatz steps on the path
&lt;/div&gt;
&lt;p&gt;&amp;ldquo;Let&amp;rsquo;s try it with a bigger number!&amp;quot;, you say. Well, we can try it on
&lt;code&gt;most-positive-fixnum&lt;/code&gt; (which is I think probably set to
2305843009213693951 by default) — but remember the size of the number
and the number of steps is not a direct linear relation, so you might
be disappointed:&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;collatz-return-steps&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;most-positive-fixnum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; =&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;&amp;#34;2305843009213693951 takes 860 steps to reach 1&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is less than for 63728127.&lt;/p&gt;
&lt;p&gt;Ok, so let&amp;rsquo;s make something really big then. &lt;code&gt;2^1000 + 1&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;collatz-return-steps&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; =&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;&amp;#34;10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069377 takes 7248 steps to reach 1&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It takes 7,248 steps. What about &lt;code&gt;2^10000 + 1&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;collatz-return-steps&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;; =&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;&amp;#34;19950631168807583848837421626835850838234968318861924548520089498529438830221946631919961684036194597899331129423209124271556491349413781117593785932096323957855730046793794526765246551266059895520550086918193311542508608460618104685509074866089624888090489894838009253941633257850621568309473902556912388065225096643874441046759871626985453222868538161694315775629640762836880760732228535091641476183956381458969463899410840960536267821064621427333394036525565649530603142680234969400335934316651459297773279665775606172582031407994198179607378245683762280037302885487251900834464581454650557929601414833921615734588139257095379769119277800826957735674444123062018757836325502728323789270710373802866393031428133241401624195671690574061419654342324638801248856147305207431992259611796250130992860241708340807605932320161268492288496255841312844061536738951487114256315111089745514203313820202931640957596464756010405845841566072044962867016515061920631004186422275908670900574606417856951911456055068251250406007519842261898059237118054444788072906395242548339221982707404473162376760846613033778706039803413197133493654622700563169937455508241780972810983291314403571877524768509857276937926433221599399876886660808368837838027643282775172273657572744784112294389733810861607423253291974813120197604178281965697475898164531258434135959862784130128185406283476649088690521047580882615823961985770122407044330583075869039319604603404973156583208672105913300903752823415539745394397715257455290510212310947321610753474825740775273986348298498340756937955646638621874569499279016572103701364433135817214311791398222983845847334440270964182851005072927748364550578634501100852987812389473928699540834346158807043959118985815145779177143619698728131459483783202081474982171858011389071228250905826817436220577475921417653715687725614904582904992461028630081535583308130101987675856234343538955409175623400844887526162643568648833519463720377293240094456246923254350400678027273837755376406726898636241037491410966718557050759098100246789880178271925953381282421954028302759408448955014676668389697996886241636313376393903373455801407636741877711055384225739499110186468219696581651485130494222369947714763069155468217682876200362777257723781365331611196811280792669481887201298643660768551639860534602297871557517947385246369446923087894265948217008051120322365496288169035739121368338393591756418733850510970271613915439590991598154654417336311656936031122249937969999226781732358023111862644575299135758175008199839236284615249881088960232244362173771618086357015468484058622329792853875623486556440536962622018963571028812361567512543338303270029097668650568557157505516727518899194129711337690149916181315171544007728650573189557450920330185304847113818315407324053319038462084036421763703911550639789000742853672196280903477974533320468368795868580237952218629120080742819551317948157624448298518461509704888027274721574688131594750409732115080498190455803416826949787141316063210686391511681774304792596709377 takes 72378 steps to reach 1&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;72,378 steps.&lt;/p&gt;
&lt;p&gt;Can we go one bigger?&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;collatz-return-steps&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;;; Debugger entered--Lisp error: (overflow-error)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No. But it&amp;rsquo;s because Emacs has &lt;code&gt;maximum-integer-width&lt;/code&gt; set to 65536 (so
a number can only be 65,536 digits long). We can set it to something
bigger, and it&amp;rsquo;ll work.&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;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-return-steps&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;; =&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; I&amp;#39;ll spare you the number `n&amp;#39; itself as it&amp;#39;s realy quite long,&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; but that number takes 717,858 steps to reach 1.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You&amp;rsquo;ll note, if you&amp;rsquo;ve been evaluating along in your own Emacs that
these results have been nearly instantaneous so far. This one takes a
bit longer.&lt;/p&gt;
&lt;p&gt;(I subsequently tried doing &lt;code&gt;collatz-cllabels-tco&lt;/code&gt; on &lt;code&gt;2^1000000 + 1&lt;/code&gt;, but with only
16Gb in my machine, Linux&amp;rsquo;s &lt;a href=&#34;https://docs.kernel.org/admin-guide/mm/concepts.html#id9&#34;&gt;OOM-killer&lt;/a&gt; killed Emacs before it reached
the end. I should probably try setting up some sort of swap better.)&lt;/p&gt;
&lt;h2 id=&#34;streaming-though-the-hail&#34;&gt;Streaming though the hail&lt;/h2&gt;
&lt;p&gt;We can also try the &lt;a href=&#34;https://elpa.gnu.org/packages/stream.html&#34;&gt;&lt;code&gt;stream&lt;/code&gt;&lt;/a&gt; package &lt;a href=&#34;https://babbagefiles.xyz/lambda-calculus-and-lisp-02-recursion/#stream-of-conses-ness&#34;&gt;we looked at before&lt;/a&gt;, which
creates &amp;ldquo;lazy&amp;rdquo; conses, of potentially infinite sequences, which can be
evaluated one piece at a time, as needed.&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;collatz-stream&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;For a number &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;, return &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`1&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; if it&amp;#39;s &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`1&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;; otherwise,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;if it&amp;#39;s even, run the same function on half of &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;else, run the same function on one more than three times
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(Also, collect each step into a list and, when &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; is &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`1&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;print the list.)
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[Uses the &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`stream&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; package for lazy-evaluated 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;collatz*&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;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;n&lt;/span&gt;
                             &lt;span class=&#34;c1&#34;&gt;;; note that this is the `real&amp;#39; collatz func&lt;/span&gt;
                             &lt;span class=&#34;c1&#34;&gt;;; no checking for 1 here; we do it below&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;=&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;n&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;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;nv&#34;&gt;collatz*&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;n&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;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;nv&#34;&gt;collatz*&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;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;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;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;clst&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;collatz*&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;nv&#34;&gt;last&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;nv&#34;&gt;out&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;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&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;last&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;;; stop when we reach 1&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;last&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;clst&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;out&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;last&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;out&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;steps&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;out&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;rlist&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;out&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;rlist&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;steps&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 8:&lt;/span&gt;
  Using lazy cons sequences in &#34;stream&#34; for Collatz calculations
&lt;/div&gt;
&lt;p&gt;This, however, turns out to in fact be much slower than our &lt;code&gt;cl-labels&lt;/code&gt;
tco recursion.&lt;/p&gt;
&lt;p&gt;In fact, we can quantify this a bit further using &lt;a href=&#34;https://github.com/alphapapa/&#34;&gt;Adam Porter&lt;/a&gt;&amp;lsquo;s
&lt;a href=&#34;https://github.com/alphapapa/emacs-package-dev-handbook?tab=readme-ov-file#benchmarking&#34;&gt;&lt;code&gt;bench-multi&lt;/code&gt; macro&lt;/a&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;bench-multi&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:times&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:forms&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-stream&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-stream&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cllabels-tco&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cllabels-tco&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;/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;
  bench-marking cl-labels vs stream collatz functions
&lt;/div&gt;
&lt;p&gt;Here the forms are ranked in order by fastest first; the second column
says how much slower the form is compared against the fastest; then
there are total runtime (for all iterations; we did here 5 for each);
and total &lt;a href=&#34;https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)&#34;&gt;garbage collections&lt;/a&gt; performed by Emacs during those tests;
and the total amount of time the garbage collection tasks themselves took.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;x fastest&lt;/th&gt;
&lt;th&gt;Total runtime&lt;/th&gt;
&lt;th&gt;# of GCs&lt;/th&gt;
&lt;th&gt;Total GC runtime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cllabels-tco&lt;/td&gt;
&lt;td&gt;fastest&lt;/td&gt;
&lt;td&gt;1.310546&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.484381&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-stream&lt;/td&gt;
&lt;td&gt;12.72&lt;/td&gt;
&lt;td&gt;16.665472&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;11.808777&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;I&amp;rsquo;m not quite sure why &lt;code&gt;collatz-stream&lt;/code&gt; is this much slower than
&lt;code&gt;collatz-cllabels-tco&lt;/code&gt; is the case. My guess is that because of the delayed/lazy
evaluation, we aren&amp;rsquo;t able to get real reduction of &lt;a href=&#34;https://en.wikipedia.org/wiki/Call_stack#STACK-FRAME&#34;&gt;stack frames&lt;/a&gt;
because we&amp;rsquo;re only evaluating one piece/instance of the Collatz
function on each &lt;code&gt;stream-pop&lt;/code&gt;, and there&amp;rsquo;s no advantage to using &lt;code&gt;cl-labels&lt;/code&gt;
here really.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;stream&lt;/code&gt; method certainly triggers more garbage collection, which is
part of it, though I&amp;rsquo;m not entirely sure why it should involve
triggering more garbage collection. (I suppose we could play with
garbage collection settings in emacs and see if we can deal garbage
collection and make the &lt;code&gt;stream&lt;/code&gt; method better.)&lt;/p&gt;
&lt;h2 id=&#34;caught-in-loops-still&#34;&gt;Caught in loops still?&lt;/h2&gt;
&lt;p&gt;But what about a plain looping method for the Collatz function. We
generally saw with the Fibonacci series that &lt;a href=&#34;https://babbagefiles.xyz/lambda-calculus-and-lisp-02-recursion/#back-to-loops&#34;&gt;loops seemed more
efficient&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We can try with both plain &lt;code&gt;while&lt;/code&gt; loops and also &lt;code&gt;cl-loops&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;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;collatz-while-loop&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;Collatz function using emacs &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`while&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; 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;m&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;nv&#34;&gt;clst&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;list&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;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&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;m&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;m&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;=&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;m&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;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;nf&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;m&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;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;nf&#34;&gt;1+&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;nv&#34;&gt;m&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;clst&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;m&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;clst&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;steps&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;clst&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;rlist&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;clst&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;rlist&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;steps&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;collatz-cl-loop&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;Collatz function using &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`cl-loop&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; with
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`while&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; clause condition.&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;m&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;nv&#34;&gt;clst&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;list&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;cl-loop&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;nv&#34;&gt;not&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;m&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;nb&#34;&gt;do&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;progn&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;m&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;=&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;m&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;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;nf&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;m&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;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;nf&#34;&gt;1+&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;nv&#34;&gt;m&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;clst&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;m&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;clst&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;steps&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;clst&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;rlist&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;clst&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;rlist&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;steps&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 10:&lt;/span&gt;
  looping methods for the Collatz function
&lt;/div&gt;
&lt;p&gt;And now comparing all of the methods:&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;bench-multi&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:times&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:forms&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-stream&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-stream&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cllabels-tco&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cllabels-tco&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-while-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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-while-loop&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cl-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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cl-loop&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;/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 11:&lt;/span&gt;
  bench-marking our Collatz function implementations
&lt;/div&gt;
&lt;p&gt;We find the following results:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;x fastest&lt;/th&gt;
&lt;th&gt;Total runtime&lt;/th&gt;
&lt;th&gt;# of GCs&lt;/th&gt;
&lt;th&gt;Total GC runtime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;collatz-while-loop&lt;/td&gt;
&lt;td&gt;fastest&lt;/td&gt;
&lt;td&gt;0.876315&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.240661&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cl-loop&lt;/td&gt;
&lt;td&gt;1.02&lt;/td&gt;
&lt;td&gt;0.896261&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.235273&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cllabels-tco&lt;/td&gt;
&lt;td&gt;1.43&lt;/td&gt;
&lt;td&gt;1.255294&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.449736&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-stream&lt;/td&gt;
&lt;td&gt;18.77&lt;/td&gt;
&lt;td&gt;16.446478&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;11.677753&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Both types of loops turn out faster than even &lt;code&gt;collatz-cllabels-tco&lt;/code&gt;, with the
plain emacs &lt;code&gt;while loop&lt;/code&gt; method seeming slightly faster than the &lt;code&gt;cl-loop&lt;/code&gt;
method, but probably within margin of error (or maybe just a bit of
extra machine in &lt;code&gt;cl-loop&lt;/code&gt; which loses a small amount of efficiency.)&lt;/p&gt;
&lt;p&gt;For our TCO tail-recurive &lt;code&gt;cll&lt;/code&gt; maybe it&amp;rsquo;s the additional garbage collection
that slows down &lt;code&gt;collatz-cllabels-tco&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What if we just look at the two loop methods, and run more trials?&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;bench-multi&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:times&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:forms&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-while-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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-while-loop&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cl-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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cl-loop&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;/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 12:&lt;/span&gt;
  bench-marking loop methods of implementing the Collatz function
&lt;/div&gt;
&lt;p&gt;Our results are:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;x fastest&lt;/th&gt;
&lt;th&gt;Total runtime&lt;/th&gt;
&lt;th&gt;# of GCs&lt;/th&gt;
&lt;th&gt;Total GC runtime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;collatz-while-loop&lt;/td&gt;
&lt;td&gt;fastest&lt;/td&gt;
&lt;td&gt;17.584334&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;4.851656&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cl-loop&lt;/td&gt;
&lt;td&gt;1.03&lt;/td&gt;
&lt;td&gt;18.027418&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;5.070158&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Still the plain &lt;code&gt;while&lt;/code&gt; is slightly faster than &lt;code&gt;cl-loop&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;an-attempt-at-promoting-our-recursive-tco-function&#34;&gt;An attempt at promoting our recursive tco function&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;d really like to somehow improve our recursive TCO collatz function.&lt;/p&gt;
&lt;p&gt;What if we pull the collector &lt;code&gt;r&lt;/code&gt; out in a higher-scoping &lt;code&gt;let&lt;/code&gt; and so
don&amp;rsquo;t have to pass it into &lt;code&gt;collatz*&lt;/code&gt; each time; thus:&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;collatz-cllabels-tco-improved&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;Calculates the &amp;#39;Collatz path&amp;#39; for &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`n&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;return a list of all of the steps cons&amp;#39;ed
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;with count of the steps in the path.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[Uses &lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`cl-labels&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; to get tail-call optimisation.]&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;r&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;cl-labels&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;collatz*&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;r&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;n&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;r&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;=&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;r&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;n&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;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;nv&#34;&gt;collatz*&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;n&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;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;nv&#34;&gt;collatz*&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;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;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;let*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;clst&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;collatz*&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;nv&#34;&gt;clngth&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;clst&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nreverse&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;clst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;clngth&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 13:&lt;/span&gt;
  trying to eke out more performance for TCO cl-labels recursive Collatz function
&lt;/div&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;bench-multi&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:times&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:forms&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cllabels-tco&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cllabels-tco&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cllabels-tco-improved&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cllabels-tco-improved&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;/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 14:&lt;/span&gt;
  bench-marking the two cl-labels recursive Collatz functions
&lt;/div&gt;
&lt;p&gt;Here are the results:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;x fastest&lt;/th&gt;
&lt;th&gt;Total runtime&lt;/th&gt;
&lt;th&gt;# of GCs&lt;/th&gt;
&lt;th&gt;Total GC runtime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cllabels-tco-improved&lt;/td&gt;
&lt;td&gt;fastest&lt;/td&gt;
&lt;td&gt;2.198572&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0.719563&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cllabels-tco&lt;/td&gt;
&lt;td&gt;1.17&lt;/td&gt;
&lt;td&gt;2.579470&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0.923288&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;We do seem to eke out a bit more performance.&lt;/p&gt;
&lt;p&gt;But compared to the loops, it&amp;rsquo;s still not as performant:&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;bench-multi&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:times&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:forms&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cllabels-tco&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cllabels-tco&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cllabels-tco-improved&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cllabels-tco-improved&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-while-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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-while-loop&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cl-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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cl-loop&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;/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 15:&lt;/span&gt;
  benchmarking two cl-labels and two loop Collatz implementations
&lt;/div&gt;
&lt;p&gt;We seem to have done a bit better. Now &lt;code&gt;collatz-cllabels-tco-improved&lt;/code&gt; is only
1.26x slower than the fastest, &lt;code&gt;collatz-while-loop&lt;/code&gt;. We save an extra gc
over the older &lt;code&gt;collatz-cllabels-tco&lt;/code&gt;, but still have to run an additional one
compared to the two loop functions.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;x fastest&lt;/th&gt;
&lt;th&gt;Total runtime&lt;/th&gt;
&lt;th&gt;# of GCs&lt;/th&gt;
&lt;th&gt;Total GC runtime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;collatz-while-loop&lt;/td&gt;
&lt;td&gt;fastest&lt;/td&gt;
&lt;td&gt;1.754987&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.486154&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cl-loop&lt;/td&gt;
&lt;td&gt;1.01&lt;/td&gt;
&lt;td&gt;1.769489&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.486728&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cllabels-tco-improved&lt;/td&gt;
&lt;td&gt;1.26&lt;/td&gt;
&lt;td&gt;2.208662&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0.732637&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cllabels-tco&lt;/td&gt;
&lt;td&gt;1.44&lt;/td&gt;
&lt;td&gt;2.528099&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0.899793&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Putting all of the methods we&amp;rsquo;ve come up with together and running more trials:&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;bench-multi&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:times&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:forms&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-stream&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-stream&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cllabels-tco&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cllabels-tco&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cllabels-tco-improved&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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cllabels-tco-improved&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-while-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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-while-loop&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;collatz-cl-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;integer-width&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;99999999&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;collatz-cl-loop&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expt&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&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;/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 16:&lt;/span&gt;
  full benchmark of all of our Collatz implementations
&lt;/div&gt;
&lt;p&gt;Here, interestingly, we end up with &lt;code&gt;collatz-cl-loop&lt;/code&gt; slightly edging
out &lt;code&gt;collatz-while-loop&lt;/code&gt;. And our favourite (well, my favourite)
&lt;code&gt;collatz-cllabels-tco-improved&lt;/code&gt; function doesn&amp;rsquo;t do too poorly: it&amp;rsquo;s only x1.28 slower
than the fastest (&lt;code&gt;collatz-cl-loop&lt;/code&gt;); and even the old &lt;code&gt;collatz-cllabels-tco&lt;/code&gt; with
additional argument passing is only x1.53 slower&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;x fastest&lt;/th&gt;
&lt;th&gt;Total runtime&lt;/th&gt;
&lt;th&gt;# of GCs&lt;/th&gt;
&lt;th&gt;Total GC runtime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cl-loop&lt;/td&gt;
&lt;td&gt;fastest&lt;/td&gt;
&lt;td&gt;17.733980&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;4.817641&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-while-loop&lt;/td&gt;
&lt;td&gt;1.01&lt;/td&gt;
&lt;td&gt;17.850171&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;4.977408&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cllabels-tco-improved&lt;/td&gt;
&lt;td&gt;1.28&lt;/td&gt;
&lt;td&gt;22.736898&lt;/td&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;7.961263&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cllabels-tco&lt;/td&gt;
&lt;td&gt;1.53&lt;/td&gt;
&lt;td&gt;27.146827&lt;/td&gt;
&lt;td&gt;47&lt;/td&gt;
&lt;td&gt;10.735285&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-stream&lt;/td&gt;
&lt;td&gt;18.97&lt;/td&gt;
&lt;td&gt;336.443089&lt;/td&gt;
&lt;td&gt;961&lt;/td&gt;
&lt;td&gt;240.167718&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The &lt;code&gt;collatz-stream&lt;/code&gt; function remains significantly slower, x19 so.&lt;/p&gt;
&lt;p&gt;There is an obvious correlation between runtime and garbage
collection, (19 vs 20 vs 33 vs 47 vs 961), so again possibly tweaking
garbage collection could change things. Although, if we get rid of the
garbage collection runtime differences we end up with:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;Total runtime w/o GC&lt;/th&gt;
&lt;th&gt;x fastest&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;collatz-while-loop&lt;/td&gt;
&lt;td&gt;12.872762999999999&lt;/td&gt;
&lt;td&gt;fastest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cl-loop&lt;/td&gt;
&lt;td&gt;12.916338999999999&lt;/td&gt;
&lt;td&gt;1.003&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cllabels-tco-improved&lt;/td&gt;
&lt;td&gt;14.775635000000001&lt;/td&gt;
&lt;td&gt;1.148&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-cllabels-tco&lt;/td&gt;
&lt;td&gt;16.411541999999997&lt;/td&gt;
&lt;td&gt;1.275&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;collatz-stream&lt;/td&gt;
&lt;td&gt;96.27537099999998&lt;/td&gt;
&lt;td&gt;7.479&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Now &lt;code&gt;collatz-while-loop&lt;/code&gt; is again indeed actually the fastest, but still
just barely more so than &lt;code&gt;collatz-cl-loop&lt;/code&gt;; both recursive TCO&amp;rsquo;ing
&lt;code&gt;cl-labels&lt;/code&gt; aren&amp;rsquo;t actually too much slower than the loops, though the
improved version is indeed better; and &lt;code&gt;collatz-stream&lt;/code&gt; is still quite slow
in comparison. So garbage collection is part of the difference, but
not the only one, especially for the &lt;code&gt;streams&lt;/code&gt; method.&lt;/p&gt;
&lt;h2 id=&#34;escaping--at-least-some--loops-out-of-recursion-and-into-dot-dot-dot-different-recursion--next-time&#34;&gt;Escaping (at least some) loops: out of recursion and into&amp;hellip; different recursion (next time)&lt;/h2&gt;
&lt;p&gt;This was really an excursus (on an excursus). And, next time — really
— we&amp;rsquo;ll deal with the Y Combinator. I know this one really wasn&amp;rsquo;t a lambda
calculus post at all, but an excursion on our previous excursion into
recursion, here mostly practical considerations for Emacs. But
recursion is crucial for the upcoming discussion of the Y Combinator,
and paradoxes (and their uses). And that&amp;rsquo;ll be interesting for lambda
calculus, and its connections with Lisp.&lt;/p&gt;
&lt;p&gt;And, after we&amp;rsquo;re through with Y Combinators and Fibonacci sequences
and barbers who shave everyone who does&amp;rsquo;t shave themselves, and how
these things all tie together, we can get to something I&amp;rsquo;ve been
working on for a while:— given that, connections aside, Lisp isn&amp;rsquo;t
lambda calculus: can we come up with a good implementation of lambda
calculus in Lisp?&lt;/p&gt;
&lt;p&gt;(And specifically in Emacs Lisp: which is maybe one of the Lisps least
naturally suited for this: a Scheme or Clojure would be a better
choice really. But it&amp;rsquo;s more fun to try to get it to work in Elisp,
with all of the additional challenges it presents.)&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;(I&amp;rsquo;m perhaps very slightly giving the game away; or, at least
providing a clue in the naming of it if you can think of what C-words
&amp;ldquo;ersatz&amp;rdquo; rhymes with.) &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;See &lt;a href=&#34;https://www.algoritmarte.com/the-collatz-tree/&#34;&gt;The Collatz Tree | Algoritmarte&lt;/a&gt;. And the video it&amp;rsquo;s
based on
&lt;a href=&#34;https://www.youtube.com/watch?v=LqKpkdRRLZw&#34;&gt;https://www.youtube.com/watch?v=LqKpkdRRLZw&lt;/a&gt;&lt;/p&gt;
&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube-nocookie.com/embed/246l3U2zngk?si=Y5owwBoDC3ivBouI&#34; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; allowfullscreen&gt;&lt;/iframe&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;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.quantamagazine.org/why-mathematicians-still-cant-solve-the-collatz-conjecture-20200922/&#34;&gt;Quantamagazine article&lt;/a&gt; notes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do not try to solve this math problem.&lt;/p&gt;
&lt;p&gt;You will be tempted. This problem is simply stated, easily understood,
and all too inviting. Just pick a number, any number: If the number is
even, cut it in half; if it’s odd, triple it and add 1. Take that new
number and repeat the process, again and again. If you keep this up,
you’ll eventually get stuck in a loop. At least, that’s what we think
will happen.&lt;/p&gt;
&lt;p&gt;Take 10 for example: 10 is even, so we cut it in half to get 5. Since
5 is odd, we triple it and add 1. Now we have 16, which is even, so we
halve it to get 8, then halve that to get 4, then halve it again to
get 2, and once more to get 1. Since 1 is odd, we triple it and
add 1. Now we’re back at 4, and we know where this goes: 4 goes to 2
which goes to 1 which goes to 4, and so on. We’re stuck in a loop.&lt;/p&gt;
&lt;p&gt;Or try 11: It’s odd, so we triple it and add 1. Now we have 34, which
is even, so we halve it to get 17, triple that and add 1 to get 52,
halve that to get 26 and again to get 13, triple that and add 1 to get
40, halve that to get 20, then 10, then 5, triple that and add 1 to
get 16, and halve that to get 8, then 4, 2 and 1. And we’re stuck in
the loop again.&lt;/p&gt;
&lt;p&gt;The infamous Collatz conjecture says that if you start with any
positive integer, you’ll always end up in this loop. And you’ll
probably ignore my warning about trying to solve it: It just seems too
simple and too orderly to resist understanding. In fact, it would be
hard to find a mathematician who hasn’t played around with this
problem.&lt;/p&gt;
&lt;p&gt;I couldn’t ignore it when I first learned of it in school. My friends
and I spent days trading thrilling insights that never seemed to get
us any closer to an answer. But the Collatz conjecture is infamous for
a reason: Even though every number that’s ever been tried ends up in
that loop, we’re still not sure it’s always true. Despite all the
attention, it’s still just a conjecture.&lt;/p&gt;
&lt;p&gt;&amp;hellip;.&lt;/p&gt;
&lt;p&gt;It’s easy to verify that the Collatz conjecture is true for any
particular number: Just compute the orbit until you arrive at 1. But
to see why it’s hard to prove for every number, let’s explore a
slightly simpler function, &lt;code&gt;ℊ&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;g(n)=&lt;/code&gt; &lt;code&gt;{n/2n+1, if n is even&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;{n+1, if n is odd&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We might conjecture that orbits under &lt;code&gt;ℊ&lt;/code&gt; always get to 1. I’ll call this
the “Nollatz” conjecture, but we could also call it the &lt;code&gt;n + 1&lt;/code&gt;
conjecture. We could explore this by testing more orbits, but knowing
something is true for a bunch of numbers — even 268 of them — isn’t a
proof that it’s true for every number. Fortunately, the Nollatz
conjecture can actually be proved. Here’s how.&lt;/p&gt;
&lt;p&gt;First, we know that half of a positive integer is always less than the
integer itself. So if &lt;code&gt;n&lt;/code&gt; is even and positive, then &lt;code&gt;ℊ(n) = n/2 &amp;lt; n&lt;/code&gt;. In
other words, when an orbit reaches an even number, the next number
will always be smaller.
&amp;hellip;.
This tells us that when an orbit under &lt;code&gt;ℊ&lt;/code&gt; reaches an odd number greater
than 1, we’ll always be at a smaller number two steps later. And now
we can outline a proof of the Nollatz conjecture: Anywhere in our
orbit, whether at an even or an odd number, we’ll trend downward. The
only exception is when we hit 1 at the bottom of our descent. But once
we hit 1 we’re trapped the loop, just as we conjectured.
&amp;hellip;
[For &lt;code&gt;f&lt;/code&gt;, the Collatz conjencture,] as with &lt;code&gt;ℊ&lt;/code&gt;, applying &lt;code&gt;f&lt;/code&gt; to an even
number makes it smaller. And as with &lt;code&gt;ℊ&lt;/code&gt;, applying &lt;code&gt;f&lt;/code&gt; to an odd number
produces an even number, which means we know what happens next: &lt;code&gt;f&lt;/code&gt; will
cut the new number in half.&lt;/p&gt;
&lt;p&gt;But here’s where our argument falls apart. Unlike our example above,
this number is bigger than &lt;code&gt;n&lt;/code&gt;: &lt;code&gt;3n+12 = 3n2 + 12&lt;/code&gt;, and &lt;code&gt;3n2 = 1.5n&lt;/code&gt;, which
is always bigger than &lt;code&gt;n&lt;/code&gt;. The key to our proof of the Nollatz
conjecture was that an odd number must end up smaller two steps later,
but this isn’t true in the Collatz case. Our argument won’t work.&lt;/p&gt;
&lt;/blockquote&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;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                
                            
                        
                     
                        
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/tags/recursion">recursion</category>
                                
                            
                        
                    
                
                <guid>https://babbagefiles.xyz/c-conjecturing-and-practical-considerations-of-recursion-in-emacs/</guid>
                <pubDate>Mon, 24 Feb 2025 04:10:00 -0600</pubDate>
            </item>
        
            
            <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>So you need kill (or do something else to) something in Linux</title>
                <link>https://babbagefiles.xyz/you-need-to-kill-or-do-something-in-linux/</link>
                
                
                <description>&lt;h2 id=&#34;or-what-if-you-can-t-just-click-the-bad-thing-with-the-skull-until-it-dies&#34;&gt;(Or, what if you can&amp;rsquo;t just click the bad thing with the skull until it dies?)&lt;/h2&gt;
&lt;p&gt;Sometimes you need to kill something in Linux. Sometimes it makes
sense to use some sort interactive process monitor, like the process
table in Plasma&amp;rsquo;s System Monitor, or &lt;code&gt;top&lt;/code&gt; or &lt;code&gt;htop&lt;/code&gt; or &lt;code&gt;bottom&lt;/code&gt; or some
other sort of top.&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; (Or, if you&amp;rsquo;re in an X11 environment rather
than a Wayland one, you could use &lt;code&gt;xkill&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;)&lt;/p&gt;
&lt;h3 id=&#34;killing-with-killall&#34;&gt;killing with &lt;code&gt;killall&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;You can often get by with &lt;a href=&#34;https://en.wikipedia.org/wiki/Killall&#34;&gt;&lt;code&gt;killall&lt;/code&gt;&lt;/a&gt;, e.g., if you want to kill all
running Firefox applications:&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;killall firefox
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;killing-with-pkill&#34;&gt;killing with &lt;code&gt;pkill&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Or you could use &lt;a href=&#34;https://en.wikipedia.org/wiki/Pkill&#34;&gt;&lt;code&gt;pkill&lt;/code&gt;&lt;/a&gt; (which has a number of options) in much the
same way.&lt;/p&gt;
&lt;p&gt;These sorts of approaches don&amp;rsquo;t always work. Sometimes (this is true
in Guix&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; a lot) processes are named in ways that &lt;code&gt;killall&lt;/code&gt; or &lt;code&gt;pkill&lt;/code&gt; don&amp;rsquo;t
match.&lt;/p&gt;
&lt;h3 id=&#34;listing-processes-and-process-ids-with-ps&#34;&gt;listing processes and process ids with &lt;code&gt;ps&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;You can list running processes in Linux with &lt;code&gt;ps -ef&lt;/code&gt;, and this will
show you all running processes. It&amp;rsquo;s too much, obviously, there are a
lot of things going on in your system. So, you can filter it by
&amp;ldquo;piping&amp;rdquo; the output of &lt;code&gt;ps -ef&lt;/code&gt; through &lt;a href=&#34;https://en.wikipedia.org/wiki/Grep&#34;&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;, e.g., &lt;code&gt;ps -ef | grep -i emacs&lt;/code&gt;, which might show you something like:&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;emacsomancer    &lt;span class=&#34;m&#34;&gt;15188&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 21:05 ?        00:00:02 /gnu/store/5vkx1cf1d2k9dj974vgd77yx0fdis284-emacs-pdf-tools-1.1.0/bin/epdfinfo
emacsomancer    &lt;span class=&#34;m&#34;&gt;23294&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 21:33 ?        00:00:00 /home/emacsomancer/.guix-home/profile/bin/emacs --quick --batch --load /home/emacsomancer/.emacs.d/eln-cache/30.0.93-e51375a4/el-job-child-8a892b0e-c7b5e3df.eln --eval &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;el-job-child--work &lt;span class=&#34;c1&#34;&gt;#&amp;#39;org-node-parser--collect-dangerously nil)&lt;/span&gt;
emacsomancer    &lt;span class=&#34;m&#34;&gt;23550&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;2250&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 21:34 pts/4    00:00:00 grep --color&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;auto -i emacs
emacsomancer    &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;     &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt; 19:47 ?        00:05:42 /home/emacsomancer/.guix-home/profile/bin/emacs --daemon --debug-init
emacsomancer    &lt;span class=&#34;m&#34;&gt;26513&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 19:47 ?        00:00:03 /home/emacsomancer/.guix-home/profile/bin/emacs --quick --batch --load /home/emacsomancer/.emacs.d/eln-cache/30.0.93-e51375a4/el-job-child-8a892b0e-c7b5e3df.eln --eval &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;el-job-child--work &lt;span class=&#34;c1&#34;&gt;#&amp;#39;org-node-parser--collect-dangerously t)&lt;/span&gt;
emacsomancer    &lt;span class=&#34;m&#34;&gt;26514&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 19:47 ?        00:00:02 /home/emacsomancer/.guix-home/profile/bin/emacs --quick --batch --load /home/emacsomancer/.emacs.d/eln-cache/30.0.93-e51375a4/el-job-child-8a892b0e-c7b5e3df.eln --eval &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;el-job-child--work &lt;span class=&#34;c1&#34;&gt;#&amp;#39;org-node-parser--collect-dangerously t)&lt;/span&gt;
emacsomancer    &lt;span class=&#34;m&#34;&gt;26515&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 19:47 ?        00:00:02 /home/emacsomancer/.guix-home/profile/bin/emacs --quick --batch --load /home/emacsomancer/.emacs.d/eln-cache/30.0.93-e51375a4/el-job-child-8a892b0e-c7b5e3df.eln --eval &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;el-job-child--work &lt;span class=&#34;c1&#34;&gt;#&amp;#39;org-node-parser--collect-dangerously t)&lt;/span&gt;
emacsomancer    &lt;span class=&#34;m&#34;&gt;26516&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 19:47 ?        00:00:01 /home/emacsomancer/.guix-home/profile/bin/emacs --quick --batch --load /home/emacsomancer/.emacs.d/eln-cache/30.0.93-e51375a4/el-job-child-8a892b0e-c7b5e3df.eln --eval &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;el-job-child--work &lt;span class=&#34;c1&#34;&gt;#&amp;#39;org-node-parser--collect-dangerously t)&lt;/span&gt;
emacsomancer    &lt;span class=&#34;m&#34;&gt;26517&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 19:47 ?        00:00:02 /home/emacsomancer/.guix-home/profile/bin/emacs --quick --batch --load /home/emacsomancer/.emacs.d/eln-cache/30.0.93-e51375a4/el-job-child-8a892b0e-c7b5e3df.eln --eval &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;el-job-child--work &lt;span class=&#34;c1&#34;&gt;#&amp;#39;org-node-parser--collect-dangerously t)&lt;/span&gt;
emacsomancer    &lt;span class=&#34;m&#34;&gt;26518&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 19:47 ?        00:00:02 /home/emacsomancer/.guix-home/profile/bin/emacs --quick --batch --load /home/emacsomancer/.emacs.d/eln-cache/30.0.93-e51375a4/el-job-child-8a892b0e-c7b5e3df.eln --eval &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;el-job-child--work &lt;span class=&#34;c1&#34;&gt;#&amp;#39;org-node-parser--collect-dangerously t)&lt;/span&gt;
emacsomancer    &lt;span class=&#34;m&#34;&gt;26519&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 19:47 ?        00:00:01 /home/emacsomancer/.guix-home/profile/bin/emacs --quick --batch --load /home/emacsomancer/.emacs.d/eln-cache/30.0.93-e51375a4/el-job-child-8a892b0e-c7b5e3df.eln --eval &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;el-job-child--work &lt;span class=&#34;c1&#34;&gt;#&amp;#39;org-node-parser--collect-dangerously t)&lt;/span&gt;
emacsomancer    &lt;span class=&#34;m&#34;&gt;26750&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;23962&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 19:48 tty8     00:00:00 /home/emacsomancer/.guix-home/profile/bin/emacsclient -c
emacsomancer    &lt;span class=&#34;m&#34;&gt;26761&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;23962&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 19:48 tty8     00:00:00 /home/emacsomancer/.guix-home/profile/bin/emacsclient -c -e &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;mu4e&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since you&amp;rsquo;ve piped &lt;code&gt;ps&lt;/code&gt; through &lt;code&gt;grep&lt;/code&gt;, you&amp;rsquo;re missing the explanatory
column headers row (because that row doesn&amp;rsquo;t contain the string &amp;ldquo;emacs&amp;rdquo;
and so has been filtered out by &lt;code&gt;grep&lt;/code&gt;), which are:&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;UID        PID  PPID  C STIME TTY          TIME CMD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, then, picking one of the entries above, let&amp;rsquo;s line them up:&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;UID             PID    PPID  C STIME TTY      TIME     CMD
emacsomancer    &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;     &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt; 19:47 ?        00:05:42 /home/emacsomancer/.guix-home/profile/bin/emacs --daemon --debug-init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The UID is just the name of &amp;ldquo;user&amp;rdquo; who executed the process (probably
you). The CMD is what the process actually is, which is important. The
other important piece here is the PID, which is the Process ID or
&lt;a href=&#34;https://en.wikipedia.org/wiki/Process_identifier&#34;&gt;Processor identifier&lt;/a&gt;, for with this you can have your system kill (or
do other things) to a very specific process (usually an application,
or a process it&amp;rsquo;s spun off). The other fields aren&amp;rsquo;t relevant for us
here.&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;h3 id=&#34;kill--or-how-to-kill-things-nicely&#34;&gt;&lt;code&gt;kill&lt;/code&gt; (or, how to kill things nicely)&lt;/h3&gt;
&lt;p&gt;With the PID, you can do various things with a process, such as
&lt;a href=&#34;https://en.wikipedia.org/wiki/Kill_(command)&#34;&gt;&lt;code&gt;kill&lt;/code&gt;&lt;/a&gt;. This could be a simple &lt;code&gt;kill 26384&lt;/code&gt; to kill the &lt;code&gt;emacs --daemon&lt;/code&gt;
process.&lt;/p&gt;
&lt;p&gt;Sometimes, processes don&amp;rsquo;t want to die and a simple &lt;code&gt;kill&lt;/code&gt; won&amp;rsquo;t work.
&lt;code&gt;kill&lt;/code&gt; is equivalent to &lt;code&gt;kill -TERM&lt;/code&gt; or &lt;code&gt;kill -15&lt;/code&gt;, which essentially nicely
ask the process to stop. This is often good, because if the process
has some sort of &amp;ldquo;exit things&amp;rdquo; it does, like saving backups of open
files, it will do those things first before stopping.&lt;/p&gt;
&lt;p&gt;But sometimes the reason you&amp;rsquo;re in the command line in the first place
is because a process is hung, and so the simple &lt;code&gt;kill&lt;/code&gt; won&amp;rsquo;t do any
good.&lt;/p&gt;
&lt;h3 id=&#34;kill-9--or-what-if-politely-killing-doesn-t-work&#34;&gt;&lt;code&gt;kill -9&lt;/code&gt; (or, what if politely killing doesn&amp;rsquo;t work)&lt;/h3&gt;
&lt;p&gt;In that case you can do &lt;code&gt;kill -9&lt;/code&gt;, which is &amp;ldquo;the unsafe way of brutally
murdering a process. It&amp;rsquo;s equivalent to pulling the power cord, and
may cause data corruption.&amp;quot;&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; This often not what you want
to do, but is useful for when you need to force something to stop
immediately or when it&amp;rsquo;s not responding to polite &lt;code&gt;kill&lt;/code&gt;&#39;s. (Though
&lt;code&gt;kill -9&lt;/code&gt; / &lt;code&gt;SIGKILL&lt;/code&gt; won&amp;rsquo;t kill &lt;a href=&#34;https://en.wikipedia.org/wiki/Zombie_process&#34;&gt;zombies&lt;/a&gt;, because they&amp;rsquo;re dead already and
are just waiting for their parent processes to reap them.)&lt;/p&gt;
&lt;h3 id=&#34;advanced-pkill--or-what-if-there-are-too-many-things-to-kill-one-by-one&#34;&gt;Advanced &lt;code&gt;pkill&lt;/code&gt; (or, what if there are too many things to kill one by one?)&lt;/h3&gt;
&lt;p&gt;If you recall the &lt;code&gt;ps -ef | grep -i emacs&lt;/code&gt; output from above, there are
often a bunch of associated processes. I&amp;rsquo;ve often ended up having to
try to run &lt;code&gt;kill&lt;/code&gt; (or &lt;code&gt;kill -9&lt;/code&gt;) on a bunch of PIDs one by one until
finally the application shut down (cases where &lt;code&gt;killall&lt;/code&gt; didn&amp;rsquo;t work for
one reason or other).&lt;/p&gt;
&lt;p&gt;We can instead use our process lister (&lt;code&gt;ps -ef&lt;/code&gt;) with piping to
&lt;code&gt;pkill&lt;/code&gt;. E.g., like this in the case of killing all processes named
&amp;ldquo;emacs&amp;rdquo;:&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;ps -ef &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pkill -f emacs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Careful, because, especially if the &amp;ldquo;name&amp;rdquo; is short, it might be a
substring of other running processes. (I.e., you probably &lt;strong&gt;don&amp;rsquo;t&lt;/strong&gt; want to
try something like &lt;code&gt;ps -ef | pkill -f e&lt;/code&gt;. It would kill &lt;code&gt;emacs --daemon&lt;/code&gt;,
true, but it would also kill any other process with an &lt;code&gt;e&lt;/code&gt; in it.)&lt;/p&gt;
&lt;p&gt;You can check first by piping &lt;code&gt;ps -ef&lt;/code&gt; through &lt;a href=&#34;https://en.wikipedia.org/wiki/Pgrep&#34;&gt;&lt;code&gt;pgrep&lt;/code&gt;&lt;/a&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;ps -ef &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pgrep -l emacs &lt;span class=&#34;c1&#34;&gt;# show the list of all the processes (and their names) to be killed first&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;to see a list of the names of the processes that would be killed (for
our &lt;code&gt;emacs&lt;/code&gt; example).&lt;/p&gt;
&lt;p&gt;Or, if you need a bit more information, do instead:&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;ps -ef &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pgrep -a emacs &lt;span class=&#34;c1&#34;&gt;# show the list of all the processes (and their full command line, not just name) to be killed first&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;to see the full command line (including but not limited to the
process&amp;rsquo;s name).&lt;/p&gt;
&lt;p&gt;And, just like &lt;code&gt;kill&lt;/code&gt; above, &lt;code&gt;pkill&lt;/code&gt; is by default the &amp;ldquo;polite kill&amp;rdquo;. If
you&amp;rsquo;re dealing with stubborn processes, you can add a &lt;code&gt;-9&lt;/code&gt; to order
&lt;code&gt;SIGKILL&lt;/code&gt;, e.g.:&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;ps -ef &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pkill -9 -f emacs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(If you had a completely hung Emacs, say.)&lt;/p&gt;
&lt;h2 id=&#34;what-if-you-need-to-do-something-other-than-killing-a-bunch-of-things&#34;&gt;What if you need to do something other than killing a bunch of things?&lt;/h2&gt;
&lt;p&gt;This is all well and good if all you need to do is &lt;code&gt;kill&lt;/code&gt;, but sometimes
there are other things to do.&lt;/p&gt;
&lt;p&gt;For instance, I finally got &lt;a href=&#34;https://en.wikipedia.org/wiki/Mullvad&#34;&gt;Mullvad VPN&lt;/a&gt;&amp;lsquo;s own &lt;a href=&#34;https://github.com/mullvad/mullvadvpn-app&#34;&gt;graphical client&lt;/a&gt; to work
on Guix,&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; but for some reason the graphical interface &lt;a href=&#34;https://en.wikipedia.org/wiki/Split_tunneling&#34;&gt;split
tunnelling&lt;/a&gt; doesn&amp;rsquo;t work for me on Guix (usually the Mullvad interface
would allow you open a specific application outside of the VPN tunnel
(i.e. on your regular connection)). Fortunately, Mullvad also has
a command-line interface and one can add currently running
applications to be excluded from the VPN tunnel (this is also useful
even if your Mullvad GUI split-tunnelling is working for not having to
shut down and re-open applications if you want them excluded from your
VPN tunnel). But it does it by PID, e.g.:&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;mullvad split-tunnel add &lt;span class=&#34;m&#34;&gt;26384&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(if we were excluding the &lt;code&gt;emacs --daemon&lt;/code&gt; PID from the above example
from the VPN tunnel, say.)&lt;/p&gt;
&lt;p&gt;One of the obvious things one might want to exclude from a VPN tunnel
is a particular browser (e.g., there&amp;rsquo;s a site that doesn&amp;rsquo;t like the
VPN, so you open up a second browser outside of the VPN to use to
access that site).&lt;/p&gt;
&lt;p&gt;But browsers often involve a number of processes, and I found myself
having to manually run the &lt;code&gt;mullvad split-tunnel add&lt;/code&gt; command on ten
different PIDs, and check mullvad.net each time to see if that was the
one I needed or not.&lt;/p&gt;
&lt;p&gt;This is both time-consuming and frustrating and, just like &lt;code&gt;kill&lt;/code&gt;&#39;ing, we
can instead do it at scale.&lt;/p&gt;
&lt;p&gt;Now, the &lt;code&gt;mullvad split-tunnel&lt;/code&gt; command itself doesn&amp;rsquo;t have a built-in
facility to either add processes by name or more than one in a single
shot, but we can write a loop over a list of PIDs and have the loop
execute &lt;code&gt;mullvad split tunnel add ...&lt;/code&gt; for each one.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&#34;https://en.wikipedia.org/wiki/Bash_(Unix_shell)&#34;&gt;Bash&lt;/a&gt; (&amp;ldquo;the Bourne Again SHell&amp;rdquo;), if you wanted to exclude Firefox
from the Mullvad VPN tunnel, you could do:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; pid in &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;pgrep -u &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;id -u&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; -f &lt;span class=&#34;s2&#34;&gt;&amp;#34;firefox&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt; mullvad split-tunnel add &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Just like for &lt;code&gt;pkill&lt;/code&gt;, you can double-check before what would be added
to the tunnel exclusion by doing one of:&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;ps -ef &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pgrep -l firefox &lt;span class=&#34;c1&#34;&gt;# show the list of all the processes (and their names) to be killed first&lt;/span&gt;
ps -ef &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pgrep -a firefox &lt;span class=&#34;c1&#34;&gt;# show the list of all the processes (and their full command line, not just name) to be killed first&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you&amp;rsquo;re using &lt;a href=&#34;https://fishshell.com&#34;&gt;Fish shell&lt;/a&gt; (&amp;ldquo;FInally, a command line SHell for the
90s&amp;rdquo;), instead of the Bash line above, you would use:&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;k&#34;&gt;for&lt;/span&gt; pid in &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;pgrep -u &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;id -u&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; -f &lt;span class=&#34;s2&#34;&gt;&amp;#34;firefox&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; mullvad split-tunnel add &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;but-what-if-you-don-t-want-to-remember-arcane-incantations&#34;&gt;But what if you don&amp;rsquo;t want to remember arcane incantations?&lt;/h3&gt;
&lt;p&gt;I don&amp;rsquo;t, or, well, won&amp;rsquo;t. I can probably find it in my shell history
once I&amp;rsquo;ve run it on a machine, but we can do better than that.&lt;/p&gt;
&lt;p&gt;We can instead add a function to the shell.&lt;/p&gt;
&lt;p&gt;For Bash, you would add to your &lt;code&gt;~/.bash_profile&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; mullvad-split-tunnel-by-name&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; pid in &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;pgrep -u &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;id -u&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -f &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&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;
  &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
      mullvad split-tunnel add &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
      &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;added to split tunnel: %s\n&amp;#34;&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;ps -p &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -o &lt;span class=&#34;nv&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk &lt;span class=&#34;s1&#34;&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(You don&amp;rsquo;t need the &lt;code&gt;printf&lt;/code&gt; bit if you don&amp;rsquo;t want, but this way you&amp;rsquo;ll see a
proper list of the names of all of the excluded processes, which the
&lt;code&gt;mullvad split-tunnel add&lt;/code&gt; command doesn&amp;rsquo;t do by itself.)&lt;/p&gt;
&lt;p&gt;Then (once your &lt;code&gt;.bash_profile&lt;/code&gt; is &lt;code&gt;source&lt;/code&gt;&#39;ed)&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;, you could just
enter the following in the terminal to have all &lt;code&gt;firefox&lt;/code&gt; processes
excluded from the Mullvad VPN tunnel:&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;mullvad-split-tunnel-by-name firefox
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(You can choose a shorter name for your function than
&lt;code&gt;mullvad-split-tunnel-by-name&lt;/code&gt; of course, but for me such is fine with
TAB completion.)&lt;/p&gt;
&lt;p&gt;And similarly for other things you wanted to exclude from the VPN
tunnel (e.g., &lt;code&gt;mullvad-split-tunnel-by-name chromium&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;For Fish, you would add a new file to your &lt;code&gt;~/.config/fish/functions/&lt;/code&gt;
directory (say
&lt;code&gt;~/.config/fish/functions/mullvad-functions.fish&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;k&#34;&gt;function&lt;/span&gt; mullvad-split-tunnel-by-name --description &lt;span class=&#34;s1&#34;&gt;&amp;#39;adds all matching instances to mullvads split tunnel&amp;#39;&lt;/span&gt;
  &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; pid in &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;pgrep -u &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;id -u&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; -f &lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
      mullvad split-tunnel add &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
      &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;added to split tunnel: %s\n&amp;#34;&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;ps -p &lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt; -o &lt;span class=&#34;nv&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk &lt;span class=&#34;s1&#34;&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(Again, the &lt;code&gt;printf&lt;/code&gt; line is optional. And again you should &lt;code&gt;source&lt;/code&gt; it or
restart your shell.)&lt;/p&gt;
&lt;h4 id=&#34;a-couple-of-other-useful-mullvad-split-tunnel-functions&#34;&gt;A couple of other useful mullvad split-tunnel functions&lt;/h4&gt;
&lt;p&gt;These can be defined in similar fashion to the above
&lt;code&gt;mullvad-split-tunnel-by-name&lt;/code&gt;: one for removing things from the VPN
excluded list, and for one for showing what&amp;rsquo;s currently on the list by
name. (since &lt;code&gt;mullvad split-tunnel list&lt;/code&gt; just spits back a list of raw
PIDs, which isn&amp;rsquo;t very helpful for identifying what&amp;rsquo;s actually being
split tunnelled&amp;hellip;.)&lt;/p&gt;
&lt;!--list-separator--&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;removing processes from exclude list&lt;/p&gt;
&lt;p&gt;Like &lt;code&gt;mullvad-split-tunnel-by-name&lt;/code&gt;, but for removing excluded processes
(i.e., re-including them in VPN tunnel):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In Bash:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; mullvad-remove-process-by-name&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
   &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; pid in &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;pgrep -u &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;id -u&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -f &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&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;
   &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
       mullvad split-tunnel delete &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
       &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;removed from split tunnel: %s\n&amp;#34;&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;ps -p &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -o &lt;span class=&#34;nv&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk &lt;span class=&#34;s1&#34;&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
   &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Fish:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
 &lt;!--listend--&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;k&#34;&gt;function&lt;/span&gt; mullvad-remove-process-by-name --description &lt;span class=&#34;s1&#34;&gt;&amp;#39;remove all matching instances to mullvads split tunnel&amp;#39;&lt;/span&gt;
  &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; pid in &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;pgrep -u &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;id -u&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; -f &lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
      mullvad split-tunnel delete &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
      &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;removed from split tunnel: %s\n&amp;#34;&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;ps -p &lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt; -o &lt;span class=&#34;nv&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk &lt;span class=&#34;s1&#34;&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!--list-separator--&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;listing processes in exclude list by name rather than PID&lt;/p&gt;
&lt;p&gt;Checking on what&amp;rsquo;s currently split out from the VPN tunnel: this
provide a listing of processes currently excluded from the VPN tunnel
by name (in a couple of options):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Bash:&lt;/li&gt;
&lt;/ul&gt;
 &lt;!--listend--&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# list full command line info associated with each PID in list&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; mullvad-list-excluded-processes-by-long-name&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nv&#34;&gt;mullvad_vpn_exclude_array&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;mullvad split-tunnel list&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nv&#34;&gt;mvre&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;^[0-9]+$&amp;#39;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Processes excluded from VPN tunnel:\n\n&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; key in &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!mullvad_vpn_exclude_array[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt; &lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mullvad_vpn_exclude_array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&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;o&#34;&gt;=&lt;/span&gt;~ &lt;span class=&#34;nv&#34;&gt;$mvre&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;PID %s = %s\n&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mullvad_vpn_exclude_array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&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;s2&#34;&gt;&amp;#34;&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;ps -p &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mullvad_vpn_exclude_array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&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;s2&#34;&gt;&amp;#34;&lt;/span&gt; -o &lt;span class=&#34;nv&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# list just process name info associated with each PID in list&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; mullvad-list-excluded-processes-by-short-name&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nv&#34;&gt;mullvad_vpn_exclude_array&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;mullvad split-tunnel list&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nv&#34;&gt;mvre&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;^[0-9]+$&amp;#39;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Processes excluded from VPN tunnel:\n\n&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; key in &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!mullvad_vpn_exclude_array[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt; &lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mullvad_vpn_exclude_array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&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;o&#34;&gt;=&lt;/span&gt;~ &lt;span class=&#34;nv&#34;&gt;$mvre&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;PID %s = %s\n&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mullvad_vpn_exclude_array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&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;s2&#34;&gt;&amp;#34;&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;ps -p &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mullvad_vpn_exclude_array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&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;s2&#34;&gt;&amp;#34;&lt;/span&gt; -o &lt;span class=&#34;nv&#34;&gt;comm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Similarly for Fish:
&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;k&#34;&gt;function&lt;/span&gt; mullvad-list-excluded-processes-by-long-name --description &lt;span class=&#34;s1&#34;&gt;&amp;#39;lists excluded processes in mullvads split tunnel by long command name&amp;#39;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Processes excluded from VPN tunnel:\n&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; key in &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;mullvad split-tunnel list&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; string match -qr &lt;span class=&#34;s1&#34;&gt;&amp;#39;^[0-9]+$&amp;#39;&lt;/span&gt; -- &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
             &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;PID %s: %s\n&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&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;ps -p &lt;span class=&#34;nv&#34;&gt;$key&lt;/span&gt; -o &lt;span class=&#34;nv&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
        end
    end
end

&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; mullvad-list-excluded-processes-by-short-name --description &lt;span class=&#34;s1&#34;&gt;&amp;#39;lists excluded processes in mullvads split tunnel by short process name&amp;#39;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Processes excluded from VPN tunnel:&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; key in &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;mullvad split-tunnel list&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; string match -qr &lt;span class=&#34;s1&#34;&gt;&amp;#39;^[0-9]+$&amp;#39;&lt;/span&gt; -- &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
             &lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;PID %s: %s\n&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&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;ps -p &lt;span class=&#34;nv&#34;&gt;$key&lt;/span&gt; -o &lt;span class=&#34;nv&#34;&gt;comm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
        end
    end
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;beyond-tunnelling-and-killing&#34;&gt;Beyond tunnelling and killing&lt;/h2&gt;
&lt;p&gt;These techniques — including defining various named speciality
functions (in whatever shell) — could obviously be adapted for other
similar cases of wanting to run a command on multiple processes
sharing (all or part of) a name, whenever you find you&amp;rsquo;re tired of
wasting time manually mucking about with heaps of PIDs.&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;For list of good Linux system &lt;code&gt;top&lt;/code&gt;&#39;s and related, see, e.g.,
&lt;a href=&#34;https://github.com/luong-komorebi/Awesome-Linux-Software#system-info--monitoring&#34;&gt;https://github.com/luong-komorebi/Awesome-Linux-Software#system-info--monitoring&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;The &lt;a href=&#34;https://en.wikipedia.org/wiki/Xkill&#34;&gt;Wikipedia page&lt;/a&gt; for &lt;code&gt;xkill&lt;/code&gt; notes: &amp;lsquo;Xkill has been cited as
an example of a program with a simple and appealing user
interface. Its mode of operation has been summed up as &amp;ldquo;Just click the
bad thing with the skull and it dies.&amp;quot;&amp;rsquo; &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 Scheme-based package manager+Linux distribution (&lt;a href=&#34;https://en.wikipedia.org/wiki/GNU_Guix&#34;&gt;Wikipedia:
Guix&lt;/a&gt;). See elsewhere on this blog: &lt;a href=&#34;https://babbagefiles.xyz/categories/guix/&#34;&gt;#guix&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;The PPID is the Process ID of parent process. You can see that
the PID we&amp;rsquo;re looking at here is &lt;code&gt;26384&lt;/code&gt;, if you look at the longer list
of the output of &lt;code&gt;ps -ef | grep -i emacs&lt;/code&gt; above, you can see that this
is the PPID of a number of the other listed processes, because they
were started by this &lt;code&gt;emacs --daemon&lt;/code&gt; process. (—which itself has a PPID
of &lt;code&gt;1&lt;/code&gt; because I started it from the terminal myself, and that seems to
count as being started by Process 1, the first process started during
the booting of the system, which is usually the &lt;a href=&#34;https://en.wikipedia.org/wiki/Init&#34;&gt;init system&lt;/a&gt;,
presumably because it&amp;rsquo;s the ancestor of all other processes and
&amp;ldquo;adopts&amp;rdquo; any &amp;ldquo;orphaned&amp;rdquo; or otherwise apparently unsupervised
processes.) &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;Quote from:
&lt;a href=&#34;https://stackoverflow.com/a/43725403/570251&#34;&gt;https://stackoverflow.com/a/43725403/570251&lt;/a&gt;. &lt;code&gt;-9&lt;/code&gt; is equivalent to
&lt;code&gt;-SIGKILL&lt;/code&gt;, on which see &lt;a href=&#34;https://en.wikipedia.org/wiki/Signal_(IPC)#SIGKILL&#34;&gt;here&lt;/a&gt;, whereas the plain &lt;code&gt;kill&lt;/code&gt; or &lt;code&gt;kill -15&lt;/code&gt; is
&lt;code&gt;-SIGTERM&lt;/code&gt;, on which see &lt;a href=&#34;https://en.wikipedia.org/wiki/Signal_(IPC)#SIGTERM&#34;&gt;here&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;A working package definition for the Mullvad VPN desktop
client on Guix is &lt;a href=&#34;https://gitlab.com/emacsomancer/guix-awesomejit/-/blob/main/awesomejit/packages/mullvad.scm&#34;&gt;here&lt;/a&gt;. Using Mullvad on Guix has been a longtime
bugbear for me — so much so that I once wrote my frontend for it in
Common Lisp: &lt;a href=&#34;https://gitlab.com/emacsomancer/volemad&#34;&gt;Volemad&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;I.e., &lt;code&gt;source ~/.bash_profile&lt;/code&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;/ol&gt;
&lt;/section&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/linux">linux</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/shell">shell</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/you-need-to-kill-or-do-something-in-linux/</guid>
                <pubDate>Sat, 15 Feb 2025 23:02:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Using Emacs and Org-Roam/Org-Node on Android (with Termux Extra Keys)</title>
                <link>https://babbagefiles.xyz/termux-extra-keys-emacs-org-roam-node-android/</link>
                
                
                <description>&lt;p&gt;My main use of Emacs on Android (via Termux) is to be able to access
and add to my Org-roam library of notes. This post is primarily about
some Termux features which improve the user experience for this use
case. [Update &lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2025-02-03 Mon]&lt;/span&gt;&lt;/span&gt;: added some screenshots throughout to
give a sense of what it looks like.]&lt;/p&gt;
&lt;h2 id=&#34;trying-to-cope-with-emacs-on-mobile&#34;&gt;Trying to Cope with Emacs on mobile&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve tried a number of different solutions for managing sync&amp;rsquo;ed Org
files on mobile&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;, and some of these are useful for some
purposes, but to being able to access and add to my Org-Roam notes,
I&amp;rsquo;ve found I really need a full-blooded Emacs
instance.&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;&lt;/p&gt;
&lt;p&gt;And dealing with interacting with Emacs on a touchscreen
interface/touchscreen keyboard is a bit of a nightmare.&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/John_Tenniel_-_Playing_cards_-_in_The_nursery_Alice_in_Wonderland.jpg&#34;/&gt; &lt;/figure&gt;

&lt;p&gt;Here, we&amp;rsquo;ll try to improve it a little. Into the rabbit-hole&amp;hellip;.&lt;/p&gt;
&lt;h2 id=&#34;note-about-using-termux-for-emacs-on-android&#34;&gt;Note about using Termux for Emacs on Android&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;re probably better off installing Termux from &lt;a href=&#34;https://f-droid.org/en/packages/com.termux/&#34;&gt;F-Droid&lt;/a&gt; rather than
from the Google Play Store [see the note from the official Termux
maintainers at:
&lt;a href=&#34;https://github.com/termux/termux-app/discussions/4000&#34;&gt;https://github.com/termux/termux-app/discussions/4000&lt;/a&gt;]. This is
especially true is you want to use Emacs in Termux for managing
Org-roam files which are shared/kept in sync with your Emacs on
desktop machines, which you can do with &lt;a href=&#34;https://syncthing.net/&#34;&gt;Syncthing&lt;/a&gt; (use Catfriend1&amp;rsquo;s
Syncthing-fork [&lt;a href=&#34;https://github.com/Catfriend1/syncthing-android&#34;&gt;Github&lt;/a&gt;]/[&lt;a href=&#34;https://f-droid.org/en/packages/com.github.catfriend1.syncthingandroid/&#34;&gt;F-Droid&lt;/a&gt;] on Android), in order to be able to
grant Termux (and thus Emacs) access to your shared Org files.&lt;/p&gt;
&lt;h2 id=&#34;termux-extra-keys&#34;&gt;Termux Extra Keys&lt;/h2&gt;
&lt;p&gt;Termux has a very useful feature adding &lt;a href=&#34;https://wiki.termux.com/wiki/Touch_Keyboard#Extra_Keys_Row&#34;&gt;extra keys&lt;/a&gt; above the system
keyboard. These are quite useful, including &amp;lsquo;sticky&amp;rsquo; &lt;code&gt;CTRL&lt;/code&gt; and &lt;code&gt;ALT&lt;/code&gt;
keys. (In addition, one can hold &lt;code&gt;volume-down&lt;/code&gt; and press a key for
&lt;code&gt;CTRL&lt;/code&gt; + [that-key] or &lt;code&gt;volume-up&lt;/code&gt; and press a key for &lt;code&gt;ALT&lt;/code&gt; + [that-key];
with &lt;code&gt;volume-up&lt;/code&gt; + &lt;code&gt;t&lt;/code&gt; inputting &lt;code&gt;TAB&lt;/code&gt;. At least on my phone, using the
volume keys as modifiers is fairly awkward/uncomfortable, so I prefer
these extra keys.)&lt;/p&gt;
&lt;p&gt;[Nb.: These keys are toggled on and off by pressing &lt;code&gt;volume-up + k&lt;/code&gt; or
&lt;code&gt;volume-up + q&lt;/code&gt;. This is important to note, for I once toggled them off
by accident and couldn&amp;rsquo;t understand what had happened to them for
several months.]&lt;/p&gt;
&lt;p&gt;Also worth mentioning is the fact that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;swipe left on extra keys brings up swipe-compatible/regular keyboard
typing&lt;/li&gt;
&lt;li&gt;swipe right on regular keyboard typing area (where extra keys was)
will get you back to extra keys&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first of these lets you use any of your keyboard&amp;rsquo;s regular
features and so can be quite useful.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;https://wiki.termux.com/wiki/Touch_Keyboard#Extra_Keys_Row&#34;&gt;Termux manual on Extra Keys&lt;/a&gt; for a description and basic
configuration and usage instructions.&lt;/p&gt;
&lt;h2 id=&#34;extra-keys-for-better-emacs-navigation&#34;&gt;Extra Keys for better Emacs navigation&lt;/h2&gt;
&lt;p&gt;Here, I explore the possibilities offered by the advanced
configuration options for Extra Keys for navigating Emacs in Termux,
especially &lt;a href=&#34;https://www.orgroam.com&#34;&gt;Org-Roam&lt;/a&gt; or &lt;a href=&#34;https://github.com/meedstrom/org-node&#34;&gt;Org-node&lt;/a&gt; &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;, to create faster/easier ways of
calling commonly used commands since the user-interface to Emacs with
an on-screen keyboard is often somewhat frustrating compared to the
using Emacs with a physical keyboard. In addition to extra tappable
keys, Extra Keys also allows for different outcomes when the user does
swipe-up on a key, including the outputting of key sequences, which
can include modifier keys like &lt;code&gt;CTRL&lt;/code&gt;. This allows the possibility of
loading them with Emacs key sequences which would otherwise be much
slower to access with an onscreen keyboard.&lt;/p&gt;
&lt;p&gt;What I wanted was:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An easy, single-key (no modifier) way of doing forward and backward
searches. It is painful to either hold &lt;code&gt;volume-down&lt;/code&gt; or have to keep
on toggling the Extra Keys&amp;rsquo; &lt;code&gt;CTRL&lt;/code&gt; for each next/previous result. So I
recruited &lt;code&gt;♡&lt;/code&gt; and &lt;code&gt;♤&lt;/code&gt; for forward and back searches, respectively
(because ♡ is sort of pointed down and ♤ is sort of pointing up),
and bound these appropriately in my Emacs configuration (see below).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;other convenient single-key buffer navigation interface features, e.g.,
arrow keys and page-up and page-down&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;some convenience things like closing all but the current window
(&lt;code&gt;delete-other-windows&lt;/code&gt; = &lt;code&gt;C-x 1&lt;/code&gt;), opening up iBuffer, switch-buffer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;slashes and &lt;code&gt;-&lt;/code&gt; and &lt;code&gt;~&lt;/code&gt; available immediately to tap insert (not under
my keyboard&amp;rsquo;s symbol toggle or long-hold)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ability to call some Org-mode/Org-node commands quickly: including
finding nodes, inserting links to nodes, capturing new dailies,
committing captures, going to today&amp;rsquo;s daily entry, moving forward
and backwards through the dailies, toggling the org-roam backlinks
buffer&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/termux-ycombinator-id-node-search-y_comb.png&#34;/&gt; &lt;/figure&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;example-configuration&#34;&gt;Example configuration&lt;/h2&gt;
&lt;p&gt;The configuration outlined below is partially specific for my Emacs
configuration, especially for the &lt;code&gt;C-c&lt;/code&gt; (&lt;code&gt;CTRL c&lt;/code&gt;) keys, but some things
involve default Emacs keybindings and it can at least serve as a model
for what one can do. To configure Extra Keys, you need to modify the
&lt;code&gt;extra-keys&lt;/code&gt; part of &lt;code&gt;~/.termux/termux.properties&lt;/code&gt; in this fashion:&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;extra-keys &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;ESC&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL x 1&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;C-x 1&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;CTRL&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;C-c&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;ALT&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;ALT x&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;M-x&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;♡&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL x r b&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;bookmarks&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;~&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c n d&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;today&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;UP&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c n n&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;new note&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c CTRL k&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;cancel note&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;PGUP&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c n y&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;prev note&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;TAB&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL x b&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;alttab&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c n f&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;find node&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;\\\\&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c n i&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;insert link&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;♤&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL x CTRL b&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;ibuffer&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;LEFT&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c n l&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;backlinks&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;DOWN&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c CTRL c&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;RIGHT&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c n v&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;goto-date&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#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;  &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;key: &lt;span class=&#34;s1&#34;&gt;&amp;#39;PGDN&amp;#39;&lt;/span&gt;, popup: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;macro: &lt;span class=&#34;s2&#34;&gt;&amp;#34;CTRL c n t&amp;#34;&lt;/span&gt;, display: &lt;span class=&#34;s2&#34;&gt;&amp;#34;next note&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


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

&lt;p&gt;Here is a rough summary of what this does:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;key&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;do on key tap&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;do on key swipe up&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;display on swipe up&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;what key swipe up does&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ESC&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;esc&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-x 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;C-x 1&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;delete-other-windows&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CTRL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;ctrl&amp;rsquo; (&lt;code&gt;C-&lt;/code&gt;) toggle&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;C-c&amp;rdquo;&lt;/td&gt;
&lt;td&gt;start &lt;code&gt;C-c&lt;/code&gt; prefix command&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ALT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;alt&amp;rsquo; (&lt;code&gt;M-&lt;/code&gt;) toggle&lt;/td&gt;
&lt;td&gt;&lt;code&gt;M-x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;M-x&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;M-x&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;♡&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;isearch-forward&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-x r b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;bookmarks&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bookmark-jump&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;~&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c n d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;today&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;org-node-goto-today&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;↑&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;up&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c n n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;new note&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;org-roam-dailies-capture-today&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;-&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c C-k&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;cancel note&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c C-k&lt;/code&gt; to cancel capture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PGUP&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;pageup&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c n y&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;prev note&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;org-node-goto-next-day&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TAB&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;tab key&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-x b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;alttab&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;consult-buffer&lt;/code&gt; (&lt;code&gt;switch-to-buffer&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;/&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c n f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;find node&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;org-node-find&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;\&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c n i&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;insert link&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;org-node-insert-link*&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;♤&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;isearch-backward&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-x C-b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;ibuffer&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ibuffer&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;←&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;left&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c n l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;backlinks&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;org-roam-buffer-toggle&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;↓&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;down&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c C-c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;commit&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c C-c&lt;/code&gt; to &amp;lsquo;commit&amp;rsquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;→&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;right&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c n v&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;goto-date&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;org-node-goto-daily&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PGDN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;lsquo;pagedown&amp;rsquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-c n t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;next note&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;org-node-goto-prev-day&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In case you do use Org-node (and, if you&amp;rsquo;re trying to do Org-roam
things on Android, I would again recommend considering Org-node, if
only for making interactions fast enough to not be completely
frustrating), you could implement the following interactive functions:&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;org-node-goto-daily&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;interactive&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;org-node-seq--jump&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;d&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;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-node-goto-today&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;interactive&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;org-node-seq-goto&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;d&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format-time-string&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;%F&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;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-node-goto-next-day&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;interactive&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-mode&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;org-node-seq--goto-next&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;d&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;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-node-goto-prev-day&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;interactive&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-mode&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;org-node-seq--goto-previous&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;d&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;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-dailies-capture-today&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;interactive&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;org-roam-dailies-capture-today&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;d&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 then bind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;org-node-insert-link*&lt;/code&gt; to &amp;ldquo;C-c n i&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-node-find&lt;/code&gt; to &amp;ldquo;C-c n f&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-node-goto-daily&lt;/code&gt; to &amp;ldquo;C-c n v&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-node-goto-today&lt;/code&gt; to &amp;ldquo;C-c n d&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-node-goto-next-day&lt;/code&gt; to &amp;ldquo;C-c n t&amp;rdquo;  (&#39;[t]omorrow&amp;rsquo;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-node-goto-prev-day&lt;/code&gt; to &amp;ldquo;C-c n y&amp;rdquo; (&#39;[y]esterday&amp;rsquo;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-roam-dailies-capture-today&lt;/code&gt; to &amp;ldquo;C-c n n&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-roam-buffer-toggle&lt;/code&gt; to &amp;ldquo;C-c n l&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most of the other keybindings implemented above are default Emacs
bindings.&lt;/p&gt;



&lt;figure&gt;
    
        &lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/termux-org-node-id-search-clo_s.png&#34;/&gt; &lt;/figure&gt;

&lt;p&gt;In terms of how this improves the Termux Emacs experience, consider
that you could open up Emacs in Termux and then proceed by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;swiping up on &lt;code&gt;↑&lt;/code&gt; to open up a new Org-[roam/node] note in today&amp;rsquo;s
daily journal&lt;/li&gt;
&lt;li&gt;then swiping left on the extra keys pane to get into normal keyboard
entry mode&lt;/li&gt;
&lt;li&gt;swipe/glide-typing the text of your note quickly, and pressing enter&lt;/li&gt;
&lt;li&gt;swiping right on the now clear virtual keyboard pane to bring back
the extra keys&lt;/li&gt;
&lt;li&gt;swiping up on &lt;code&gt;\&lt;/code&gt; to insert (&amp;lsquo;splice in&amp;rsquo;) a org-id link to another
Org-roam node or two&lt;/li&gt;
&lt;li&gt;swiping up on &lt;code&gt;↓&lt;/code&gt; to commit/complete your daily note&lt;/li&gt;
&lt;li&gt;swiping up on &lt;code&gt;PGUP&lt;/code&gt; to see yesterday&amp;rsquo;s Org-roam daily journal&lt;/li&gt;
&lt;li&gt;swiping up on &lt;code&gt;/&lt;/code&gt; to search for your &amp;ldquo;Termux&amp;rdquo; Org-roam node to add
notes about Extra Keys to your Termux Org-roam node/file&lt;/li&gt;
&lt;li&gt;tapping &lt;code&gt;♡&lt;/code&gt; to search through the entry to see all the places you made
reference to &amp;ldquo;extra keys&amp;rdquo;&lt;/li&gt;
&lt;li&gt;swiping up on &lt;code&gt;←&lt;/code&gt; to see what backlinks you have for &amp;ldquo;Termux&amp;rdquo;&lt;/li&gt;
&lt;li&gt;swiping up on &lt;code&gt;ESC&lt;/code&gt; to get back to single window view&lt;/li&gt;
&lt;li&gt;swiping up on &lt;code&gt;♤&lt;/code&gt; to get to IBuffer to be able to manage your buffers&lt;/li&gt;
&lt;li&gt;swiping up on &lt;code&gt;↑&lt;/code&gt; to open another new daily note in today&amp;rsquo;s journal&lt;/li&gt;
&lt;li&gt;changing your mind and swiping up on &lt;code&gt;-&lt;/code&gt; to cancel the note capture&lt;/li&gt;
&lt;li&gt;&amp;hellip;..&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is all a lot faster than having to tap &lt;code&gt;CTRL&lt;/code&gt; and then type &lt;code&gt;c&lt;/code&gt; &lt;code&gt;n&lt;/code&gt; &lt;code&gt;n&lt;/code&gt;
to start a new entry in today&amp;rsquo;s Org-roam daily journal, typing it out
(tapping &lt;code&gt;CTRL&lt;/code&gt; and then &lt;code&gt;c n i&lt;/code&gt; each time you want to link text to
another node), and then tapping &lt;code&gt;CTRL&lt;/code&gt; and then &lt;code&gt;c&lt;/code&gt; and then &lt;code&gt;CTRL&lt;/code&gt; and then
&lt;code&gt;c&lt;/code&gt; to commit it, and so on.&lt;/p&gt;
&lt;p&gt;For a bonus reduction in modifier and key tapping, consider using a
modal mode in Emacs: I particularly like &lt;a href=&#34;https://github.com/meow-edit/meow&#34;&gt;meow&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;appendix-key-mnemonics&#34;&gt;Appendix: Key Mnemonics&lt;/h2&gt;
&lt;p&gt;A potentially useful/emblematic list of mnemonics for the keys. [I use
☝️ to indicate swiping up on a key below.] Some of these mnemonics are
stretches, but there are only so many keys and a particular set of
things one wants, so stretches are sometimes required.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;♡&lt;/code&gt; is a forwards/downwards search because the heart points down&lt;/li&gt;
&lt;li&gt;&lt;code&gt;♤&lt;/code&gt; is a backwards/upwards search because the spade points up [and we
use these pointy characters indicating card suits in preference to
others because I&amp;rsquo;m not going to be typing them on Android ever]&lt;/li&gt;
&lt;li&gt;(all other single tap keys just do what it says on the tin,
inserting characters, toggling modifiers, &amp;amp;c.)&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;♡&lt;/code&gt; is bookmarks because these are &amp;lsquo;favourites&amp;rsquo; because you &amp;lsquo;♡&amp;rsquo; them&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;♤&lt;/code&gt; is IBuffer because if you have icons enabled in your IBuffer&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;
then you&amp;rsquo;ll see icons and ♤ is like an icon (I know this one is a
stretch, but&amp;hellip;.&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;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;ESC&lt;/code&gt; is &lt;code&gt;delete-other-windows&lt;/code&gt; because you&amp;rsquo;re &amp;lsquo;escaping&amp;rsquo; from them&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;CTRL&lt;/code&gt; is &lt;code&gt;C-c&lt;/code&gt; because &lt;code&gt;C-c&lt;/code&gt; starts with CTRL&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;ALT&lt;/code&gt; is &lt;code&gt;M-x&lt;/code&gt; because &lt;code&gt;M-x&lt;/code&gt; starts with ALT&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;~&lt;/code&gt; is &lt;code&gt;org-node-goto-today&lt;/code&gt; because in Unix &lt;code&gt;~&lt;/code&gt; is &amp;ldquo;user&amp;rsquo;s home
directory&amp;rdquo; and today&amp;rsquo;s daily Org-roam entry is a sort of a &amp;lsquo;home&amp;rsquo;
(it makes sense to me anyway)&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;-&lt;/code&gt; is &lt;code&gt;C-c C-k&lt;/code&gt; is which &amp;lsquo;cancel&amp;rsquo; in lots of places (like capture
templates) and &lt;code&gt;-&lt;/code&gt; is a negative sign and so can be understood like
&amp;ldquo;don&amp;rsquo;t do it!&amp;rdquo;&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;↑&lt;/code&gt; is &lt;code&gt;org-roam-dailies-capture-today&lt;/code&gt; because this is the function
to capture a new Org-roam daily note and ↑ is like &amp;ldquo;opening up
something&amp;rdquo;&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;↓&lt;/code&gt; is &lt;code&gt;C-c C-c&lt;/code&gt; which is in many places in Emacs something like
&amp;lsquo;commit&amp;rsquo;, and for capture templates it is the &amp;lsquo;finish capture&amp;rsquo;
binding and if ↑ is opening a new note, then ↓ is finishing it,
putting it &amp;lsquo;down&amp;rsquo;&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;←&lt;/code&gt; is open up Org-roam backlinks buffer because ← is pointing
&amp;lsquo;backwards&amp;rsquo;&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;→&lt;/code&gt; is &lt;code&gt;org-node-goto-daily&lt;/code&gt; because we&amp;rsquo;re looking &amp;lsquo;forward&amp;rsquo; towards a
specific date and going to it&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;PGUP&lt;/code&gt; is &lt;code&gt;org-node-goto-prev-day&lt;/code&gt; because we&amp;rsquo;re going
&amp;lsquo;up&amp;rsquo;/&amp;lsquo;backwards&amp;rsquo; in the calendar (of daily Org-roam journal entries)&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;PGDN&lt;/code&gt; is &lt;code&gt;org-node-goto-prev-day&lt;/code&gt; because we&amp;rsquo;re going
&amp;lsquo;down&amp;rsquo;/&amp;lsquo;forwards&amp;rsquo; in the calendar (of daily Org-roam journal
entries)&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;TAB&lt;/code&gt; is &lt;code&gt;consult-buffer&lt;/code&gt; / &lt;code&gt;switch-to-buffer&lt;/code&gt; because this function is
sort of like &lt;code&gt;Alt-TAB&lt;/code&gt; in many window environments&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;/&lt;/code&gt; is &lt;code&gt;org-node-find&lt;/code&gt; because &lt;code&gt;/&lt;/code&gt; is the search key in Vim, and also
associated with searches elsewhere in Unixland (the marker of
beginning/end of regexs, often used for searches) [and because &lt;code&gt;/&lt;/code&gt; is
the opposite slash from &lt;code&gt;\&lt;/code&gt;, which we&amp;rsquo;re going to use for the
complementary operation to insert links]&lt;/li&gt;
&lt;li&gt;☝️ &lt;code&gt;\&lt;/code&gt; is &lt;code&gt;org-node-insert-link*&lt;/code&gt; because in many environments &lt;code&gt;\&lt;/code&gt; is some
sort of &amp;lsquo;splice&amp;rsquo; indicator&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;, and inserting a link to a node is
also sort of a splice [and because &lt;code&gt;\&lt;/code&gt; is the opposite slash from &lt;code&gt;/&lt;/code&gt;
which performs a complementary operation]&lt;/li&gt;
&lt;/ul&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;E.g., &lt;a href=&#34;https://www.orgzly.com/&#34;&gt;orgzly&lt;/a&gt;, &lt;a href=&#34;https://organice.200ok.ch/&#34;&gt;organice&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;There is a &lt;a href=&#34;https://f-droid.org/packages/org.gnu.emacs/&#34;&gt;full GUI Emacs now on Android&lt;/a&gt;, but I
don&amp;rsquo;t know how to get it to be able to access files shared via
Syncthing, and, anyway, you wouldn&amp;rsquo;t be able to do the sort of
convenient keyboard hacks there I&amp;rsquo;m going to discuss in this post. &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;I highly recommend looking at Martin Edström&amp;rsquo;s &lt;a href=&#34;https://github.com/meedstrom/org-node&#34;&gt;Org-node&lt;/a&gt; package if
you&amp;rsquo;re trying to manage Org-roam notes on Android; the performance
differences between the two packages are especially noticeable on
Android (orders of magnitude&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;). And the two packages can live
alongside each other, so you can keep your existing Org-roam set-up
going while you set-up/experiment with Org-node. &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;With a package like
&lt;a href=&#34;https://github.com/seagle0128/all-the-icons-ibuffer&#34;&gt;https://github.com/seagle0128/all-the-icons-ibuffer&lt;/a&gt;. On IBuffer
itself, see &lt;a href=&#34;https://www.emacswiki.org/emacs/IbufferMode&#34;&gt;https://www.emacswiki.org/emacs/IbufferMode&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;Well, okay, so here&amp;rsquo;s another one: think of
IBuffer as trying to right your buffer organisation like Two, Five,
and Seven (of Spades) in Alice in Wonderland trying sort out the
Queen of Hearts&amp;rsquo; rose-bushes (by painting the roses red):
&lt;img src=&#34;https://babbagefiles.xyz/ox-hugo/Two_Five_and_Seven_of_Spades_Painting_the_Rosebushes.jpg&#34; alt=&#34;&#34;&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;From &lt;a href=&#34;https://port70.net/~nsz/c/c11/n1570.html#5.1.1.2&#34;&gt;https://port70.net/~nsz/c/c11/n1570.html#5.1.1.2&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Each instance of a backslash character (\) immediately followed by a
new-line character is deleted, &lt;strong&gt;splicing&lt;/strong&gt; physical source lines to form
logical source lines. Only the last backslash on any physical source
line shall be eligible for being part of such a &lt;strong&gt;splice&lt;/strong&gt;. A source file
that is not empty shall end in a new-line character, which shall not
be immediately preceded by a backslash character before any such
&lt;strong&gt;splicing&lt;/strong&gt; takes place.&lt;/p&gt;
&lt;/blockquote&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;/li&gt;
&lt;li id=&#34;fn:7&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Android 10/11 seems to have introduced
which restricts
how regular applications/users can interact with the filesystem, for
&amp;lsquo;security&amp;rsquo; reasons, implemented via &lt;a href=&#34;https://en.wikipedia.org/wiki/Filesystem_in_Userspace&#34;&gt;Filesystem in Userspace (FUSE)&lt;/a&gt;,
which makes operations which interact with the file system sometimes
very sluggish. Accessing directories with lots of files, as one might
have in an Org-roam directory, can be amazingly slow. The increases
exponentially with the number of Org-roam files.&lt;/p&gt;
&lt;p&gt;Org-node is implemented in such a way
[cf. &lt;a href=&#34;https://github.com/meedstrom/org-node/issues/26&#34;&gt;https://github.com/meedstrom/org-node/issues/26&lt;/a&gt;] that it
caches/stores and accesses many things in ways that avoid directly
accessing the file-system (especially in &lt;a href=&#34;https://github.com/meedstrom/org-node-fakeroam&#34;&gt;org-node-fakeroam&lt;/a&gt;), where
Org-roam does not. &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;/ol&gt;
&lt;/section&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                
                            
                        
                     
                        
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/tags/orgroam">orgroam</category>
                                 
                                    <category domain="https://babbagefiles.xyz/tags/android">android</category>
                                
                            
                        
                    
                
                <guid>https://babbagefiles.xyz/termux-extra-keys-emacs-org-roam-node-android/</guid>
                <pubDate>Thu, 30 Jan 2025 14:15:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Guix, XIM, Emacs, Multi_key, Shft&#43;SPC</title>
                <link>https://babbagefiles.xyz/guix-xim-emacs-multikey-shft-spc/</link>
                
                
                <description>&lt;blockquote&gt;
&lt;p&gt;— Describe in single words only the good things that come into your mind
about&amp;hellip; &lt;code&gt;&amp;lt;Multi_key&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;— &lt;code&gt;&amp;lt;Multi_key&amp;gt;&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;— Yeah.&lt;/p&gt;
&lt;p&gt;— Let me tell you about &lt;code&gt;&amp;lt;Multi_key&amp;gt;&lt;/code&gt;&amp;hellip;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;quot;&amp;lt;Multi_key&amp;gt; is undefined&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A bit out of order, but things tangle, a problem I&amp;rsquo;m having on my Guix
machine with Emacs.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s connected with the Lucid toolkit&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;, but only in an
indirect causal sort of way:— I&amp;rsquo;m using the standard GTK3 toolkit on
this particular build of Emacs on Guix. (A custom build, admittedly,
which might be part of the issue, but where exactly, I&amp;rsquo;m not sure.)
I&amp;rsquo;ll probably say some other things connected to this later, but for
the moment forget about Lucid. It&amp;rsquo;s just a GTK3 toolkit build.&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;&lt;/p&gt;
&lt;p&gt;So, skipping over large swathes of story, I&amp;rsquo;ve got a seemingly
mostly-functioning build of Emacs 30.0.93 running on my Guix laptop
(which finally has a functioning StumpWM environment again), and I go
to type &lt;em&gt;æ&lt;/em&gt; or &lt;em&gt;þ&lt;/em&gt; or &lt;em&gt;á&lt;/em&gt; or &lt;em&gt;λ&lt;/em&gt; or something using &lt;code&gt;Right_Alt&lt;/code&gt; as a compose key
(defined by &lt;code&gt;xmodmap&lt;/code&gt;) and Emacs, without blinking an eye, flashes at
me, saying &lt;code&gt;&amp;quot;&amp;lt;Multi_key&amp;gt; is undefined&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I try various things to do with &lt;a href=&#34;https://en.wikipedia.org/wiki/X_Input_Method&#34;&gt;XIM&lt;/a&gt; and environment variables&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; and
none of it works. I finally come across a post on a FreeBSD bugs
tracker&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; which suggests a possible fix of setting &lt;code&gt;(setq x-gtk-use-native-input &#39;t)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And, though it feels like a hack for something that&amp;rsquo;s gone wrong in a
deeper way, it seems to work, and I can type &lt;em&gt;ɔ&lt;/em&gt; and &lt;em&gt;Þ&lt;/em&gt; and &lt;em&gt;γ&lt;/em&gt; and so
on.&lt;/p&gt;
&lt;p&gt;But then I&amp;rsquo;m reading a PDF (using &lt;a href=&#34;https://github.com/vedang/pdf-tools&#34;&gt;PDF Tools&lt;/a&gt;) and I go to page back up
to read an earlier bit by pressing Shift and SPACE and I find myself
paging down to the end of the document instead.&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;native input&amp;rdquo; method apparently won&amp;rsquo;t recognise Shft+SPACE, but
just sees SPACE and so pages down.&lt;/p&gt;
&lt;p&gt;So if &lt;code&gt;x-gtk-use-native-input&lt;/code&gt; is &lt;code&gt;nil&lt;/code&gt;, I can&amp;rsquo;t use the compose key in
Emacs, and if it&amp;rsquo;s &lt;code&gt;t&lt;/code&gt; then I can&amp;rsquo;t scroll properly in PDFs.&lt;/p&gt;
&lt;p&gt;I thought vaguely about writing a macro to process the &lt;a href=&#34;https://github.com/kragen/xcompose/&#34;&gt;&amp;lsquo;kragen&amp;rsquo; XCompose
definitions&lt;/a&gt; into a bunch of things of the form:&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;nf&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;global-map&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;Multi_key&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;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;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;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;nb&#34;&gt;interactive&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;insert&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;223&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 then have my init.el load the whole thing in. But I don&amp;rsquo;t think
that would quite work anyway, since sometimes I want to say insert a special
character as part of a search and not insert it into a text buffer.&lt;/p&gt;
&lt;p&gt;So I came up with a different stupid solution. It&amp;rsquo;s not perfect, but
it&amp;rsquo;s at least somewhat working while I try to figure out what went
wrong in the first place.&lt;/p&gt;
&lt;p&gt;Here it 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;nb&#34;&gt;when&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;system-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;guix-laptop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; on this Guix/StumpWM machine&amp;#39;s Emacs, xcompose doesn&amp;#39;t work:&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Emacs says &amp;#34;I don&amp;#39;t know what &amp;lt;Multi_key&amp;gt; means&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (well, it actually says &amp;#34;&amp;lt;Multi_key&amp;gt; is undefined&amp;#34;).&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; As per https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=278167&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; we can &amp;#39;fix&amp;#39; this if we set (setq x-gtk-use-native-input &amp;#39;t).&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Then xcompose will will work again ... but now Shift-SPACE won&amp;#39;t&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; So...&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;x-gtk-use-native-input&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;c1&#34;&gt;;; make sure Shift-SPACE works...&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; So, Emacs says &amp;#34;&amp;lt;Multi_key&amp;gt; is undefined&amp;#34;.&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Well, then, we can define it.&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Namely as a function which sets `x-gtk-use-native-input&amp;#39; to `t&amp;#39;,&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; and then calls an external shell-command to input &amp;lt;Multi_key&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (so that it acts like Right_Alt was pressed), and then sets a timer running&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; that turns `x-gtk-use-native-input&amp;#39; to `nil&amp;#39; after 10 seconds&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (so that Shift-SPACE will work again).&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;bms/xinput-hack&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;interactive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;;; stop the timer if there is one running already:&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;nv&#34;&gt;bms/xinput-timer-running&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cancel-timer&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bms/xinput-timer-running&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;;; set the input method to allow xcompose to work:&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;x-gtk-use-native-input&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;c1&#34;&gt;;; must have `xdotool&amp;#39; installed:&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;xdotool key Multi_key&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;;; record the name of the timer to stop it,&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;;; so we don&amp;#39;t end up with tonnes of timers somehow&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;bms/xinput-timer-running&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-at-time&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;;; this sets it for 10 secs; maybe could be shorter,&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;;; but you don&amp;#39;t want it turning off in the middle of sequences&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;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;x-gtk-use-native-input&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;c1&#34;&gt;;; And then we bind &amp;lt;Multi_key&amp;gt; to that function.&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (There, now it&amp;#39;s not undefined anymore.)&lt;/span&gt;

  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;global-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;&amp;lt;Multi_key&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bms/xinput-hack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; A stupid solution to a stupid problem.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&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;See &lt;a href=&#34;https://www.reddit.com/r/emacs/comments/1hlj04t/emacs_using_the_lucid_toolkit_is_blazingly_fast/&#34;&gt;Emacs Using the Lucid toolkit is blazingly fast |
r/emacs&lt;/a&gt; for why this might be interesting. This is the whole &amp;ldquo;out of
order&amp;rdquo; thing, but it&amp;rsquo;s not directly relevant for this particular post. &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;Though, on the plain, boring, ordinary GTK3 toolkit and its
relation to Emacs see &lt;a href=&#34;https://web.archive.org/web/20161115194659/https://www.facebook.com/notes/daniel-colascione/buttery-smooth-emacs/10155313440066102/&#34;&gt;&amp;ldquo;Buttery Smooth Emacs&amp;rdquo;&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;And I&amp;rsquo;ve already got &lt;code&gt;(setf (getenv &amp;quot;GTK_IM_MODULE&amp;quot;) &amp;quot;xim&amp;quot;)&lt;/code&gt;
and &lt;code&gt;(setf (getenv &amp;quot;QT_IM_MODULE&amp;quot;) &amp;quot;xim&amp;quot;&lt;/code&gt; setting environment variables
in my &lt;code&gt;init.lisp&lt;/code&gt; config for StumpWM here anyway. &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;&lt;a href=&#34;https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=278167&#34;&gt;https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=278167&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;/ol&gt;
&lt;/section&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/guix">guix</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/guix-xim-emacs-multikey-shft-spc/</guid>
                <pubDate>Thu, 30 Jan 2025 12:22:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Linux Terminal Emulator Features and Hardware Compatibility</title>
                <link>https://babbagefiles.xyz/terminal-emulator-vtt-features-compatibility/</link>
                
                
                <description>&lt;p&gt;In a continuing series of, er, terminal-related posts, a look at some
features of a subset of terminal emulators on Linux.&lt;/p&gt;
&lt;p&gt;I mainly use &lt;a href=&#34;https://github.com/akermu/emacs-libvterm&#34;&gt;vterm inside of Emacs&lt;/a&gt;, usually via &lt;a href=&#34;https://babbagefiles.xyz/categories/equake/&#34;&gt;Equake&lt;/a&gt;, but sometimes
I do want to spawn a terminal outside of Emacs, and so I&amp;rsquo;ve been
curious about the properties of different terminals, including the
ability to be used across a wide range of hardware.&lt;/p&gt;
&lt;p&gt;A few weeks ago [as of 28 June 2022], I came across &lt;a href=&#34;https://tomscii.sig7.se/zutty/&#34;&gt;Zutty&lt;/a&gt;, which
describes itself as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Zutty is a terminal emulator for the X Window System, functionally similar to several other X terminal emulators such as xterm, rxvt and countless others. It is also similar to other, much more modern, GPU-accelerated terminal emulators such as Alacritty and Kitty. What really sets Zutty apart is its radically simple, yet extremely efficient rendering implementation, coupled with a sufficiently complete feature set to make it useful for a wide range of users. Zutty offers high throughput with low latency, and strives to conform to relevant (published or de-facto) standards.&lt;/p&gt;
&lt;p&gt;Zutty is written in straightforward C++ and only relies on OpenGL ES 3.1 for rendering&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Zutty page includes a link to a blog post &lt;a href=&#34;https://tomscii.sig7.se/2020/12/A-totally-biased-comparison-of-Zutty&#34;&gt;&amp;ldquo;A totally biased
comparison of Zutty (to some better-known X terminal emulators)&amp;quot;&lt;/a&gt;,
which includes some interesting discussion of features of different
terminal emulators, including comparison of VT support levels, and
discussion of why this could be important. A number of terminal
emulators, perhaps leaning towards &amp;ldquo;minimalism&amp;rdquo;, only implement
support up to VT220, or even lower, which creates inefficiencies in
certain cases:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The difference between implementing a VT400 or VT500 terminal (provided the implementations are correct) is relatively inconsequential. The same cannot be said of the gap between these and VT220-level terminals. Programs running in a less capable virtual terminal must sometimes use longer series of basic escape sequences to achieve the results of a fewer number of more modern ones. For example, the DECLRMM control sequence (set left-right margin mode) is available from the VT420 and up, and will be used to restrict scrolling to the active part of two horizontally split tmux panes. On less capable terminals, tmux is forced to perform more work to achieve the same result. This is quite similar to how extended instructions on modern CPUs allow machine code to be more efficient than code compiled for an older machine. In other words, not implementing a modern VT variant goes directly counter to greater efficiency. And there is yet another downgrade from VT220 to those terminals that only claim to support VT100/VT102.&lt;/p&gt;
&lt;p&gt;It is surprising how unambitious the newer terminals Alacritty and Kitty are in this regard. I would have hoped that new, supposedly state-of-the-art entrants would take the effort to add support for modern VT standards. Switching from xterm to Alacritty (or any other modern terminal) should not be a major downgrade.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Inspired by this, I copy/supplement the table on that page with some
additional comparison information, and a few additional terminal
emulators. As per the Zutty post, I use &lt;a href=&#34;https://invisible-island.net/vttest/&#34;&gt;VTTEST&lt;/a&gt; (originally written in
1983-1985 by Per Lindberg at the Stockholm University Computing
Center; in 1996 a new version written by Thomas E. Dickey, the
maintainer of &lt;a href=&#34;https://en.wikipedia.org/wiki/Xterm&#34;&gt;xterm&lt;/a&gt;). to check for reported VT support level. The
below table includes also whether the terminal emulator is
GPU-accelerated or not, and what the mininum &lt;a href=&#34;https://en.wikipedia.org/wiki/OpenGL&#34;&gt;OpenGL&lt;/a&gt; hardware support
is, as well as what display server is targeted (&lt;a href=&#34;https://en.wikipedia.org/wiki/X11&#34;&gt;X11&lt;/a&gt; or &lt;a href=&#34;https://en.wikipedia.org/wiki/Wayland_(display_server_protocol)&#34;&gt;Wayland&lt;/a&gt; or
both).&lt;/p&gt;
&lt;p&gt;(&lt;strong&gt;Nb.&lt;/strong&gt;: see &lt;a href=&#34;./#note-on-gnome-terminal&#34;&gt;note on gnome-terminal and VT-capability&lt;/a&gt;.)&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;program&lt;/th&gt;
&lt;th&gt;tested version&lt;/th&gt;
&lt;th&gt;VT self-id&lt;/th&gt;
&lt;th&gt;GPU-accel&lt;/th&gt;
&lt;th&gt;minimum OpenGL&lt;/th&gt;
&lt;th&gt;DS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;zutty&lt;/td&gt;
&lt;td&gt;0.6&lt;/td&gt;
&lt;td&gt;VT520&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;ES 3.1&lt;/td&gt;
&lt;td&gt;X11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;terminology&lt;/td&gt;
&lt;td&gt;1.12.1&lt;/td&gt;
&lt;td&gt;VT510&lt;/td&gt;
&lt;td&gt;when possible&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;X11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wezterm&lt;/td&gt;
&lt;td&gt;20220624&lt;/td&gt;
&lt;td&gt;VT500&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;3.3 (?)&lt;/td&gt;
&lt;td&gt;both&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;xterm&lt;/td&gt;
&lt;td&gt;344&lt;/td&gt;
&lt;td&gt;VT420&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;X11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kitty&lt;/td&gt;
&lt;td&gt;0.19.3&lt;/td&gt;
&lt;td&gt;VT220&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;3.3&lt;/td&gt;
&lt;td&gt;both&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;foot&lt;/td&gt;
&lt;td&gt;1.12.1&lt;/td&gt;
&lt;td&gt;VT220&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;wayland&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;alacritty&lt;/td&gt;
&lt;td&gt;0.4.3&lt;/td&gt;
&lt;td&gt;VT102&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;3.3&lt;/td&gt;
&lt;td&gt;both&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;st&lt;/td&gt;
&lt;td&gt;0.8.2&lt;/td&gt;
&lt;td&gt;VT102&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;X11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;urxt&lt;/td&gt;
&lt;td&gt;v9.22&lt;/td&gt;
&lt;td&gt;VT102&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;X11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(lib)vterm&lt;/td&gt;
&lt;td&gt;0.1.4&lt;/td&gt;
&lt;td&gt;VT100/VT102&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gnome-terminal&lt;/td&gt;
&lt;td&gt;3.48.3&lt;/td&gt;
&lt;td&gt;VT510?(see &lt;a href=&#34;./#note-on-gnome-terminal&#34;&gt;note&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;no?&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;both&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;a href=&#34;https://codeberg.org/dnkl/foot&#34;&gt;Foot&lt;/a&gt; is another interesting new terminal emulator - targetting Wayland
only, and not GPU-accelerated, but with some design choices that make
it faster than GPU-accelerated terminal emulators in some cases, as
described in the wiki &lt;a href=&#34;https://codeberg.org/dnkl/foot/wiki/Performance&#34;&gt;&amp;ldquo;When is foot fast, and when is it not?&amp;quot;&lt;/a&gt;. One of
the things it does is &amp;ldquo;damage tracking&amp;rdquo;, i.e. only rendering cells
that have been updated, whereas e.g. alacritty rerenders everything
(though, as noted, &amp;ldquo;Alacritty renders empty cells really fast&amp;rdquo;). But
foot only supports up to VT220 (though alacritty only up to VT102!).&lt;/p&gt;
&lt;p&gt;The terminal emulator I end up using most is based on &lt;a href=&#34;https://www.leonerd.org.uk/code/libvterm/&#34;&gt;libvterm&lt;/a&gt;, this
is the library underlying Emacs&amp;rsquo; vterm, and claims to &amp;ldquo;implement[] a
VT220 or xterm-like terminal emulator&amp;rdquo;, but VTTEST seems to report as
VT102/VT100, at least inside of Emacs.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s no clear &amp;ldquo;best choice&amp;rdquo; here, even putting vterm aside (vterm
isn&amp;rsquo;t particularly fast, at least inside of Emacs (though it&amp;rsquo;s faster
than other Emacs terminal emulator choices like &lt;code&gt;ansi-term&lt;/code&gt;), doesn&amp;rsquo;t
have &amp;ldquo;very high&amp;rdquo; VT support; but it runs inside in Emacs, which offers
me a lot of advantages). Though alacritty, &lt;a href=&#34;https://st.suckless.org/&#34;&gt;st&lt;/a&gt;, and &lt;a href=&#34;https://en.wikipedia.org/wiki/Rxvt&#34;&gt;urxvt&lt;/a&gt; implement
only up to VT102 level features.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://codeberg.org/dnkl/foot&#34;&gt;Foot&lt;/a&gt;, &lt;a href=&#34;https://tomscii.sig7.se/zutty/&#34;&gt;Zutty&lt;/a&gt;, &lt;a href=&#34;https://sw.kovidgoyal.net/kitty/&#34;&gt;Kitty&lt;/a&gt;, and &lt;a href=&#34;https://github.com/alacritty/alacritty&#34;&gt;Alacritty&lt;/a&gt; are all fast, at least sometimes
(the Zutty biased comparison post above offers some additional
discussion on this, not including foot). They&amp;rsquo;re all limited in
various ways (hardware or display server - though Zutty apparently has
&lt;a href=&#34;https://github.com/tomszilagyi/zutty/wiki/FAQ&#34;&gt;experimental support for software rendering&lt;/a&gt;), with only Zutty having
&amp;ldquo;very high&amp;rdquo; VT support. (And Zutty has some &lt;a href=&#34;https://github.com/tomszilagyi/zutty/wiki/FAQ&#34;&gt;bells-and-whistles
limitations&lt;/a&gt;: no plans for transparency support, ligatures, bitmap
images (e.g. &lt;a href=&#34;https://en.wikipedia.org/wiki/Sixel&#34;&gt;SIXEL&lt;/a&gt;).)&lt;/p&gt;
&lt;p&gt;Foot runs on pretty much any hardware and has some nice features, but
is Wayland only (and limited in VT level support).&lt;/p&gt;
&lt;p&gt;Kitty and Alacritty require OpenGL 3.3 (on Intel hardware, this means
at least Intel HD Graphics 3000 (so 2011-era **20 ThinkPads or
later)).&lt;/p&gt;
&lt;p&gt;Zutty &amp;ldquo;runs on a wider range of graphics hardware by virtue of only
requiring &lt;a href=&#34;https://en.wikipedia.org/wiki/OpenGL_ES&#34;&gt;OpenGL ES&lt;/a&gt; as opposed to “desktop” OpenGL, and its resource
demands are otherwise minimal&amp;rdquo;, but it requires ES 3.1, which isn&amp;rsquo;t
supported by, for instance, Intel HD Graphics 3000.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/borisfaure/terminology&#34;&gt;Terminology&lt;/a&gt;, a terminal emulator which doesn&amp;rsquo;t seem to get talked
about as much, actually turns out to be a good choice across different
hardware. It can use GPU-acceleration, rendering using OpenGL or
OpenGL-ES2, but this is not a hard requirement. It offers VT510 level
support, and has lots of bells and whistles. I haven&amp;rsquo;t seen many speed
test comparisons with it, but in use it feels fast. (No native Wayland
support though, if that matters to you.)&lt;/p&gt;
&lt;h2 id=&#34;note-on-gnome-terminal&#34;&gt;Note on gnome-terminal:&lt;/h2&gt;
&lt;p&gt;gnome-terminal &lt;a href=&#34;https://tomscii.sig7.se/zutty/test/output/gnome-terminal/vt_06_04.png&#34;&gt;used to self-report &amp;ldquo;VT525&amp;rdquo;&lt;/a&gt; in VTTEST (back in 2022,
with v3.30.2), but self-described as VT220-compatible. But now (2025,
v.3.48.3) seems to self-report as &amp;ldquo;VT100&amp;rdquo;. [Actually, I&amp;rsquo;m wrong about
this. Or, it&amp;rsquo;s complicated: it says &amp;ldquo;VT100&amp;rdquo; family on one screen, and
&amp;ldquo;VT510&amp;rdquo; on another.]&lt;/p&gt;
&lt;p&gt;The Zutty post we&amp;rsquo;ve been talking about &lt;a href=&#34;https://tomscii.sig7.se/2020/12/A-totally-biased-comparison-of-Zutty#gnome-terminal&#34;&gt;identifies a whole host of
bugs in gnome-terminal&lt;/a&gt; and comments:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[&amp;hellip;there&amp;rsquo;s] &lt;em&gt;a steaming pile of bugs&lt;/em&gt; in various problem areas, some of
them pretty basic (such as TAB handling). Horizontal margins (VT420
and above) seem to be completely unsupported, as well as various other
sequences from VT420, VT520 and ISO-6429 (ECMA-48) – not entirely sure
if the latter is in scope. Overall, a puzzling outcome!&lt;/p&gt;
&lt;p&gt;Digging a bit further, I discovered some ambiguity on whether
gnome-terminal supports the claimed VT520 level at all: its &lt;a href=&#34;https://www.systutorials.com/docs/linux/man/1-gnome-terminal/&#34;&gt;manpage&lt;/a&gt;
(not organic to the project, but contributed by Debian) has this to
say about the support level of gnome-terminal: &lt;code&gt;Run any application that is designed to run on VT102, VT220, and xterm terminals.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That is pretty sloppy as far as specifications go. Apparently, it
might be the case that nothing above VT220 is intentionally supported
by gnome-terminal at all, and that its primary device attributes
&lt;a href=&#34;https://tomscii.sig7.se/zutty/test/output/gnome-terminal/vt_06_04.png&#34;&gt;response&lt;/a&gt; is a &lt;em&gt;big fat lie&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Tom (of Zutty) refers to the &lt;a href=&#34;https://invisible-island.net/xterm/xterm.faq.html#bug_gnometerm&#34;&gt;xterm-faq&amp;rsquo;s page on gnome-terminal&lt;/a&gt; (and
gnome-terminal&amp;rsquo;s underlying &lt;a href=&#34;https://wiki.gnome.org/Apps/Terminal/VTE&#34;&gt;VTE terminal widget library&lt;/a&gt;) as well,
which documents extensive issues with gnome-terminal (and VTE) from
1999 onwards, summarising:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Unless specifically mentioned, GNOME Terminal and VTE&amp;rsquo;s issues
generally accumulate, with occasional veering off with skin-deep
“rewrites”. Each sighting provides a new episode.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But now (06 Nov 2025: gnome-terminal v3.48.3) it seems to only
self-report in VTTEST as &amp;ldquo;VT100 family&amp;rdquo; in [4.] Primary Device
Attributes (DA):&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;Report is: &amp;lt;27&amp;gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; ? &lt;span class=&#34;m&#34;&gt;6&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;8&lt;/span&gt; c  VT100 family
    &lt;span class=&#34;nv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;132&lt;/span&gt; columns
    &lt;span class=&#34;nv&#34;&gt;21&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; horizontal scrolling
    &lt;span class=&#34;nv&#34;&gt;22&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; color
    &lt;span class=&#34;nv&#34;&gt;28&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; rectangular editing
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But as &amp;ldquo;VT510&amp;rdquo; in [5.] Secondary Device Attributes (DA):&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;Testing Secondary Device Attributes &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;Firmware version&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;

          &amp;lt;27&amp;gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &amp;gt; &lt;span class=&#34;m&#34;&gt;6&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;8&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; c
         &lt;span class=&#34;nv&#34;&gt;Pp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;61&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;VT510&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;nv&#34;&gt;Pv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;7802, firmware version 780.2
         &lt;span class=&#34;nv&#34;&gt;Pc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1, ROM cartridge registration number ok
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;update-10-july-2022&#34;&gt;Update: 10 July 2022:&lt;/h2&gt;
&lt;p&gt;Added &lt;a href=&#34;https://wezfurlong.org/wezterm/&#34;&gt;WezTerm&lt;/a&gt; (another one written in Rust) which I haven&amp;rsquo;t really had
a chance to play with much, but it has good VT feature levels. It
seems to have the same OpenGL requirements as Kitty or Alacritty. This
seems a very good choice overall, with a lot of cool features,
including implementing Kitty&amp;rsquo;s display of images in terminal protocol
(along with iTerm2&amp;rsquo;s image display protocol), and
scripting/extensibility in Lua.&lt;/p&gt;
&lt;h2 id=&#34;update-06-nov-2025&#34;&gt;Update: 06 Nov 2025:&lt;/h2&gt;
&lt;p&gt;Should really add &lt;a href=&#34;https://ghostty.org&#34;&gt;Ghostty&lt;/a&gt; at some point (and update things in
general), which I was trying out for a while, but recent versions of
Ghostty require higher OpenGL-capable hardware than most of my
machines have.&lt;/p&gt;
&lt;p&gt;(Added &lt;a href=&#34;./#note-on-gnome-terminal&#34;&gt;above note on gnome-terminal&lt;/a&gt; as well.)&lt;/p&gt;
&lt;h2 id=&#34;update-21-dec-2025&#34;&gt;Update: 21 Dec 2025:&lt;/h2&gt;
&lt;p&gt;Updated corrections about gnome-terminal&amp;rsquo;s two differing reports
(VT100-family in primary attributes, but VT510 in secondary
attributes).&lt;/p&gt;
&lt;p&gt;Noticed a &amp;ldquo;new&amp;rdquo; terminal emulator, &lt;a href=&#34;https://gitlab.gnome.org/chergert/ptyxis&#34;&gt;ptyxis&lt;/a&gt;, when using a Fedora Atomic
spin. And, indeed, it bills itself as a &amp;ldquo;terminal for a
container-oriented desktop&amp;rdquo;. It seems to report like gnome-terminal,
which makes sense as they&amp;rsquo;re both really using Gnome&amp;rsquo;s VTE (discussed above).&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/terminals">terminals</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/terminal-emulator-vtt-features-compatibility/</guid>
                <pubDate>Tue, 28 Jun 2022 16:57:00 -0500</pubDate>
            </item>
        
            
            <item>
                <title>Towards a history of Quake-style drop-down terminals</title>
                <link>https://babbagefiles.xyz/quake-drop-down-terminal-history/</link>
                
                
                <description>&lt;p&gt;Continued work on fooling Emacs into behaving like a drop-down console
(i.e. &lt;a href=&#34;https://babbagefiles.xyz/categories/equake/&#34;&gt;Equake&lt;/a&gt;), set me to thinking about the development of
Quake-style drop-down terminals.&lt;/p&gt;
&lt;p&gt;The frequent label &amp;ldquo;Quake-style&amp;rdquo; does seem to suggest at least part of
the origin in the computer game &lt;a href=&#34;https://en.wikipedia.org/wiki/Quake_(video_game)&#34;&gt;Quake&lt;/a&gt; (1996), or at least that the drop-down console in
Quake was the most prominent/remembered example of this sort of UI.[&lt;span class=&#34;org-target&#34; id=&#34;org-target--ddt0t&#34;&gt;&lt;/span&gt;&lt;a href=&#34;#org-target--ddt0b&#34;&gt;0&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;On Linux/Unix, a number of terminal emulators have been designed with
Quake-style drop-down interaction, and other platforms now seem to
have these as well. As far as I can tell, drop-down terminal emulators
first appeared on Linux, and probably in the early 2000s. (Though I
wonder about this, both the KDE project started in 1996 (same year as
Quake) and the GNOME project shortly after and it almost feels like
someone must have thought about doing something of this sort between
1996-2000.)&lt;/p&gt;
&lt;p&gt;The earliest surviving drop-down terminals on Linux seem to be
&lt;a href=&#34;https://github.com/KDE/yakuake&#34;&gt;Yakuake&lt;/a&gt; (QT/KDE), &lt;a href=&#34;https://github.com/lanoxx/tilda&#34;&gt;Tilda&lt;/a&gt; (GTK), and &lt;a href=&#34;https://github.com/Guake/guake&#34;&gt;Guake&lt;/a&gt; (GTK).&lt;/p&gt;
&lt;p&gt;Yakuake seems to have been released in the early 2000s, certainly by
2005[&lt;span class=&#34;org-target&#34; id=&#34;org-target--ddt1t&#34;&gt;&lt;/span&gt;&lt;a href=&#34;#org-target--ddt1b&#34;&gt;1&lt;/a&gt;], but perhaps a bit earlier. Tilda was released by 2006[&lt;span class=&#34;org-target&#34; id=&#34;org-target--ddt2t&#34;&gt;&lt;/span&gt;&lt;a href=&#34;#org-target--ddt2b&#34;&gt;2&lt;/a&gt;]. Guake
was explicitly inspired by the original author seeing
Yakuake[&lt;span class=&#34;org-target&#34; id=&#34;org-target--ddt3t&#34;&gt;&lt;/span&gt;&lt;a href=&#34;#org-target--ddt3b&#34;&gt;3&lt;/a&gt;], itself being released in 2007.&lt;/p&gt;
&lt;p&gt;But &amp;ldquo;Yakuake&amp;rdquo; stands for &amp;ldquo;yet another Kuake&amp;rdquo;, and indeed the earliest
drop-down terminal I can find on Linux is &lt;a href=&#34;https://web.archive.org/web/20040219101722/http://www.nemohackers.org/kuake.php&#34;&gt;Kuake&lt;/a&gt;, released probably by 2003,
with the last update in 2004[&lt;span class=&#34;org-target&#34; id=&#34;org-target--ddt4t&#34;&gt;&lt;/span&gt;&lt;a href=&#34;#org-target--ddt4b&#34;&gt;4&lt;/a&gt;].&lt;/p&gt;
&lt;p&gt;Happy to hear about further history of early drop-down Quake-style
terminals on any platform.&lt;/p&gt;
&lt;p&gt;[&lt;span class=&#34;org-target&#34; id=&#34;org-target--ddt0b&#34;&gt;&lt;/span&gt;&lt;a href=&#34;#org-target--ddt0t&#34;&gt;0&lt;/a&gt;] &lt;a href=&#34;https://en.wikipedia.org/wiki/Console_(computer_games)&#34;&gt;https://en.wikipedia.org/wiki/Console_(computer_games)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;span class=&#34;org-target&#34; id=&#34;org-target--ddt1b&#34;&gt;&lt;/span&gt;&lt;a href=&#34;#org-target--ddt1t&#34;&gt;1&lt;/a&gt;] &lt;a href=&#34;https://web.archive.org/web/20051016011941/http://yakuake.uv.ro/&#34;&gt;https://web.archive.org/web/20051016011941/http://yakuake.uv.ro/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;span class=&#34;org-target&#34; id=&#34;org-target--ddt2b&#34;&gt;&lt;/span&gt;&lt;a href=&#34;#org-target--ddt2t&#34;&gt;2&lt;/a&gt;] &lt;a href=&#34;https://web.archive.org/web/20061028182927/http://tilda.sourceforge.net/wiki/index.php/Main_Page&#34;&gt;https://web.archive.org/web/20061028182927/http://tilda.sourceforge.net/wiki/index.php/Main_Page&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;span class=&#34;org-target&#34; id=&#34;org-target--ddt3b&#34;&gt;&lt;/span&gt;&lt;a href=&#34;#org-target--ddt3t&#34;&gt;3&lt;/a&gt;] &lt;a href=&#34;https://news.ycombinator.com/item?id=22524552&#34;&gt;https://news.ycombinator.com/item?id=22524552&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;span class=&#34;org-target&#34; id=&#34;org-target--ddt4b&#34;&gt;&lt;/span&gt;&lt;a href=&#34;#org-target--ddt4t&#34;&gt;4&lt;/a&gt;]
&lt;a href=&#34;https://web.archive.org/web/20040219101722/http://www.nemohackers.org/kuake.php&#34;&gt;https://web.archive.org/web/20040219101722/http://www.nemohackers.org/kuake.php&lt;/a&gt;&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/terminals">terminals</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/quake-drop-down-terminal-history/</guid>
                <pubDate>Sun, 26 Jun 2022 20:19:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Dealing with possessed TrackPoints on later model ThinkPads</title>
                <link>https://babbagefiles.xyz/possessed-trackpoint/</link>
                
                
                <description>&lt;p&gt;On a new-to-me ThinkPad T440p, I&amp;rsquo;ve had the worst time with the
TrackPoint.&lt;/p&gt;
&lt;p&gt;First, the stock configuration has a horrible touchpad -
which shouldn&amp;rsquo;t matter if you don&amp;rsquo;t use the touchpad, but the
horribleness of it is that the physical buttons that should be on the
top of the touchpad, and are on the touchpads of models preceding and
following the **40 line, are not there. But one &lt;a href=&#34;https://octoperf.com/blog/2018/11/07/thinkpad-t440p-buyers-guide/#trackpad&#34;&gt;can replace it&lt;/a&gt;, and so
I did.&lt;/p&gt;
&lt;p&gt;The T440p is nice in that servicing the fan and other internals of the
machine is a relatively easy affair compared to say an X230. Just undo
two screws on the bottom of the laptop and slide off the back panel,
and you have access to memory, drives, the CPU, and so on. And so
swapping in a different CPU was really easy and painless.&lt;/p&gt;
&lt;p&gt;On the other hand, changing the touchpad was a very involved
affair. But it &lt;a href=&#34;https://www.youtube.com/watch?v=7wM4Kqdy3_E&#34;&gt;can be done&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, still the mouse-cursor experience for the machine continued
to be horrible. Firstly, there was significant &amp;ldquo;drift&amp;rdquo; of the
TrackPoint. I.e., even once pressure is released, it keeps moving, for
a long time.&lt;/p&gt;
&lt;p&gt;However, this ends up being solvable via&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;sudo -s &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;  &lt;span class=&#34;s1&#34;&gt;&amp;#39;ACTION==&amp;#34;add&amp;#34;,SUBSYSTEM==&amp;#34;input&amp;#34;,ATTR{name}==&amp;#34;TPPS/2 IBM TrackPoint&amp;#34;,ATTR{device/drift_time}=&amp;#34;30&amp;#34;&amp;#39;&lt;/span&gt;  &amp;gt; /etc/udev/rules.d/10-trackpoint.rules
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(If you&amp;rsquo;re trying to do this in Guix, something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;define &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;%trackpoint-drift-rule&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;udev-rule&lt;/span&gt;
    &lt;span class=&#34;s&#34;&gt;&amp;#34;10-trackpoint.rules&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;string-append &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ACTION==\&amp;#34;add\&amp;#34;,SUBSYSTEM==\&amp;#34;input\&amp;#34;,ATTR{name}==\&amp;#34;TPPS/2 IBM TrackPoint\&amp;#34;,ATTR{device/drift_time}=\&amp;#34;25\&amp;#34;&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;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;define &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;%my-desktop-services&lt;/span&gt;
   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cons &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;udev-rules-service&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;trackpoint-drift&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;%trackpoint-drift-rule&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;modify-services&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;%desktop-services&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;c1&#34;&gt;; other modifications here&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;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;operating-system&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;nf&#34;&gt;services&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;list&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;service&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;openssh-service-type&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;service&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;cups-service-type&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;service&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;nix-service-type&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;nv&#34;&gt;%my-desktop-services&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;instead.)&lt;/p&gt;
&lt;p&gt;But, unfortunately, this doesn&amp;rsquo;t solve what is actually the most horrible issue:
the mouse cursor sometimes, when in use, just teleports around the edges
of the screen and starts randomly clicking on things.&lt;/p&gt;
&lt;p&gt;I finally turned up some discussion of this issue (though not for the
T440p specifically) at: &lt;a href=&#34;https://bugzilla.kernel.org/show_bug.cgi?format=multiple&amp;amp;id=209167&#34;&gt;https://bugzilla.kernel.org/show_bug.cgi?format=multiple&amp;amp;id=209167&lt;/a&gt;
(The discussion suggests that it should somehow be solved in the
kernel, but that is not my experience, even running kernel 5.17.13.)&lt;/p&gt;
&lt;p&gt;And found that adding &lt;code&gt;psmouse.proto=imps&lt;/code&gt; to the kernel arguments and
disabling the touchpad in the stock BIOS solves the &amp;ldquo;possessed mouse
cursor&amp;rdquo; issue. For better or worse, it seem to make the TrackPoint be
detected as a generic PS/2 mouse. Which means that &lt;code&gt;drift_time&lt;/code&gt; can no
longer be set, and I do get a little bit of drift from time to time,
but it&amp;rsquo;s not too bad and certainly is far less maddening than the
&amp;ldquo;possessed mouse cursor&amp;rdquo; behaviour.&lt;/p&gt;
&lt;p&gt;For Guix, the way to implement this is something along the lines of:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;operating-system&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;nf&#34;&gt;kernel-arguments&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;s&#34;&gt;&amp;#34;modprobe.blacklist=pcspkr,snd_pcsp&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;psmouse.proto=imps&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;acpi_osi=Linux&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;%default-kernel-arguments&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;(The other kernel arguments are simply the other ones I use, and are
not directly connected with this issue.)&lt;/p&gt;
&lt;p&gt;Depending on the model of ThinkPad and/or the environment, using
&lt;code&gt;psmouse.proto=bare&lt;/code&gt; instead may work better (see discussion at:
&lt;a href=&#34;https://www.reddit.com/r/thinkpad/comments/v7vn0o/thinkpad_t440p_trackpoint_occasionally_going_crazy/icjkk0o/&#34;&gt;https://www.reddit.com/r/thinkpad/comments/v7vn0o/thinkpad_t440p_trackpoint_occasionally_going_crazy/icjkk0o/&lt;/a&gt;
).&lt;/p&gt;
&lt;p&gt;So, perhaps not an entirely satisfactory solution, this impish
exorcism, but better than alternatives.&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/thinkpad">thinkpad</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/linux">linux</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/guix">guix</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/possessed-trackpoint/</guid>
                <pubDate>Sat, 18 Jun 2022 19:51:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Equake: A Geas on Gnomish Smiths</title>
                <link>https://babbagefiles.xyz/equake-geas-on-gnomish-smiths/</link>
                
                
                <description>&lt;p&gt;A new version of &lt;a href=&#34;https://gitlab.com/emacsomancer/equake&#34;&gt;Equake&lt;/a&gt;, the drop-down &amp;ldquo;terminal emulator&amp;rdquo; for Emacs, should be hitting Melpa shortly. This version includes a number of bug fixes, and some new features.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/jeffkowalski&#34;&gt;Jeff Kowalski&lt;/a&gt; added code for a &lt;a href=&#34;https://gitlab.com/emacsomancer/equake/-/merge_requests/8&#34;&gt;&amp;ldquo;close Equake frame on loss of focus
feature&amp;rdquo;&lt;/a&gt; (similar to the &lt;a href=&#34;https://github.com/lanoxx/tilda&#34;&gt;Tilda&lt;/a&gt; feature) and a number of bug fixes and code-cleanup.&lt;/p&gt;
&lt;p&gt;Further: I&amp;rsquo;m (half-)jokingly calling this the &lt;strong&gt;Geas on Gnomish Smiths&lt;/strong&gt; release as I&amp;rsquo;ve finally figured out how to make it behave properly under GNOME Shell Wayland.&lt;/p&gt;
&lt;p&gt;To my knowledge, the only other currently working drop-down terminal
for GNOME Shell Wayland is the JavaScript GNOME extension
&lt;a href=&#34;https://github.com/amezin/gnome-shell-extension-ddterm&#34;&gt;ddterm&lt;/a&gt;. Wayland (at least GNOME Shell&amp;rsquo;s Wayland) seems very
restrictive in how non-user-initiated events can affect window
properties. E.g., it is difficult to programmatically affect window focus in GNOME Shell under Wayland. The default &amp;ldquo;hide window&amp;rdquo; behaviour of Equake doesn&amp;rsquo;t work.&lt;/p&gt;
&lt;p&gt;However, I did have a legacy feature where closing/hiding Equake involved destroying the frame rather than hiding it. This is somewhat complicated, as re-invoking Equake then involves creating a new frame and restoring the tabs and buffer history. This is how Equake originally worked, but it is simpler (and slightly faster) just to hide the frame on &amp;ldquo;close&amp;rdquo; and then unhide it on &amp;ldquo;re-open&amp;rdquo;, and this became the default behaviour for Equake some time ago. But I left the old code in place as another option.&lt;/p&gt;
&lt;p&gt;However, various changes apparently ended up with the restoration behaviour not working quite properly. I have fixed this (more or less, see &lt;a href=&#34;https://gitlab.com/emacsomancer/equake/-/issues/26&#34;&gt;https://gitlab.com/emacsomancer/equake/-/issues/26&lt;/a&gt;). With that fix in place, we can then trick GNOME Shell under Wayland into behaving properly. Rather than hiding the Equake frame on &amp;ldquo;close&amp;rdquo;, we destroy it and then recreate it on &amp;ldquo;open&amp;rdquo;. This involves quite a bit of trickery behind the scenes. Essentially, opening a new window under GNOME Shell Wayland can result in that window being placed on top of any existing windows (though to do it properly, employing a it of Elisp &lt;code&gt;(select-frame-set-input-focus (selected-frame))&lt;/code&gt; seems to result in the new Emacs client frame being on top (and focussed) [this is a potentially useful trick for opening regular new Emacsclient frames as well].&lt;/p&gt;
&lt;p&gt;But, the usual way that Equake frames are created internally is via
Emacs &lt;code&gt;make-frame&lt;/code&gt;, which doesn&amp;rsquo;t automatically focus the new
frame. So rather than doing this, we need to have the user call &lt;code&gt;emacsclient -c&lt;/code&gt; and then transform that frame into an Equake frame. A new Equake function &lt;code&gt;equake--transform-existing-frame-into-equake-frame&lt;/code&gt; takes care of this. The transformation and the old code restoring tabs and history doesn&amp;rsquo;t quite take care of everything though as the point/cursor is left by default at the top of the frame, which is not the user-expected behaviour. So an addition bit of elisp &lt;code&gt;(goto-char (1- (point-max)))&lt;/code&gt; generally moves the point/cursor to the end of the buffer where the user might expect it.&lt;/p&gt;
&lt;p&gt;So I have a bit of shell script as a helper function which is what one should create a keybinding for in GNOME Shell Wayland:&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;
&lt;span class=&#34;nv&#34;&gt;equakestatus&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;emacsclient -n -e &lt;span class=&#34;s1&#34;&gt;&amp;#39;(frame-live-p (alist-get (equake--get-monitor) equake--frame))&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&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;$equakestatus&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;nil&amp;#34;&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;k&#34;&gt;then&lt;/span&gt;
    emacsclient -c -e &lt;span class=&#34;s2&#34;&gt;&amp;#34;(progn (select-frame-set-input-focus (selected-frame))
&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;                              (equake--transform-existing-frame-into-equake-frame)
&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;                              (goto-char (1- (point-max))))&amp;#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
    emacsclient -n -e &lt;span class=&#34;s1&#34;&gt;&amp;#39;(progn (setq equake-use-frame-hide nil)
&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;                              (equake-invoke))&amp;#39;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This checks if there is a live Equake frame; if there is, it is hidden; otherwise a new frame is created and transformed.&lt;/p&gt;
&lt;p&gt;Finally, in order to be able to get the &amp;ldquo;Always on Top&amp;rdquo; behaviour, the new Equake frame transmutation function calls &lt;code&gt;(shell-command &amp;quot;wmctrl -r :ACTIVE: -b toggle,above&amp;quot;)&lt;/code&gt; (so one needs &lt;code&gt;wmctrl&lt;/code&gt; installed), which seems to trigger the &amp;ldquo;Always on Top&amp;rdquo; feature at least for Xwayland windows.&lt;/p&gt;
&lt;p&gt;And, presto, change-o, voilà, we have a version of Equake which
exhibits its normal X11 behaviour in GNOME Shell Wayland.&lt;/p&gt;
&lt;p&gt;(As long as Emacs is run as an Xwayland application; otherwise the
&amp;ldquo;always on top&amp;rdquo; behaviour doesn&amp;rsquo;t work properly.)&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/equake">equake</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/elisp">elisp</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/eshell">eshell</category>
                                
                            
                        
                     
                        
                     
                        
                    
                
                <guid>https://babbagefiles.xyz/equake-geas-on-gnomish-smiths/</guid>
                <pubDate>Wed, 08 Jun 2022 10:54:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Social network platforms (IRC, Matrix, Discord, Slack, and others)</title>
                <link>https://babbagefiles.xyz/tridactyl/</link>
                
                
                <description>&lt;p&gt;Following on the last post&lt;/p&gt;
&lt;h2 id=&#34;lisp&#34;&gt;Lisp&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Common Lisp:
&lt;ul&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!--listend--&gt;
&lt;ul&gt;
&lt;li&gt;Clojure: slack
&lt;ul&gt;
&lt;li&gt;Racket: slack&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/irc">irc</category>
                                
                            
                        
                     
                        
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/tags/socialmedia">socialmedia</category>
                                 
                                    <category domain="https://babbagefiles.xyz/tags/"></category>
                                
                            
                        
                    
                
                <guid>https://babbagefiles.xyz/tridactyl/</guid>
                <pubDate>Wed, 27 Oct 2021 14:22:23 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Automatically adding information to Org-roam file properties</title>
                <link>https://babbagefiles.xyz/org-roam-auto-propertise/</link>
                
                
                <description>&lt;p&gt;This expands on a feature I included in the setup for using &lt;a href=&#34;https://www.orgroam.com/&#34;&gt;Org-roam&lt;/a&gt;
on Android/LineageOS in the &lt;a href=&#34;../org-roam-on-android&#34;&gt;last post&lt;/a&gt;, specifically automatically
adding properties to newly created Org-roam files.&lt;/p&gt;
&lt;p&gt;Since Org-roam v2 creates a top properties drawer (with an &lt;code&gt;:ID:&lt;/code&gt; tag) anyway, it is nice to stick other information there as well. Specifically, information that could be useful in some situation, but which usually we don&amp;rsquo;t want to see, like &lt;code&gt;:AUTHOR:&lt;/code&gt; (it&amp;rsquo;s probably you, and you know who you are), &lt;code&gt;:CREATION_TIME:&lt;/code&gt; (and why not use Unix epoch time?), and so on. I have org drawers fold themselves automatically, so the normally-useless information doesn&amp;rsquo;t distract me.&lt;/p&gt;
&lt;p&gt;We can do this by leveraging Org-roam&amp;rsquo;s &lt;code&gt;org-roam-capture-new-node-hook&lt;/code&gt;, and some &lt;code&gt;org-roam-add-property&lt;/code&gt; function calls, as below.&lt;/p&gt;
&lt;p&gt;But, while we&amp;rsquo;re at it, we might also record &lt;strong&gt;where&lt;/strong&gt; a note was made from. There are a number of ways we might do this, but an easy one (only requiring &lt;code&gt;curl&lt;/code&gt; and an active Internet connection) is using &lt;a href=&#34;https://ipinfo.io/developers/data-types#geolocation-data&#34;&gt;ipinfo.io&lt;/a&gt;. &lt;code&gt;curl ipinfo.io&lt;/code&gt; will give you a bunch of information in JSON format about your internet provider, including latitude and longitude, which will likely be at least somewhere &lt;strong&gt;near&lt;/strong&gt; your present location. And &lt;code&gt;curl ipinfo.io/loc&lt;/code&gt; will return just latitude,longitude.&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;bms/add-other-auto-props-to-org-roam-properties&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;;; if the file already exists, don&amp;#39;t do anything, otherwise...&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;nf&#34;&gt;file-exists-p&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;buffer-file-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
      &lt;span class=&#34;c1&#34;&gt;;; if there&amp;#39;s also a CREATION_TIME property, don&amp;#39;t modify it&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;nv&#34;&gt;org-find-property&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;CREATION_TIME&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;;; otherwise, add a Unix epoch timestamp for CREATION_TIME prop&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;;; (this is what &amp;#34;%s&amp;#34; does - see http://doc.endlessparentheses.com/Fun/format-time-string )&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-roam-add-property&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format-time-string&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;%s&amp;#34;&lt;/span&gt;
                             &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nth&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;nf&#34;&gt;file-attributes&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;buffer-file-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
         &lt;span class=&#34;s&#34;&gt;&amp;#34;CREATION_TIME&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
      &lt;span class=&#34;c1&#34;&gt;;; similarly for AUTHOR and MAIL properties&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;nv&#34;&gt;org-find-property&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;AUTHOR&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;org-roam-add-property&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;roam-user&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;AUTHOR&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;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-find-property&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;MAIL&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;org-roam-add-property&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;roam-email&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;MAIL&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
      &lt;span class=&#34;c1&#34;&gt;;; also add the latitude and longitude&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;nv&#34;&gt;org-find-property&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;LAT_LONG&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;;; recheck location:&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bms/get-lat-long-from-ipinfo&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;org-roam-add-property&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;concat&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;number-to-string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calendar-latitude&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;nf&#34;&gt;number-to-string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calendar-longitude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;LAT-LONG&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; hook to be run whenever an org-roam capture completes&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;ss&#34;&gt;&amp;#39;org-roam-capture-new-node-hook&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bms/add-other-auto-props-to-org-roam-properties&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; function to find latitude &amp;amp; longitude&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;;                      (requires curl to be installed on system)&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;calendar-latitude&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;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calendar-longitude&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;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bms/get-lat-long-from-ipinfo&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;latlong&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;substring&lt;/span&gt;
                 &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command-to-string&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;curl -s &amp;#39;ipinfo.io/loc&amp;#39;&amp;#34;&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;-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;latlong-list&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;split-string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;latlong&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;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calendar-latitude&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;string-to-number&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;latlong-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;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calendar-longitude&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;string-to-number&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;latlong-list&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;You might also calculate/set &lt;code&gt;calendar-latitude&lt;/code&gt; and &lt;code&gt;calendar-longitude&lt;/code&gt; in other ways. Including just hard-coding them for stationary machines. On Android, we could in theory make use of the Termux command &lt;code&gt;termux-location&lt;/code&gt;, which queries the device&amp;rsquo;s GPS. But unfortunately it doesn&amp;rsquo;t always work (if it can&amp;rsquo;t find a good connection to a GPS satellite) and even when it does work it&amp;rsquo;s slow, so it&amp;rsquo;s not something you&amp;rsquo;d want to call every time you made a note. &lt;a href=&#34;https://gitlab.freedesktop.org/geoclue/geoclue/-/wikis/home&#34;&gt;GeoClue&lt;/a&gt; would be another possible source.&lt;/p&gt;
&lt;p&gt;(If you&amp;rsquo;re using a VPN, you&amp;rsquo;ll want to escape from it somehow to get something closer to your real location. How you do this will vary based on your VPN provider and other factors. (If you&amp;rsquo;re calling from Emacs, and you use something like Mullvad, you may want to revise the &lt;code&gt;shell-command-to-string&lt;/code&gt; to call up a bash session/script, then exclude that specific bash session/script from the VPN, and &lt;em&gt;then&lt;/em&gt; call &lt;code&gt;curl&lt;/code&gt;, so that the call references your &amp;ldquo;real&amp;rdquo; IP. E.g. if you&amp;rsquo;re using Mullvad, then:&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/bash
&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;
mullvad split-tunnel pid add &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
curl ipinfo.io/loc &lt;span class=&#34;c1&#34;&gt;# for lat/long ; `curl ipinfo.io` for full info&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;might give you a start on something.))&lt;/p&gt;
&lt;p&gt;Let me know if you think of other properties that could be useful to automatically add to Org-roam file properties.&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/org">org</category>
                                
                            
                        
                     
                        
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/tags/orgroam">orgroam</category>
                                
                            
                        
                    
                
                <guid>https://babbagefiles.xyz/org-roam-auto-propertise/</guid>
                <pubDate>Tue, 10 Aug 2021 21:12:00 -0600</pubDate>
            </item>
        
            
            <item>
                <title>Org-roam on Android</title>
                <link>https://babbagefiles.xyz/org-roam-on-android/</link>
                
                
                <description>&lt;p&gt;I&amp;rsquo;ve been using the note-taking &lt;a href=&#34;https://en.wikipedia.org/wiki/Zettelkasten&#34;&gt;Zettelkasten&lt;/a&gt;-ish &lt;a href=&#34;https://www.orgroam.com/&#34;&gt;Org-roam&lt;/a&gt; system for a
few months and it&amp;rsquo;s been very useful to me, just as a low-friction way
of making more notes and easily finding and/or (re)discovering notes
that I&amp;rsquo;ve made.&lt;/p&gt;



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

&lt;p&gt;It&amp;rsquo;s pretty useful to be able to have access to these notes, and be
able to quickly add notes, on mobile as well. I thought it might be
useful to include here some notes on how to do, since (especially
since &lt;a href=&#34;https://blog.jethro.dev/posts/org_roam_v2/&#34;&gt;v2 of Org-roam&lt;/a&gt;) there are some hurdles.&lt;/p&gt;
&lt;p&gt;On Android/LineageOS install the &lt;a href=&#34;https://f-droid.org/&#34;&gt;F-Droid app store&lt;/a&gt;, and then from
there install &lt;a href=&#34;https://f-droid.org/en/packages/com.termux/&#34;&gt;Termux&lt;/a&gt;. Open Termux and install four things we&amp;rsquo;ll need
(strictly speaking you don&amp;rsquo;t need curl and ripgrep, but they&amp;rsquo;ll
be useful): Emacs, sqlite, curl, and ripgrep via &lt;code&gt;pkg install emacs sqlite curl ripgrep&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can then open up Emacs via &lt;code&gt;emacs&lt;/code&gt; and get started.&lt;/p&gt;
&lt;p&gt;I include here a commented partial version of my &lt;code&gt;~/.emacs.d/init.el&lt;/code&gt;
configuration file for my Termux/Emacs Org-roam setup:&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;;; BASIC SETUP:&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; package setup - bootstrap the package system&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;package&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;package-enable-at-startup&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;gnutls-algorithm-priority&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;NORMAL:-VERS-TLS1.3&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;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;package-archives&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;s&#34;&gt;&amp;#34;GNU ELPA&amp;#34;&lt;/span&gt;     &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;https://elpa.gnu.org/packages/&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;s&#34;&gt;&amp;#34;ORG&amp;#34;&lt;/span&gt;		&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;https://orgmode.org/elpa/&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;s&#34;&gt;&amp;#34;MELPA Stable&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;https://stable.melpa.org/packages/&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;s&#34;&gt;&amp;#34;MELPA&amp;#34;&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;https://melpa.org/packages/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
      &lt;span class=&#34;nv&#34;&gt;package-archive-priorities&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;s&#34;&gt;&amp;#34;ORG&amp;#34;&lt;/span&gt;		&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20&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;MELPA&amp;#34;&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;15&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;MELPA Stable&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&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;GNU ELPA&amp;#34;&lt;/span&gt;     &lt;span class=&#34;o&#34;&gt;.&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;nv&#34;&gt;package-initialize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; Bootstrap `use-package&amp;#39;&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;nv&#34;&gt;package-installed-p&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;use-package&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;package-refresh-contents&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;package-install&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;use-package&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;eval-when-compile&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;use-package&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; for Termux-specific things; useful if you want to share&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; configs across platforms&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defvar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;termux-p&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;null&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;ANDROID_ROOT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;If non-nil, GNU Emacs is running on Termux.&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;when&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;termux-p&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;nv&#34;&gt;package-installed-p&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;use-package&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;package-refresh-contents&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;package-install&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;use-package&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; This makes Emacs in Termux use your Android browser for opening urls&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;browse-url-browser-function&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;browse-url-xdg-open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; mouse&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; enable mouse reporting for terminal emulators&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; this lets you scroll around by swiping&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;nf&#34;&gt;window-system&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;xterm-mouse-mode&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;global-set-key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mouse-4&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;nb&#34;&gt;interactive&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;scroll-down&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;global-set-key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mouse-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;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;nb&#34;&gt;interactive&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;scroll-up&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;;; ORG&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-plus-contrib&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:init&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;org-src-fontify-natively&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;nb&#34;&gt;:config&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (add-to-list &amp;#39;auto-mode-alist &amp;#39;(&amp;#34;\\.org\\&amp;#39;&amp;#34; . org-mode))&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-mode-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;M-p&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-metaup&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;define-key&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-mode-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;M-n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-metadown&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;org-catch-invisible-edits&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;show-and-error&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;org-cycle-separator-lines&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;org-return-follows-link&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;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-export-with-toc&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;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-startup-folded&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;content&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;org-ellipsis&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;c1&#34;&gt;;; **** use regular android apps to view pdfs &amp;amp; images *****&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;nv&#34;&gt;termux-p&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-to-list&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-file-apps&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;s&#34;&gt;&amp;#34;\\.pdf\\&amp;#39;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;termux-open %s&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-to-list&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-file-apps&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;s&#34;&gt;&amp;#34;\\.png\\&amp;#39;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;termux-open %s&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-to-list&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-file-apps&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;s&#34;&gt;&amp;#34;\\.jpg\\&amp;#39;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;termux-open %s&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-to-list&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-file-apps&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;s&#34;&gt;&amp;#34;\\.jpeg\\&amp;#39;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;termux-open %s&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; needed for &amp;lt;s etc. expansion of code-blocks&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-tempo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; define our Org-roam user and their email (set to your desired name/email)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defvar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;roam-user&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Some User&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;The name of the Org-roam note author.&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;defvar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;roam-email&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;roman@mode.org&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;The public email of that author.&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;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-v2-ack&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;c1&#34;&gt;;; we need this package for v2 of Org-oram&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;emacsql-sqlite3&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&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;c1&#34;&gt;;; If you&amp;#39;ve replicated my setup; otherwise change to the Termux&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; local path.&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;org-roam-directory&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file-truename&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;~/Documents/Org/org-roam/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; org-roam&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:custom&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;org-roam-db-location&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file-truename&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;org-roam-directory&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file-truename&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;~/Documents/Org/org-roam/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:bind&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;C-c n l&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-buffer-toggle&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;C-c n f&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-node-find&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;C-c n r&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-graph&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;C-c n i&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-node-insert&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;C-c n c&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-capture&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;C-c n g&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-id-get-create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
         &lt;span class=&#34;c1&#34;&gt;;; Dailies&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;C-c n n&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-dailies-capture-today&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;C-c n d&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-dailies-goto-today&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; find toDay&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;C-c n v&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-dailies-goto-date&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;C-c n f&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-dailies-goto-next-note&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;C-c n b&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-dailies-goto-previous-note&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; this is a chunglak&amp;#39;s hack to get sqlite to work on Android with org-roam v2:&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; from: https://github.com/org-roam/org-roam/issues/1605#issuecomment-885997237&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;org-roam-db&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;s&#34;&gt;&amp;#34;Entrypoint to the Org-roam sqlite database.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Initializes and stores the database, and the database connection.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Performs a database upgrade when required.&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;and&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-roam-db--get-connection&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;emacsql-live-p&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-roam-db--get-connection&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;init-db&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;file-exists-p&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-db-location&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;make-directory&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;file-name-directory&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-db-location&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;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;emacsql-sqlite3&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-db-location&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;emacsql&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;:pragma&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;foreign_keys&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;ON&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;set-process-query-on-exit-flag&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;emacsql-process&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;conn&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;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;puthash&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expand-file-name&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                   &lt;span class=&#34;nv&#34;&gt;conn&lt;/span&gt;
                   &lt;span class=&#34;nv&#34;&gt;org-roam-db--connection&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;nv&#34;&gt;init-db&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-roam-db--init&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;conn&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;version&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;caar&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;emacsql&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;PRAGMA user_version&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;version&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-roam-db--upgrade-maybe&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;version&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;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;version&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-db-version&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;emacsql-close&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;conn&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;ne&#34;&gt;user-error&lt;/span&gt;
               &lt;span class=&#34;s&#34;&gt;&amp;#34;The Org-roam database was created with a newer Org-roam version.  &amp;#34;&lt;/span&gt;
               &lt;span class=&#34;s&#34;&gt;&amp;#34;You need to update the Org-roam package&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;nf&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;version&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-db-version&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;emacsql-close&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;conn&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;ne&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;BUG: The Org-roam database scheme changed %s&amp;#34;&lt;/span&gt;
                     &lt;span class=&#34;s&#34;&gt;&amp;#34;and there is no upgrade 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;org-roam-db--get-connection&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;org-roam-db--init&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;s&#34;&gt;&amp;#34;Initialize database DB with the correct schema and user version.&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;emacsql-with-transaction&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;emacsql&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;PRAGMA foreign_keys = ON&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;;; added&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;emacsql&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;:pragma&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;foreign_keys&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;ON&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;pcase-dolist&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;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;schema&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-db--table-schemata&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;emacsql&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;:create-table&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$i1&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$S2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;schema&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;pcase-dolist&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;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;index-name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;columns&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-db--table-indices&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;emacsql&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;:create-index&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$i1&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:on&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$i2&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$S3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;index-name&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;columns&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;emacsql&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;PRAGMA user_version = %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-db-version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; end chunglak hack&lt;/span&gt;

  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-roam-setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; If using org-roam-protocol&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-roam-protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; These are my capture templates:&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;org-roam-capture-templates&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;&amp;#34;d&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;plain&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;%?&amp;#34;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:if-new&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file+head&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;%&amp;lt;%Y%m%d%H%M%S&amp;gt;-${slug}.org&amp;#34;&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;nf&#34;&gt;concat&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;#+title: ${title}\n&amp;#34;&lt;/span&gt;
                             &lt;span class=&#34;s&#34;&gt;&amp;#34;#+date: %U\n\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
         &lt;span class=&#34;nb&#34;&gt;:unnarrowed&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;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-dailies-directory&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;~/Documents/Org/org-roam/daily&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;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-dailies-capture-templates&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;&amp;#34;d&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;* %?&amp;#34;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:if-new&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file+head&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;%(concat org-roam-dailies-directory \&amp;#34;/%&amp;lt;%Y-%m-%d&amp;gt;.org\&amp;#34;)&amp;#34;&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;nf&#34;&gt;concat&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;#+title: %&amp;lt;%Y-%m-%d&amp;gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;
                             &lt;span class=&#34;s&#34;&gt;&amp;#34;#+filetags: :daily_journal:\n\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; deft - one way to search Org-roam notes, but not the fastest (see below)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;deft&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:after&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:bind&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;C-c r d&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;deft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:custom&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;deft-recursive&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;deft-use-filter-string-for-filename&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;deft-default-extension&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;org&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;deft-directory&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;~/Documents/Org/org-roam/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; Here end the basic setup, but....&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; SOME OTHER THINGS YOU MIGHT ADD&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; bars seems pointless here, but if you like, don&amp;#39;t do this&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;menu-bar-mode&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;tool-bar-mode&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;;; You could use a different theme&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;cyberpunk-theme&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;load-theme&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;cyberpunk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; Spell-checking ;;;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;flymake&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;ispell-program-name&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;hunspell&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; could be ispell as well, depending on your preferences&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;ispell-dictionary&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;en_GB&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; this can obviously be set to any language your spell-checking program supports&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; I installed the en_GB ones, but these don&amp;#39;t come in Termux by default. To add arbitrary hunspell languages, see:&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; https://www.reddit.com/r/termux/comments/k5o6mp/new_hunspell_dictionaries/?&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; in summary:&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; - how to add new: copy .aff and .dic files in /data/data/com.termux/files/usr/share/hunspell/&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; - where to get new: https://www.freeoffice.com/en/download/dictionaries&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;dolist&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;hook&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;nv&#34;&gt;org-mode-hook&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;nv&#34;&gt;hook&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;flyspell-mode&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;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-mode-hook&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;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;ispell-parser&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;tex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; make orgmode recognise LaTeX syntax [from http://stackoverflow.com/questions/11646880/flyspell-in-org-mode-recognize-latex-syntax-like-auctex ]&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;ss&#34;&gt;&amp;#39;text-mode-hook&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;flyspell-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; Undo-Tree ;; - a new undo package&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;undo-tree&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (setq undo-tree-auto-save-history 1)&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Each node in the undo tree should have a timestamp.&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;undo-tree-visualizer-timestamps&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;c1&#34;&gt;;; Show a diff window displaying changes between undo nodes.&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;undo-tree-visualizer-diff&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;global-undo-tree-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; display time and date in modeline, if you like&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;display-time-day-and-date&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;display-time-mode&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;;; prettier bullets&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-bullets&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&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;ss&#34;&gt;&amp;#39;org-mode-hook&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;org-bullets-mode&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;org-bullets-bullet-list&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;s&#34;&gt;&amp;#34;⋇&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;∴&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;∵&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;∷&amp;#34;&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;c1&#34;&gt;;; A nice way of quickly adding links.&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; (Though in Termux, you first must paste from your&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; Android clipboard and then copy/kill via Emacs before&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; it&amp;#39;ll work.)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-cliplink&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-mode-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-c o c&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-cliplink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; This is also not needed, but adds some (dubiously) useful properties&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; to the Org-roam file&amp;#39;s property drawer.&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; First, set up a system for getting location&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; (we could also try to leverage termux&amp;#39;s built-in&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; GPS location abilities via `termux-location`, but&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; it seems a bit slow and doesn&amp;#39;t even always work if&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; your device can&amp;#39;t get a good satellite connection.)&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;calendar-latitude&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;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calendar-longitude&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;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bms/get-lat-long-from-ipinfo&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;latlong&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;substring&lt;/span&gt;
                 &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command-to-string&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;curl -s &amp;#39;ipinfo.io/loc&amp;#39;&amp;#34;&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;-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;latlong-list&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;split-string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;latlong&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;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calendar-latitude&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;string-to-number&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;latlong-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;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calendar-longitude&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;string-to-number&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cadr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;latlong-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;bms/add-other-auto-props-to-org-roam-properties&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;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;file-exists-p&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;buffer-file-name&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;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-find-property&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;CREATION_TIME&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;org-roam-add-property&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format-time-string&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;%s&amp;#34;&lt;/span&gt;
                                                 &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nth&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;nf&#34;&gt;file-attributes&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;buffer-file-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
                             &lt;span class=&#34;s&#34;&gt;&amp;#34;CREATION_TIME&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;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-find-property&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;AUTHOR&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;org-roam-add-property&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;roam-user&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;AUTHOR&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;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-find-property&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;MAIL&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;org-roam-add-property&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;roam-email&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;MAIL&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;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-find-property&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;LAT_LONG&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;bms/get-lat-long-from-ipinfo&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;org-roam-add-property&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;concat&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;number-to-string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calendar-latitude&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;nf&#34;&gt;number-to-string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;calendar-longitude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;LAT-LONG&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;ss&#34;&gt;&amp;#39;org-roam-capture-new-node-hook&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bms/add-other-auto-props-to-org-roam-properties&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; You could use Ivy or Helm or the default, but I&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; like Selectrum, Consult &amp;amp; friends. Plus we can leverage&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; Consult for a nice alternative to deft for note-searching.&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; You&amp;#39;ll need this to use my ripgrep note searching feature below.&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; selectrum&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;selectrum&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;selectrum-mode&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;;; ;; prescient  - T9&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;prescient&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&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;prescient-persist-mode&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;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;prescient-filter-method&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;nv&#34;&gt;literal&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;regexp&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;initialism&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fuzzy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;;; added fuzzy&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;orderless&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:init&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;icomplete-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;                &lt;span class=&#34;c1&#34;&gt;; optional but recommended!&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:custom&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;completion-styles&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;nv&#34;&gt;orderless&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&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;orderless-matching-styles&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;nv&#34;&gt;orderless-flex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; This means that the company-capf backend will automatically use orderless, but following issue exists:&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Pressing SPC takes you out of completion, so with the default separator you are limited to one component,&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; which is no fun. To fix this add a separator that is allowed to occur in identifiers, for example, for&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Emacs Lisp code you could use an ampersand:&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;orderless-component-separator&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;[ &amp;amp;]&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; The matching portions of candidates aren’t highlighted. But while you can’t get different faces for&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; different components, you can at least get the matches highlighted in the sole available face with this configuration&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;just-one-face&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fn&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;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;orderless-match-faces&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;completions-common-part&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;apply&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fn&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;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;advice-add&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;company-capf--candidates&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:around&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;just-one-face&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;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;selectrum-prescient&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; to make sorting and filtering more intelligent&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;selectrum-prescient-mode&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;;; Filtering with orderless&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;selectrum-refine-candidates-function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;orderless-filter&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;selectrum-highlight-candidates-function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;orderless-highlight-matches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; If you also configure `completion-styles` for orderless you might want to use the&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; following advice because orderless isn&amp;#39;t well suited for initial gathering of&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; candidates by completion in region.&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;advice-add&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;completion--category-override&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:filter-return&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;completion-in-region-style-setup+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;s&#34;&gt;&amp;#34;Fallback to default styles for region completions with orderless.&amp;#34;&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;nv&#34;&gt;res&lt;/span&gt;
                    &lt;span class=&#34;c1&#34;&gt;;; Don&amp;#39;t use orderless for initial candidate gathering.&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;nv&#34;&gt;completion-in-region-mode-predicate&lt;/span&gt;
                         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;minibufferp&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;equal&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;nv&#34;&gt;orderless&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;completion-styles&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;nv&#34;&gt;basic&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;partial-completion&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;emacs22&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; Minibuffer-actions with embark&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; You should bind embark commands like embark-act, embark-act-noexit&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; and embark-export in minibuffer-local-map (as embark commands are not selectrum specific).&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; For available commands and other embark configurations see the embark documentation and its wiki.&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;current-candidate+category&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;nv&#34;&gt;selectrum-is-active&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;selectrum--get-meta&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;category&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;selectrum-get-current-candidate&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;ss&#34;&gt;&amp;#39;embark-target-finders&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-candidate+category&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;current-candidates+category&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;nv&#34;&gt;selectrum-is-active&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;selectrum--get-meta&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;category&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;selectrum-get-current-candidates&lt;/span&gt;
             &lt;span class=&#34;c1&#34;&gt;;; Pass relative file names for dired.&lt;/span&gt;
             &lt;span class=&#34;nv&#34;&gt;minibuffer-completing-file-name&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;ss&#34;&gt;&amp;#39;embark-candidate-collectors&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-candidates+category&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; No unnecessary computation delay after injection.&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;ss&#34;&gt;&amp;#39;embark-setup-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;selectrum-set-selected-candidate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; The following is not selectrum specific but included here for convenience.&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; If you don&amp;#39;t want to use which-key as a key prompter skip the following code.&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;embark-action-indicator&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;map&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;which-key--show-keymap&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Embark&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;no-paging&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;which-key--hide-popup-ignore-command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;embark-become-indicator&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;embark-action-indicator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; to save your command history on disk, so the sorting gets more&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; intelligent over time&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;prescient-persist-mode&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;;; Example configuration for Consult&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Replace bindings. Lazily loaded due by `use-package&amp;#39;.&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:bind&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;C-x M-:&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-complex-command&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;C-c h&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-history&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;C-c m&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-mode-command&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;C-x b&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-buffer&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;C-x 4 b&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-buffer-other-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;C-x 5 b&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-buffer-other-frame&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;C-x r x&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-register&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;C-x r b&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-bookmark&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;M-g g&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-goto-line&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;M-g M-g&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-goto-line&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;M-g o&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-outline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;       &lt;span class=&#34;c1&#34;&gt;;; &amp;#34;M-s o&amp;#34; is a good alternative.&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;M-g l&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;          &lt;span class=&#34;c1&#34;&gt;;; &amp;#34;M-s l&amp;#34; is a good alternative.&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;M-g m&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-mark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;          &lt;span class=&#34;c1&#34;&gt;;; I recommend to bind Consult navigation&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;M-g k&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-global-mark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;;; commands under the &amp;#34;M-g&amp;#34; prefix.&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;M-g r&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-ripgrep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;      &lt;span class=&#34;c1&#34;&gt;;; or consult-grep, consult-ripgrep&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;M-g f&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-find&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;          &lt;span class=&#34;c1&#34;&gt;;; or consult-locate, my-fdfind&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;M-g i&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-project-imenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;;; or consult-imenu&lt;/span&gt;
         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;M-g e&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-error&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;M-s m&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-multi-occur&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;M-y&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-yank-pop&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;&amp;lt;help&amp;gt; a&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-apropos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; The :init configuration is always executed (Not lazy!)&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:init&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; Custom command wrappers. It is generally encouraged to write your own&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; commands based on the Consult commands. Some commands have arguments which&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; allow tweaking. Furthermore global configuration variables can be set&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; locally in a let-binding.&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;my-fdfind&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kp&#34;&gt;&amp;amp;optional&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;dir&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;interactive&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;P&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;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;consult-find-command&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;s&#34;&gt;&amp;#34;fdfind&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;--color=never&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;--full-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;consult-find&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; Replace `multi-occur&amp;#39; with `consult-multi-occur&amp;#39;, which is a drop-in replacement.&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;fset&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;multi-occur&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;consult-multi-occur&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; Configure other variables and modes in the :config section, after lazily loading the package&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; Configure preview. Note that the preview-key can also be configured on a&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; per-command basis via `consult-config&amp;#39;.&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (setq consult-preview-key &amp;#39;any) ;; any key triggers preview, the default&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; Optionally configure narrowing key.&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Both &amp;lt; and C-+ work reasonably well.&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;consult-narrow-key&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;lt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;;; (kbd &amp;#34;C-+&amp;#34;)&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Optionally make narrowing help available in the minibuffer.&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Probably not needed if you are using which-key.&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (define-key consult-narrow-map (vconcat consult-narrow-key &amp;#34;?&amp;#34;) #&amp;#39;consult-narrow-help)&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; Optional configure a view library to be used by `consult-buffer&amp;#39;.&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; The view library must provide two functions, one to open the view by name,&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; and one function which must return a list of views as strings.&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Example: https://github.com/minad/bookmark-view/&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (setq consult-view-open-function #&amp;#39;bookmark-jump&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;;       consult-view-list-function #&amp;#39;bookmark-view-names)&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; Optionally configure a function which returns the project root directory&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (autoload &amp;#39;projectile-project-root &amp;#34;projectile&amp;#34;)&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; (setq consult-project-root-function #&amp;#39;projectile-project-root)&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; Optionally add the `consult-flycheck&amp;#39; command.&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-flycheck&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:bind&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;:map&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;flycheck-command-map&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;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;consult-flycheck&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; Optionally enable richer annotations using the Marginalia package&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;marginalia&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; The :init configuration is always executed (Not lazy!)&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:init&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; Must be in the :init section of use-package such that the mode gets&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; enabled right away. Note that this forces loading the package.&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;marginalia-mode&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;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;embark&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:bind&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;C-S-a&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;embark-act&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;               &lt;span class=&#34;c1&#34;&gt;; pick some comfortable binding&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; For Selectrum users:&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;current-candidate+category&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;nv&#34;&gt;selectrum-is-active&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;selectrum--get-meta&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;category&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;selectrum-get-current-candidate&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;ss&#34;&gt;&amp;#39;embark-target-finders&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-candidate+category&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;current-candidates+category&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;nv&#34;&gt;selectrum-is-active&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;selectrum--get-meta&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;category&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;selectrum-get-current-candidates&lt;/span&gt;
             &lt;span class=&#34;c1&#34;&gt;;; Pass relative file names for dired.&lt;/span&gt;
             &lt;span class=&#34;nv&#34;&gt;minibuffer-completing-file-name&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;ss&#34;&gt;&amp;#39;embark-candidate-collectors&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-candidates+category&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;;; No unnecessary computation delay after injection.&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;ss&#34;&gt;&amp;#39;embark-setup-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;selectrum-set-selected-candidate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; org-roam-rg-search - this is a much faster way to search Org-roam notes:&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; requires the Selectrum+Consult setup immediately preceding.&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; Use C-c r r to search notes via consult&amp;#39;s ripgrep interface&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;bms/org-roam-rg-search&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Search org-roam directory using consult-ripgrep. With live-preview.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&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;consult-ripgrep&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;rg --null --ignore-case --type org --line-buffered --color=always --max-columns=500 --no-heading --line-number . -e ARG OPTS&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;consult-ripgrep&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-directory&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;global-set-key&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-c rr&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;bms/org-roam-rg-search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; speed-keys - see https://github.com/alhassy/emacs.d#manipulating-sections&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;org-use-speed-commands&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;c1&#34;&gt;;; On an org-heading, C-a goes to after the star, heading markers. To use speed keys, run C-a C-a to get to the star markers.&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; C-e goes to the end of the heading, not including the tags.&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;org-special-ctrl-a/e&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;c1&#34;&gt;;;drag images into orgmode&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-download&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&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;ss&#34;&gt;&amp;#39;dired-mode-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-download-enable&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;global-set-key&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-c o i&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-download-yank&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;org-download-method&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;attach&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;bms/org-attach-insert-link&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kp&#34;&gt;&amp;amp;optional&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;in-emacs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Insert attachment from list.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;P&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;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;attach-dir&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-attach-dir&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;nv&#34;&gt;attach-dir&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;file&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pcase&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-attach-file-list&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;attach-dir&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;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;file&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;files&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;completing-read&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Insert attachment: &amp;#34;&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;list&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;files&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;path&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expand-file-name&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;file&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;attach-dir&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;desc&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;file-name-nondirectory&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;path&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;initial-input&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;not&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-link-make-description-function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desc&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;no&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;condition-case&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;nf&#34;&gt;funcall&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-link-make-description-function&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;link&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desc&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;ne&#34;&gt;error&lt;/span&gt;
                        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Can&amp;#39;t get link description from %S&amp;#34;&lt;/span&gt;
                                 &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;symbol-name&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-link-make-description-function&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;sit-for&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;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;desc&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;nv&#34;&gt;called-interactively-p&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;any&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-string&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Description: &amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;initial-input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                         &lt;span class=&#34;nv&#34;&gt;initial-input&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;org-insert-link&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;concat&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;attachment:&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desc&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;ne&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;No attachment directory exist&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;nf&#34;&gt;define-key&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-mode-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-c o l&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bms/org-attach-insert-link&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; in case you want some things not in melpa&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; you&amp;#39;ll need it for the remaining things below&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;quelpa&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&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;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;quelpa-use-package&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&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;c1&#34;&gt;;; A bit of sugar for the visual appearance of Org syntax&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; Use if you like.&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-appear&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:quelpa&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-appear&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:fetcher&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;github&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:repo&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;awth13/org-appear&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:config&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;org-hide-emphasis-markers&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;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-mode-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-appear-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;;; You don&amp;#39;t need this, but it&amp;#39;s cool and it does work on Android:&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;;; see https://github.com/org-roam/org-roam-ui for features&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-ui&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:quelpa&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-roam-ui&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:fetcher&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;github&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:repo&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;org-roam/org-roam-ui&amp;#34;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:branch&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:files&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;*.el&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;out&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:after&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;:hook&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-roam&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-roam-ui-mode&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;An excellent way of keeping Org notes (and files more generally) in
sync between desktop, laptop, and mobile devices is &lt;a href=&#34;https://syncthing.net/&#34;&gt;Syncthing&lt;/a&gt;. On
Android I recommend using the &lt;a href=&#34;https://f-droid.org/en/packages/com.github.catfriend1.syncthingandroid/&#34;&gt;Syncthing-Fork&lt;/a&gt; app (via F-Droid), which has various improvements over the default Syncthing app on Android, including better file-access features. (On iOS there is now a third-party solution for syncing via Syncthing: &lt;a href=&#34;https://www.mobiussync.com/&#34;&gt;Möbius-Sync&lt;/a&gt;. I have no idea how to use Emacs/Org-mode on iOS though, but I recall hearing about some ways of running a Linux shell on iOS like &lt;a href=&#34;https://ish.app/&#34;&gt;iSH&lt;/a&gt;, so possibly there&amp;rsquo;s some way.)&lt;/p&gt;
&lt;p&gt;I have Syncthing sync my Org files to a directory in my main &amp;ldquo;home&amp;rdquo;
directory on Android &lt;code&gt;Documents/Org&lt;/code&gt; and then in Termux created a
&lt;code&gt;Documents&lt;/code&gt; directory and inside of that directory created a symlink to
my actual Org directory via &lt;code&gt;ln -s storage/shared/Documents/Org Org&lt;/code&gt;. I&amp;rsquo;ve found that is easier for allowing Syncthing to have access
to the files in order to keep them in sync. (And having my Org files
live at &lt;code&gt;~/Documents/Org&lt;/code&gt; in Termux mimics the directory structure on my
Linux boxes, which makes lots of things easier in terms of sharing
configurations.)&lt;/p&gt;
</description>
                
                        <author>Benjamin.Slade@fakeEmailToMakeValidatorHappy.com (Benjamin Slade)</author>
                
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/categories/emacs">emacs</category>
                                 
                                    <category domain="https://babbagefiles.xyz/categories/org">org</category>
                                
                            
                        
                     
                        
                     
                        
                             
                            
                                
                                 
                                    <category domain="https://babbagefiles.xyz/tags/orgroam">orgroam</category>
                                 
                                    <category domain="https://babbagefiles.xyz/tags/android">android</category>
                                
                            
                        
                    
                
                <guid>https://babbagefiles.xyz/org-roam-on-android/</guid>
                <pubDate>Mon, 09 Aug 2021 20:06:00 -0500</pubDate>
            </item>
        
    </channel>
</rss>


