<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title></title>
    <link rel="self" type="application/atom+xml" href="https://beta.lambdaland.org/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://beta.lambdaland.org"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-01-21T00:00:00+00:00</updated>
    <id>https://beta.lambdaland.org/atom.xml</id>
    <entry xml:lang="en">
        <title>Explainer: Tree-sitter vs. LSP</title>
        <published>2026-01-21T00:00:00+00:00</published>
        <updated>2026-01-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2026-01-21_tree-sitter_vs_lsp/"/>
        <id>https://beta.lambdaland.org/posts/2026-01-21_tree-sitter_vs_lsp/</id>
        
        <summary type="html">&lt;p&gt;I got asked a good question today: what is the difference between &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tree-sitter_(parser_generator)&quot;&gt;Tree-sitter&lt;&#x2F;a&gt; and a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Language_Server_Protocol&quot;&gt;language server&lt;&#x2F;a&gt;? I don’t understand how either of these tools work in depth, so I’m just going to explain from an &lt;em&gt;observable&lt;&#x2F;em&gt;, &lt;em&gt;pragmatic&lt;&#x2F;em&gt; point of view.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Running</title>
        <published>2026-01-09T00:00:00+00:00</published>
        <updated>2026-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2026-01-09_running/"/>
        <id>https://beta.lambdaland.org/posts/2026-01-09_running/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2026-01-09_running/">&lt;p&gt;I guess I’m a runner now.&lt;&#x2F;p&gt;
&lt;p&gt;I never liked running. I did swim team in high school and that was pretty much the only sport I enjoyed. During the pandemic I started running a little bit, but I didn’t know very much and when I moved to Salt Lake City to start my PhD I pretty much stopped running entirely because everywhere was so hilly.&lt;&#x2F;p&gt;
&lt;p&gt;Last year I moved again and I saw that I had a nice, flat route I could take for running if I wanted to. I got some better shoes and started following the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;c25k.com&#x2F;c25k_plan&#x2F;&quot;&gt;Couch to 5k&lt;&#x2F;a&gt; training plan. I thought the first weeks would be too easy. I was wrong: every week turned out to be perfectly tuned to what I needed. I finished the training plan and just tried to get out on a run 2–3 times a week.&lt;&#x2F;p&gt;
&lt;p&gt;I ran just shy of 200 miles last year!&lt;&#x2F;p&gt;
&lt;p&gt;This is a big change for me health-wise. I was in a bad spot during the first few years of my PhD. I wanted to improve my cardiovascular health to improve longevity and cognitive function. I am &lt;em&gt;really&lt;&#x2F;em&gt; enjoying my runs now, and I feel energized and clearer-headed whenever I finish one. This is not something I thought I would ever say.&lt;&#x2F;p&gt;
&lt;p&gt;Some things that made a big difference for me:&lt;&#x2F;p&gt;
&lt;dl&gt;
&lt;dt&gt;Having a level track to get started on&lt;&#x2F;dt&gt;
&lt;dd&gt;Hills are important for training and I wish I had some where I live. But when I was starting out, it was a good motivator to just have a nice, flat route.&lt;&#x2F;dd&gt;
&lt;dt&gt;Good shoes&lt;&#x2F;dt&gt;
&lt;dd&gt;Good shoes are a must, and they degrade over time. I was running in some 5-year-old runners that didn’t provide much cushion. My new ones made my runs much more pleasant, and I’ll be getting a new pair once I reach the 300-mile mark.&lt;&#x2F;dd&gt;
&lt;dt&gt;Gentle training plan&lt;&#x2F;dt&gt;
&lt;dd&gt;I did not understand how important rest and stretching were, and I kind of banged up my knees. Having a training plan helped me not overdo my runs so I could keep running and improving over time.&lt;&#x2F;dd&gt;
&lt;dt&gt;Learning about running form&lt;&#x2F;dt&gt;
&lt;dd&gt;I watched some YouTube videos on proper running form. I think I was over-striding and my feet were landing out in front of me on the heel. This put a lot of strain on my legs and my knees hurting tended to be the limiting factor on how often I could run. I still need to go get my gait analyzed, but I have noticed a difference!&lt;&#x2F;dd&gt;
&lt;&#x2F;dl&gt;
&lt;p&gt;Running is good. I enjoy getting out, and I enjoy seeing improvement both in my speed as well as in my alertness and mood post-run. I get a little grumpy on days that I &lt;em&gt;don’t&lt;&#x2F;em&gt; get to go for a run. Best kind of addiction I suppose.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Typst for Your Code Blocks</title>
        <published>2025-11-20T00:00:00+00:00</published>
        <updated>2025-11-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2025-11-20_typst_your_codeblocks/"/>
        <id>https://beta.lambdaland.org/posts/2025-11-20_typst_your_codeblocks/</id>
        
        <summary type="html">&lt;p&gt;I started using &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;typst.app&quot;&gt;Typst&lt;&#x2F;a&gt; about a month ago to write my dissertation proposal. I had seen Typst before and decided to keep an eye on it as it matured. While it still is very much in development, it is mature enough that I was able to rewrite my dissertation proposal from an org-mode → LaTeX pipeline to pure Typst in about an hour with &lt;em&gt;no&lt;&#x2F;em&gt; major hiccups. In fact, most things got &lt;em&gt;simpler&lt;&#x2F;em&gt; as a consequence of using Typst.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Federate Away From GitHub</title>
        <published>2025-11-18T00:00:00+00:00</published>
        <updated>2025-11-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2025-11-18_federate_your_forges/"/>
        <id>https://beta.lambdaland.org/posts/2025-11-18_federate_your_forges/</id>
        
        <summary type="html">&lt;p&gt;The past few weeks have seen major AWS, Azure, and Cloudflare outages. I predict Google Cloud will have a major outage sometime soon as well. Each time one of these massive systems goes down, it takes a sizable chunk of the internet with it. This is troubling: the internet should be more robust against partial outages.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>How I Organize the Papers I Read</title>
        <published>2025-10-03T00:00:00+00:00</published>
        <updated>2025-10-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2025-10-03_reading_papers/"/>
        <id>https://beta.lambdaland.org/posts/2025-10-03_reading_papers/</id>
        
        <summary type="html">&lt;p&gt;I got asked how I manage papers, notes, and citations for doing research. I started writing out a &lt;em&gt;very&lt;&#x2F;em&gt; long Slack message, but it quickly passed the threshold where I ought to just turn it into a blog post.&lt;&#x2F;p&gt;
&lt;p&gt;The short of it: I’m an incorrigible Emacs user, so I do a lot through my editor of choice on my laptop. That said, &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.zotero.org&#x2F;&quot;&gt;Zotero&lt;&#x2F;a&gt; is a fabulous piece of technology, and I rely on it heavily to get my work done.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Getting Started With Lock Picking</title>
        <published>2025-08-21T00:00:00+00:00</published>
        <updated>2025-08-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2025-08-21_lockpicking/"/>
        <id>https://beta.lambdaland.org/posts/2025-08-21_lockpicking/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2025-08-21_lockpicking/">&lt;p&gt;There are few sounds as satisfying to me as a lock popping open, especially when it’s a well-machined lock that makes a nice, crisp “chink!” sound as the shackle releases.&lt;&#x2F;p&gt;
&lt;p&gt;This post is some suggestions I gave to a friend of mine who wanted to get started in lock picking. Please consult your local laws to know the ins and outs around the hobby. Nothing here is legal advice. Also, while I do link to a few product pages, I never have and never will take commissions for material on this blog. I am recommending these tools because &lt;em&gt;I&lt;&#x2F;em&gt; like them, and not for any financial gain.&lt;&#x2F;p&gt;
&lt;div class=&quot;info&quot;&gt;
&lt;p&gt;&lt;strong&gt;Rules for Lock Picking&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are two big rules to follow when picking locks:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Only pick locks that you own.&lt;&#x2F;li&gt;
&lt;li&gt;Never pick locks that are in use.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Rule 1 should be fairly obvious: picking other locks can be a criminal offense. Rule 2 is for your sake: picking a lock can, on rare occasions, break the lock. If the lock is in use, you might have to get bolt cutters or a big drill to fix the problem destructively.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;picks-and-tensioning&quot;&gt;Picks &amp;amp; Tensioning&lt;&#x2F;h2&gt;
&lt;p&gt;Tools matter. The biggest piece of advice is this: &lt;strong&gt;never buy picks off Amazon!&lt;&#x2F;strong&gt; Those pick sets are made with cheap steel that gets caught in keyways and provides lousy feedback. I thought I was a bad picker for many years—and that is true—but it was also due in large part to how my tools were holding me back.&lt;&#x2F;p&gt;
&lt;p&gt;Remember: a few high-quality tools is better than a big set of nearly useless ones.&lt;&#x2F;p&gt;
&lt;p&gt;Get picks from &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jimylongs.com&#x2F;&quot;&gt;JimyLongs&lt;&#x2F;a&gt;. They are the best. They will last you forever. Everyone on &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;reddit.com&#x2F;r&#x2F;lockpicking&quot;&gt;r&#x2F;lockpicking&lt;&#x2F;a&gt; loves them. They are remarkably affordable. They’re versatile and comfortable.&lt;&#x2F;p&gt;
&lt;p&gt;I would start with the Basics and Intermediate sets. They’re both 0.019“ thick, which is a touch thinner than the picks you were working with (0.025“) which means feedback is a little more subtle, but it’s easier to get into more keyways. The two sets will also get you a nice selection of turning tools. The z-bar TOK (Top Of Keyway) turners are really nice to use; I almost exclusively use TOK turners now.&lt;&#x2F;p&gt;
&lt;p&gt;I love the Covert Instruments ergo turners. They make practicing so comfortable.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; They might go on sale around Black Friday, so watch out for that. I wouldn’t bother much with other stuff from CI unless you see something that you really like. I do have the Covert Companion with some extension kits for EDC-style (Every Day Cary) portability, but it’s rather terrible for practice.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jimylongs.com&#x2F;products&quot;&gt;https:&#x2F;&#x2F;jimylongs.com&#x2F;products&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;covertinstruments.com&#x2F;products&#x2F;ergo-turner-set&quot;&gt;https:&#x2F;&#x2F;covertinstruments.com&#x2F;products&#x2F;ergo-turner-set&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;practice-locks&quot;&gt;Practice Locks&lt;&#x2F;h2&gt;
&lt;p&gt;A great resource is the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lpubelts.com&#x2F;#&#x2F;locks&quot;&gt;LPU Belt Explorer&lt;&#x2F;a&gt;. This is a big categorization of pretty much any lock you’ll ever run into broken down by complexity. For example, &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lpubelts.com&#x2F;#&#x2F;locks?tab=search&amp;amp;search=2455f0ae&amp;amp;id=2455f0ae&amp;amp;name=Master_Lock_140_141&quot;&gt;here is the entry for the Master Lock 140&lt;&#x2F;a&gt;—a great beginner lock. The locks are organized according to “belts” like those in Karate.&lt;&#x2F;p&gt;
&lt;p&gt;You can find Brinks laminated and brass padlocks at Walmart. These are both in the yellow belt tier and are fine locks for getting started. Once you start wanting better locks, I have found that locks from Abus tend to be well-machined and give good feedback. Sometimes a crappy Master Lock can be hard to open because it’s greasy or something on the inside and that can totally kill feedback.&lt;&#x2F;p&gt;
&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;&lt;strong&gt;A dirty old lock is typically harder to open than a clean, well-machined higher-tier lock.&lt;&#x2F;strong&gt; Not having feedback when picking a lock is like trying to assemble a puzzle while blindfolded. If you get a used lock, you might want to clean it first to get that feedback back.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;As you go higher, the Abus 55&#x2F;40 is a fantastic orange belt. The American 1100 is a popular green belt. I just bought 7 of these things off of Ebay. The Master Lock LOTO lock (plastic body; lots of colors) is another excellent green belt that will force you to get a feel for spool pins. That’s as high as I’ve gone.&lt;&#x2F;p&gt;
&lt;p&gt;Around Black Friday definitely check out the Covert Instruments practice lock: it’s re-pinable and comes with a bunch of pins so you can practice getting a feel for different bitting and security pins. My brother got me this set with the set of picks I let you borrow for Christmas, and the lock has been super helpful.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;community&quot;&gt;Community&lt;&#x2F;h2&gt;
&lt;p&gt;If you like Reddit, r&#x2F;lockpicking is a great place to hang out, ask questions, and get tips.&lt;&#x2F;p&gt;
&lt;p&gt;Lots of good YouTubers:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Lockpicking Lawyer (of course): He focuses more on picking commercial locks and pointing out their security flaws. Not necessarily the best resource for learning lock picking. (His “inside perspective” series is great though!)&lt;&#x2F;li&gt;
&lt;li&gt;Lockpicking Dev: This channels has a little bit more about how to actually pick locks.&lt;&#x2F;li&gt;
&lt;li&gt;Lady Locks: She had a video that helped me get my first American 1100 open.&lt;&#x2F;li&gt;
&lt;li&gt;Fish Picks&lt;&#x2F;li&gt;
&lt;li&gt;Sandman&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;tl-dr&quot;&gt;TL;DR&lt;&#x2F;h2&gt;
&lt;p&gt;Start with these picks and locks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Basics set from JimyLongs lock picks&lt;&#x2F;li&gt;
&lt;li&gt;Master Lock 140, Brinks laminated&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Level up with these:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Intermediate set from JimyLongs&lt;&#x2F;li&gt;
&lt;li&gt;Covert Instruments ergo-turners&lt;&#x2F;li&gt;
&lt;li&gt;Locks from Abus, ACE hardware (their brass padlock is &lt;em&gt;insane&lt;&#x2F;em&gt;—I have not yet opened it)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Decide where to go from there!&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Left-handed pickers: the ergo turners will probably not work for you—sorry! &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>AI stands for “Artificial Inanity”</title>
        <published>2025-08-04T00:00:00+00:00</published>
        <updated>2025-08-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2025-08-04_artifical_inanity/"/>
        <id>https://beta.lambdaland.org/posts/2025-08-04_artifical_inanity/</id>
        
        <summary type="html">&lt;p&gt;There’s something icky about LLM-generated text when you think it’s written by a human. I think I finally put my finger on one reason why I feel this way.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Bedrock Version 1.5.0 Released</title>
        <published>2025-07-15T00:00:00+00:00</published>
        <updated>2025-07-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2025-07-15_bedrock_release/"/>
        <id>https://beta.lambdaland.org/posts/2025-07-15_bedrock_release/</id>
        
        <summary type="html">&lt;p&gt;I just released version 1.5.0 of &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;emacs-bedrock&quot;&gt;Emacs Bedrock&lt;&#x2F;a&gt;—a super minimal starter kit for Emacs. This is a minor change: I’ve fixed a few bugs and added a package or two to some of the optional config files under &lt;code&gt;extras&#x2F;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>How I Take Notes for Research</title>
        <published>2025-07-11T00:00:00+00:00</published>
        <updated>2025-07-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2025-07-11_research_notes/"/>
        <id>https://beta.lambdaland.org/posts/2025-07-11_research_notes/</id>
        
        <summary type="html">&lt;p&gt;The key principle I follow is this: &lt;em&gt;how I take my notes will evolve over time&lt;&#x2F;em&gt;. I do not stick to any system too dogmatically.&lt;&#x2F;p&gt;
&lt;p&gt;That said, I’ve settled on a system that’s been fairly robust and stable for the past few years. I have tweaked it here and there to make it easier for me to find what I need.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Programmers and Their Monospace Blogs</title>
        <published>2025-06-24T00:00:00+00:00</published>
        <updated>2025-06-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2025-06-24_reading_blogs/"/>
        <id>https://beta.lambdaland.org/posts/2025-06-24_reading_blogs/</id>
        
        <summary type="html">&lt;p&gt;Many developers seem to have a fanatic obsession with monospace fonts and using them to make their blogs look “cool”. I won’t call out anyone’s blog specifically, but you don’t have to look to hard to find some. As an example &lt;em&gt;theme&lt;&#x2F;em&gt; using a monospace font by default, look at &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;panr&#x2F;hugo-theme-terminal&quot;&gt;hugo-theme-terminal&lt;&#x2F;a&gt;, which has over 2,400 stars on GitHub. If you have a blog or are thinking about starting one, and you are writing mostly prose (you probably are), I have one suggestion for you about fonts:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Do not use monospace fonts for prose.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Real Programmers</title>
        <published>2025-05-13T00:00:00+00:00</published>
        <updated>2025-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2025-05-13_real_programmers/"/>
        <id>https://beta.lambdaland.org/posts/2025-05-13_real_programmers/</id>
        
        <summary type="html">&lt;p&gt;There’s been an explosion of tools for software development. At the same time there’s a growing sense that software quality isn’t what it used to be—or that developers these days don’t understand what it takes to be a “real” programmer, whatever that means. I’m not that old, but I have some old-school tool preferences. Some tools I really like; in other cases I feel that by &lt;em&gt;not&lt;&#x2F;em&gt; adopting particular habits, I’ve gained or retained an edge over others in the software development space.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>TV Shows for Kids</title>
        <published>2025-04-20T00:00:00+00:00</published>
        <updated>2025-04-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/personal/2025-04-20-kids-shows/"/>
        <id>https://beta.lambdaland.org/posts/personal/2025-04-20-kids-shows/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/personal/2025-04-20-kids-shows/">&lt;p&gt;When I was in my early 20s, I vowed that I would keep my kids from watching any amount of television.&lt;&#x2F;p&gt;
&lt;p&gt;Turns out, sometimes you &lt;em&gt;really&lt;&#x2F;em&gt; need a break as a parent. A good show can keep your kid entertained while you perform necessary tasks like preparing a meal, doing the dishes, or getting just enough extra sleep to not blow your top or doze off in the car while you drive your kid to preschool.&lt;&#x2F;p&gt;
&lt;p&gt;So, I have had a change of heart: TV can be a tool, but not all TV programs are created equal.&lt;&#x2F;p&gt;
&lt;p&gt;Without further ado, here is my tier list of the shows I’ve seen or heard about:&lt;&#x2F;p&gt;
&lt;h1 id=&quot;s-tier&quot;&gt;S-tier&lt;&#x2F;h1&gt;
&lt;p&gt;These are the shows that I am fine with my kid watching any time. They are well-written, low-stimulus, and never get annoying.&lt;&#x2F;p&gt;
&lt;p&gt;Why do I care so much about low-stimulus shows? I don’t want my kids getting hooked on dopamine rushes. I’d rather that they play imaginatively as much as possible. Low-stimulus shows help by not desensitizing kids to the gentler kind of happiness that comes through creative play.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bluey&quot;&gt;Bluey&lt;&#x2F;h2&gt;
&lt;p&gt;How could it not be &lt;em&gt;Bluey&lt;&#x2F;em&gt;?! It’s a low-stimulus show about parenting that kids happen to enjoy as well. The dad, Bandit, is an enthusiastic, clever, engaged parent who sometimes messes up but always makes up for it. The mum, Chili, is loving, firm, hard-working, and creative. The relationships are positive and realistic.&lt;&#x2F;p&gt;
&lt;p&gt;My favorite episodes are:&lt;&#x2F;p&gt;
&lt;dl&gt;
&lt;dt&gt;Camping&lt;&#x2F;dt&gt;
&lt;dd&gt;This one makes me tear up. I initially saw Jean-Luc’s departure as a metaphor for death and Chili’s words as a hope to see our friends again in the hereafter. But then my wife pointed out that the episode is essentially the Star Trek episode &lt;em&gt;Darmok&lt;&#x2F;em&gt; where the captain of the Enterprise (Jean-Luc Picard—the name should have been a clue) must learn how to communicate with someone who speaks a strange language.&lt;&#x2F;dd&gt;
&lt;dt&gt;The Sign&lt;&#x2F;dt&gt;
&lt;dd&gt;The hour-long 3rd-season finale is an absolute onslaught of emotional sucker-punches if you’ve watched the entire show.&lt;&#x2F;dd&gt;
&lt;dt&gt;Granny Mobile&lt;&#x2F;dt&gt;
&lt;dd&gt;Nothing particularly deep in this episode, but it is &lt;em&gt;so&lt;&#x2F;em&gt; funny.&lt;&#x2F;dd&gt;
&lt;&#x2F;dl&gt;
&lt;p&gt;There are more. &lt;em&gt;Bluey&lt;&#x2F;em&gt; deserves all the hype it gets. It’s that good. If you have a toddler, watch &lt;em&gt;Bluey&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;puffin-rock&quot;&gt;Puffin Rock&lt;&#x2F;h2&gt;
&lt;p&gt;This feels like an Irish-flavored &lt;em&gt;Bluey&lt;&#x2F;em&gt;-type show, but with Irish-accented puffins. Sweet show with a pretty animation style. Most episodes are just about the main character, Oona, exploring the island. Less anthropomorphic than &lt;em&gt;Bluey&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;a-tier&quot;&gt;A-tier&lt;&#x2F;h1&gt;
&lt;p&gt;Good shows that don’t quite rise to the level of &lt;em&gt;Bluey&lt;&#x2F;em&gt; and aren’t as visually beautiful as &lt;em&gt;Puffin Rock&lt;&#x2F;em&gt; but are still fun and occasionally educational.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;little-einsteins&quot;&gt;Little Einsteins&lt;&#x2F;h2&gt;
&lt;p&gt;Four kids fly around in a “Rocket”. Each episode features a work of classical music and some art by a famous artist. The kids never fight—the whole show is about them solving problems. The best part is that my kid can now recognize lots of different important classical pieces and enjoys listening to them. Occasionally the episodes get a &lt;em&gt;little&lt;&#x2F;em&gt; annoying because of how formulaic they are, but maybe that’s good for the kids.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;blue-s-clues&quot;&gt;Blue’s Clues&lt;&#x2F;h2&gt;
&lt;p&gt;I grew up watching &lt;em&gt;Blue’s Clues&lt;&#x2F;em&gt; and it’s still such a nice, sweet show.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;b-tier&quot;&gt;B-tier&lt;&#x2F;h1&gt;
&lt;p&gt;These are shows that we will turn on if we have to. I wouldn’t consider them &lt;em&gt;bad&lt;&#x2F;em&gt;, but they are moderately annoying.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;if-you-give-a-mouse-a-cookie&quot;&gt;If You Give A Mouse A Cookie&lt;&#x2F;h2&gt;
&lt;p&gt;This is a TV show based off of the series of children’s books by Laura Numeroff and Felicia Bond. The show is… fine. Most of the characters seem to have a sense of helplessness when something gets lost&#x2F;broken and they feel that the circumstances “…will be ruined—forever!”&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; At least half the episodes involve some &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;MacGuffin&quot;&gt;MacGuffin&lt;&#x2F;a&gt; rolling down a hill to a pond.&lt;&#x2F;p&gt;
&lt;p&gt;Again, it’s not a &lt;em&gt;bad&lt;&#x2F;em&gt; show, but sometimes my daughter will start talking like Mouse with one-word requests for things like “thirsty” or “hungry” instead of speaking in full sentences.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;c-tier&quot;&gt;C-tier&lt;&#x2F;h1&gt;
&lt;p&gt;These are shows that I don’t consider actively harmful, but I strongly dislike because of how annoying they are or because my kid picks up bad behaviors from them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;daniel-tiger&quot;&gt;Daniel Tiger&lt;&#x2F;h2&gt;
&lt;p&gt;On the surface, this is the perfect show: it’s a spin-off of &lt;em&gt;Mr. Roger’s Neighborhood&lt;&#x2F;em&gt;, the animation gentle and low-stimulus, and it’s moderately cute.&lt;&#x2F;p&gt;
&lt;p&gt;But oh—oh how deceptive it is.&lt;&#x2F;p&gt;
&lt;p&gt;Daniel Tiger displays an impressive degree of learned helplessness and timidity. All of the “problems” that he encounters in the show are invented and stupid. E.g., it is raining outside so we can’t play on the beach—grrr I’m mad and now I need help calming down from a total meltdown.&lt;&#x2F;p&gt;
&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;The &lt;em&gt;worst&lt;&#x2F;em&gt; thing from this rainy-beach episode is when the kids drag in &lt;em&gt;several wheelbarrows’ worth of sand onto the living room carpet&lt;&#x2F;em&gt; and, when the mom comes in and gets angry, Daniel tells the mom to take a deep breath and calm down from her slightly agitated state.&lt;&#x2F;p&gt;
&lt;p&gt;If my kid ever dragged several cubic meters of sand into any part of my house, I reserve the right to be upset.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Anyway, cute on the surface, aggravating underneath.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;f-tier&quot;&gt;F-tier&lt;&#x2F;h1&gt;
&lt;p&gt;I have not watched these shows. I’m too scared to go near them with a stick.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cocomelon&quot;&gt;CoComelon&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;CoComelon&lt;&#x2F;em&gt; is the epitome of high-stimulus children’s programming. In every shot the camera is panning, no shot lasts more than 3 seconds, and the show’s developers &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20250403005628&#x2F;https:&#x2F;&#x2F;www.nytimes.com&#x2F;2022&#x2F;05&#x2F;05&#x2F;arts&#x2F;television&#x2F;cocomelon-moonbug-entertainment.html?user_id=bde5ab3cc9b4378d62ec514312d1791c&amp;amp;campaign_id=61&amp;amp;emc=edit_ts_20220505&amp;amp;instance_id=60520&amp;amp;nl=the-great-read&amp;amp;regi_id=54686842&amp;amp;segment_id=91384&amp;amp;te=1&quot;&gt;utilize a tool they call “The Distraction”&lt;&#x2F;a&gt; to determine when scenes are insufficiently attention-grabbing: when a test subject (a small child) looks away from the show to look at a screen showing adults doing banal household chores, the animators will amp up the show at that point to keep kids dialed in.&lt;&#x2F;p&gt;
&lt;p&gt;I would rather not have my child’s dopamine receptors burned out by stimulus-overload.&lt;&#x2F;p&gt;
&lt;p&gt;Look, if you like &lt;em&gt;CoComelon&lt;&#x2F;em&gt;, I won’t judge you. If you’re wondering if you should pull it up for your kids, I would stay &lt;em&gt;far away&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-fewer-shows-the-better&quot;&gt;The fewer shows the better&lt;&#x2F;h1&gt;
&lt;p&gt;Kids need to be bored. The more bored they are, the more time they have to be creative and develop an internal world. I do think it’s fine to have some TV—I grew up loving &lt;em&gt;Arthur&lt;&#x2F;em&gt;, &lt;em&gt;Cyber Chase&lt;&#x2F;em&gt;, and &lt;em&gt;Reading Rainbow&lt;&#x2F;em&gt;. It is really nice to have half an hour to shower, eat, and get some chores done so I can better take care of my child. I’m trying to find good shows though. I hope this helps any parents out there looking for ideas. :) Hang in there—raising kids is &lt;strong&gt;the very best&lt;&#x2F;strong&gt; experience this world has to offer.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;This is a phrase that I am &lt;em&gt;pretty&lt;&#x2F;em&gt; sure crops up in every episode. Ugh. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Quick Guide to LaTeX</title>
        <published>2025-02-06T00:00:00+00:00</published>
        <updated>2025-02-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2025-02-06_latex_bootstrap/"/>
        <id>https://beta.lambdaland.org/posts/2025-02-06_latex_bootstrap/</id>
        
        <summary type="html">&lt;p&gt;LaTeX is a powerful typesetting system hamstrung by a few decades-old decisions and some… &lt;em&gt;ahem…&lt;&#x2F;em&gt; questionable design decisions. Nevertheless, its ability to typeset technical documents remains unmatched, and it enjoys wide support across STEM fields. Learning LaTeX is a worthy use of your time, if you intend to pursue a career in science.&lt;&#x2F;p&gt;
&lt;p&gt;This is meant as a short and simple how-to guide for learning LaTeX. It is not meant to be comprehensive, but rather serve as a guide of where to look to get the information you need to know. It is organized as a problem → solution mapping.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>What&#x27;s New in Emacs: Last Decade Edition</title>
        <published>2024-12-14T00:00:00+00:00</published>
        <updated>2024-12-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-12-14_emacs_catchup/"/>
        <id>https://beta.lambdaland.org/posts/2024-12-14_emacs_catchup/</id>
        
        <summary type="html">&lt;p&gt;Emacs has come a long way in the past decade. This is meant as a guide to anyone who’s been using stock or near-stock Emacs for some years and wants a quick update on the new shiny stuff that comes bundled with Emacs.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Should Programming Languages be Safe or Powerful?</title>
        <published>2024-11-21T00:00:00+00:00</published>
        <updated>2024-11-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-11-21_powerful_or_safe_languages/"/>
        <id>https://beta.lambdaland.org/posts/2024-11-21_powerful_or_safe_languages/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-11-21_powerful_or_safe_languages/">&lt;p&gt;Should a programming language be powerful and let a programmer do a lot, or should it be safe and protect the programmer from bad mistakes? Contrary to what the title insinuates, these are &lt;em&gt;not&lt;&#x2F;em&gt; diametrically opposed attributes. Nevertheless, this is the mindset that underlies notions such as, “macros, manual memory management, etc. are power tools—they’re not supposed to be safe.” If safety and power are not necessarily opposed, why does this notion persist?&lt;&#x2F;p&gt;
&lt;p&gt;The problem—I think—is that historically you &lt;em&gt;did&lt;&#x2F;em&gt; have to trade safety for certain kinds of power: if you wanted to write a high-performance device driver, C—with all its unsafe behavior—was your only option. This founded the idea that the “power tools” of the industry were fundamentally dangerous.&lt;&#x2F;p&gt;
&lt;p&gt;There’s a few things wrong with this though:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Power is relative to the domain of interest.&lt;&#x2F;strong&gt; Both Haskell and C are powerful, but in completely different ways. So, when judging whether an aspect of a language is powerful or not, consider its application.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Expressive languages get you power without sacrificing safety.&lt;&#x2F;strong&gt; New advances in programming language research have found ways to express problem domains more precisely. This means that we have less and less reason to breach safety and reach into the unsafe implementation details to get our work done.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;It’s good to add safety to power tools.&lt;&#x2F;strong&gt; A safe power tool is more trustworthy than an unsafe one. This holds for real-world tools: I will never use a table saw without a functioning saw stop.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Specifically in the case of macros, there’s been an evolution from powerful-but-unsafe procedural macros in Lisp to safe-but-less-powerful pattern macros in Scheme, and finally to &lt;strong&gt;powerful-and-safe&lt;&#x2F;strong&gt; macros in Racket.&lt;&#x2F;p&gt;
&lt;p&gt;More safety means higher reliability—something that everyone wants. And with advances in making languages more expressive, you can have a language perfectly suited to a particular domain without sacrificing safety.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-makes-a-language-powerful&quot;&gt;What makes a language powerful?&lt;&#x2F;h2&gt;
&lt;p&gt;A language that lets you do more of what you want to do is more powerful than a language where you can’t do what you want. But what does “what you want to do” encompass? If you want to write device drivers, then C is great for you. However, C is not as expressive in some of the ways that, say, Haskell is. For example, in Haskell, I can write lazy, recursive definitions. Here’s a list of all&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; the Fibonacci numbers:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fibs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; zipWith &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; fibs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tail fibs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Before you tell me that that’s just a useless cute trick, I actually had to use this when I was building the balancing algorithm in my rope data structure for &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;ysue&quot;&gt;my text editor written in Haskell&lt;&#x2F;a&gt;. Haskell is incredibly powerful in an &lt;em&gt;expressive&lt;&#x2F;em&gt; sense: a single line of code can elegantly capture a complicated computation.&lt;&#x2F;p&gt;
&lt;div class=&quot;epigraph&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise.&lt;&#x2F;p&gt;
&lt;footer&gt;
&lt;p&gt;Edsgar Dijkstra&lt;&#x2F;p&gt;
&lt;&#x2F;footer&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Power is closely related to the domain of interest: a language is powerful in a particular realm of problems. C is powerful for working with memory directly. Conversely, Haskell or Racket is more powerful than C in pretty much every other domain because these languages give the user tremendous ability to &lt;em&gt;match the program to the domain&lt;&#x2F;em&gt;. This is a meta-power that sets high-level languages apart from lower-level ones.&lt;&#x2F;p&gt;
&lt;p&gt;Safe languages can be just as powerful as their unsafe counterparts—in many cases, they are &lt;em&gt;more&lt;&#x2F;em&gt; powerful because the abstractions they create better fit the domain. Whenever a tradeoff between power and safety must be made, that is a sign that the language is not the right fit for the domain.&lt;&#x2F;p&gt;
&lt;p&gt;Consider how immutability gives you &lt;em&gt;local reasoning power&lt;&#x2F;em&gt;. At one of my industry jobs, our codebase was a mixture of Ruby and Elixir. Both are safe languages, but Elixir is immutable. When I was working on some Elixir code, I could read:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;user &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get_user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;session&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;name &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get_user_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;do_something_else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and I didn’t have to worry about &lt;code&gt;user&lt;&#x2F;code&gt; getting modified in the call to &lt;code&gt;get_user_name&lt;&#x2F;code&gt;. To understand the output of this function, I didn’t have to worry too much about the implementation of &lt;code&gt;get_user_name&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In contrast, if you did the same sort of thing in Ruby:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get_user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;session&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;get_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;do_something_else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;the &lt;code&gt;get_name&lt;&#x2F;code&gt; method &lt;em&gt;could&lt;&#x2F;em&gt; do something sneaky like set name to &lt;code&gt;&quot;blank&quot;&lt;&#x2F;code&gt; if it didn’t exist.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; In this case, I &lt;em&gt;did&lt;&#x2F;em&gt; have to understand what every method call did to understand the function. This made it harder to track down errors because I had to account for all the side effects that &lt;em&gt;could&lt;&#x2F;em&gt; happen at every method call.&lt;&#x2F;p&gt;
&lt;p&gt;Certain things like immutability might seem constraining, but &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=GqmsQeSzMdw&quot;&gt;constraints can liberate you&lt;&#x2F;a&gt; by allowing you to rely on particular behaviors. Elixir doesn’t let you modify things in-place, but you can rely on this, which makes understanding and composing code easier. Haskell forces you to express side-effects in the type system, but this lets you know that calling a function with a signature like &lt;code&gt;String → Int&lt;&#x2F;code&gt; won’t do any IO or throw an exception. Rust doesn’t have &lt;code&gt;null&lt;&#x2F;code&gt; like in Java, but you know when you get a pointer, you can safely dereference it and you don’t have to do all the null checking that you have to do in Java.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;case-study-macros-in-lisp-scheme-and-racket&quot;&gt;Case study: macros in Lisp, Scheme, and Racket&lt;&#x2F;h2&gt;
&lt;p&gt;The evolution of syntax macros in Lisp, Scheme, and Racket provide an interesting real-world instance of how safety and power can start off as a trade-off, but with better language design, become complimentary.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lisp-macros-unsafe-but-powerful&quot;&gt;Lisp macros: unsafe but powerful&lt;&#x2F;h3&gt;
&lt;p&gt;I don’t have the space here to do a deep dive into Lisp macros, but here’s the short of it: Lisp macros are just functions that receive code as data. This code is represented as nested lists of symbols. All a macro needs to do is return a &lt;em&gt;new&lt;&#x2F;em&gt; list of symbols that will be spliced right into the call site.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;common-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defmacro&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; my-or&lt;&#x2F;span&gt;&lt;span&gt; (thing1 thing2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  `(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; ((tmp ,thing1))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; tmp tmp ,thing2)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; calling the macro&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(my-or &lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; expands to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; ((tmp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; tmp tmp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;=&amp;gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The problem with this is that these macros are &lt;em&gt;unhygienic&lt;&#x2F;em&gt;: if I introduce a new variable, as I did with &lt;code&gt;tmp&lt;&#x2F;code&gt; in &lt;code&gt;my-or&lt;&#x2F;code&gt;, that is just a bare symbol that can be inadvertently captured producing unexpected output:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;common-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; ((tmp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;99&lt;&#x2F;span&gt;&lt;span&gt;)) (my-or &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;nil&lt;&#x2F;span&gt;&lt;span&gt; tmp))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; expands to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; ((tmp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;99&lt;&#x2F;span&gt;&lt;span&gt;)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; ((tmp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;nil&lt;&#x2F;span&gt;&lt;span&gt;)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; tmp tmp tmp))) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;=&amp;gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is very bad! To use a macro safely, you need to be sure that it’s not introducing variables that you might accidentally capture. Lisp provides a mechanism&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to avoid some of the pitfalls with variable capture, but that’s not the end of the danger. If I have a macro that expands to a call to a function, e.g. &lt;code&gt;printf&lt;&#x2F;code&gt;, I would expect this to be the &lt;code&gt;printf&lt;&#x2F;code&gt; in scope at the time I defined the macro. However, this might not be the case—a user might inadvertently redefine a function, and then the macro would not behave in the expected way.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;scheme-macros-safe-but-less-powerful&quot;&gt;Scheme macros: safe but less powerful&lt;&#x2F;h3&gt;
&lt;p&gt;Scheme has a faculty called &lt;code&gt;syntax-rules&lt;&#x2F;code&gt;, which lets you define transformations between a pattern and a template:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;scheme&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-syntax&lt;&#x2F;span&gt;&lt;span&gt; my-or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;syntax-rules&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    ((&lt;&#x2F;span&gt;&lt;span&gt;_ thing1 thing2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span&gt;tmp thing1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                         (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; tmp tmp thing2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;ch19-06-macros.html&quot;&gt;Rust’s &lt;code&gt;macro_rules!&lt;&#x2F;code&gt; form&lt;&#x2F;a&gt; is essentially &lt;code&gt;syntax-rules&lt;&#x2F;code&gt; from Scheme, but a little fancier with some syntax classes like &lt;code&gt;:expr&lt;&#x2F;code&gt; and such.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;This is safe; the examples from the Lisp run as expected:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;scheme&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;my-or &lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;                      ;=&amp;gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;my-or &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;                    ;=&amp;gt; 42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span&gt;tmp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;99&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)) (&lt;&#x2F;span&gt;&lt;span&gt;my-or &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#f&lt;&#x2F;span&gt;&lt;span&gt; tmp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;  ;=&amp;gt; 99&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, we’ve lost some of the power because we can only define transformations between templates. We can’t, for example, write a macro that does some deep inspection of the code and makes decisions on how to expand. Furthermore, there’s no way for us to intentionally break hygiene when we really want to.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;racket-macros-the-best-of-both-worlds&quot;&gt;Racket macros: the best of both worlds&lt;&#x2F;h3&gt;
&lt;p&gt;Racket resolves the dilemma between having to choose between powerful Lisp-like procedural macros, and safe Scheme-like hygienic macros by giving us fully hygienic procedural macros! I have &lt;a href=&quot;&#x2F;posts&#x2F;2023-10-17_fearless_macros&#x2F;&quot;&gt;another blog post discussing macros in Lisp, Scheme, and Racket&lt;&#x2F;a&gt; and I go into some detail about the evolution of those macro systems.&lt;&#x2F;p&gt;
&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;And if you want to dive deep into macro hygiene, see Matthew Butterick’s excellent &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;beautifulracket.com&#x2F;explainer&#x2F;hygiene.html&quot;&gt;explainer on Hygiene&lt;&#x2F;a&gt; from his book &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;beautifulracket.com&#x2F;&quot;&gt;&lt;em&gt;Beautiful Racket&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The upshot of it is that Racket uses a combination of features (scope sets, syntax objects, etc.) to give the user a richer way of specifying syntax than simple dumb lists of symbols. This avoids inadvertent variable capture as well as keeps function references lined up nicely. However, macros can still do arbitrary computation, which means that we’re not constrained in the way that the pattern-transformation macros in Scheme are.&lt;&#x2F;p&gt;
&lt;p&gt;And just to prove that Racket is just as powerful as Common Lisp, here’s the classic &lt;code&gt;aif&lt;&#x2F;code&gt; macro:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#lang&lt;&#x2F;span&gt;&lt;span&gt; racket&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt; racket&#x2F;stxparam syntax&#x2F;parse&#x2F;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;define-syntax-parameter it&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;stx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;raise-syntax-error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;syntax-e&lt;&#x2F;span&gt;&lt;span&gt; stx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;                        &amp;quot;can only be used inside aif&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define-syntax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;aif&lt;&#x2F;span&gt;&lt;span&gt; stx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;syntax-parse stx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt; test tcase fcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;     #&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;tmp test&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; tmp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span&gt;syntax-parameterize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 ([&lt;&#x2F;span&gt;&lt;span&gt;it&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;make-rename-transformer #&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;tmp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;               tcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             fcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;aif&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; it&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;#39;whatever&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt; ;=&amp;gt; 42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;it&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;                          ;error: it: can only be used inside aif&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This example is inspired by Greg Hendershott’s fabulous tutorial &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.greghendershott.com&#x2F;fear-of-macros&#x2F;index.html&quot;&gt;&lt;em&gt;Fear of Macros&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. The &lt;code&gt;define-syntax-parameter&lt;&#x2F;code&gt; bit lets us introduce new bindings &lt;em&gt;intentionally&lt;&#x2F;em&gt;, whilst still keeping us from accidental breaches of macro hygiene.&lt;&#x2F;p&gt;
&lt;p&gt;Consequentially, &lt;strong&gt;Racket’s macro system is far more useful than Lisp or Scheme’s systems, and this because of Racket’s safety and expressiveness.&lt;&#x2F;strong&gt; You can actually build trustworthy systems on top of Racket’s macro system because you’re not constantly foot-gunning yourself with hygiene malfunctions, and the macros are expressive enough to do some &lt;a href=&quot;&#x2F;posts&#x2F;2023-08-14_types_with_macros&#x2F;&quot;&gt;rather complicated things&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;towards-greater-safety-and-reliability&quot;&gt;Towards greater safety and reliability&lt;&#x2F;h2&gt;
&lt;p&gt;Safe systems let us build software that is more capable and more reliable. &lt;strong&gt;Unsafe power is something to improve, not grudgingly accept—and much less defend as somehow desirable.&lt;&#x2F;strong&gt; Languages like Rust and Zig have made systems programming immune to whole hosts of errors by being more expressive than C, and languages like Racket are leading the way in making metaprogramming more useful reliable and less like dark magic.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;p&gt;If you want to learn more about writing macros in Racket, check out &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;beautifulracket.com&#x2F;&quot;&gt;&lt;em&gt;Beautiful Racket&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; by Matthew Butterick and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.greghendershott.com&#x2F;fear-of-macros&#x2F;index.html&quot;&gt;&lt;em&gt;Fear of Macros&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; by Greg Hendershott.&lt;&#x2F;p&gt;
&lt;p&gt;I highly recommend listening Runar Bjarnason’s talk at Scala World, &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=GqmsQeSzMdw&quot;&gt;&lt;em&gt;Constraints Liberate, Liberties Constrain&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, wherein he discusses how constraining one part of a system can open up freedoms of later components that build on that constrained part.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Yes, &lt;em&gt;all&lt;&#x2F;em&gt; the Fibonacci numbers. Haskell is lazy; this will compute as many as you ask for. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;You might think, “well, just document that behavior.” Now I need to read the documentation of &lt;em&gt;every&lt;&#x2F;em&gt; function I encounter—I might as well go read the code to be sure the documentation isn’t out of date. Local reasoning means to understand what &lt;code&gt;do_something_else&lt;&#x2F;code&gt; is passed, I don’t have to worry &lt;em&gt;in the first place&lt;&#x2F;em&gt; if &lt;code&gt;get_name&lt;&#x2F;code&gt; will do somethig to the result of &lt;code&gt;get_user&lt;&#x2F;code&gt;. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;Lisp has a function called &lt;code&gt;gensym&lt;&#x2F;code&gt; which makes a fresh symbol for you to use. Some other languages such as &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.julialang.org&#x2F;en&#x2F;v1&#x2F;base&#x2F;base&#x2F;#Base.gensym&quot;&gt;Julia&lt;&#x2F;a&gt; have a &lt;code&gt;gensym&lt;&#x2F;code&gt; function; &lt;code&gt;gensym&lt;&#x2F;code&gt; is a poor substitute for proper hygiene. &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Towards the Fastest Brainf*** Implementation Ever</title>
        <published>2024-10-22T00:00:00+00:00</published>
        <updated>2024-10-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-10-22_bf_writeup/"/>
        <id>https://beta.lambdaland.org/posts/2024-10-22_bf_writeup/</id>
        
        <summary type="html">&lt;p&gt;In &lt;a href=&quot;&#x2F;posts&#x2F;2024-09-27_threaded_interpreter&#x2F;&quot;&gt;my last post&lt;&#x2F;a&gt; I described how I made a very fast BF interpreter. Well, there’s a lot more speed to be had with an optimizing compiler. This post is a write-up of my assignment for a compilers class, so the post a little rougher than normal.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Make Racket Go (Almost) As Fast As C</title>
        <published>2024-10-15T00:00:00+00:00</published>
        <updated>2024-10-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-09-27_threaded_interpreter/"/>
        <id>https://beta.lambdaland.org/posts/2024-09-27_threaded_interpreter/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-09-27_threaded_interpreter/">&lt;p&gt;I recently wrote about &lt;a href=&quot;&#x2F;posts&#x2F;2024-09-11_parameterized_decisions&#x2F;&quot;&gt;using first-class functions to help make a BF interpreter&lt;&#x2F;a&gt;. This is a follow-up post to describe a nifty solution to a tricky problem that made my program go 2–5× faster and put it about on-par with an interpreter written in pure C.&lt;&#x2F;p&gt;
&lt;p&gt;A basic interpreter works by walking down the AST and evaluating nodes recursively: when the interpreter encounters an expression, it dispatches on the type of expression to decide how to perform the evaluation. Here’s the key insight to get a massive speed bump with very little effort: &lt;em&gt;that dispatch is expensive and can be performed ahead-of-time&lt;&#x2F;em&gt;. We can walk through the code &lt;em&gt;once&lt;&#x2F;em&gt; and precompute all the dispatching work.&lt;&#x2F;p&gt;
&lt;p&gt;This is not a new idea. The first description that I’m aware of comes from Feeley and Lapalme [&lt;a href=&quot;#citeproc_bib_item_1&quot;&gt;1&lt;&#x2F;a&gt;]. A name for this technique is making a &lt;em&gt;threaded interpreter&lt;&#x2F;em&gt;. It’s nowhere near as fast as a native code compiler, but interpreters are easy to write, and this is a very simple way to get a very big boost in performance.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-basic-interpreter&quot;&gt;A basic interpreter&lt;&#x2F;h2&gt;
&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;Please see &lt;a href=&quot;https:&#x2F;&#x2F;beta.lambdaland.org&#x2F;posts&#x2F;2024-09-27_threaded_interpreter&#x2F;#appendix-full-code-for-basic-interpreter&quot;&gt;the appendix&lt;&#x2F;a&gt; for the full code for this interpreter. Tested to run with Racket v8.14 [cs].&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Here’s a simple language and a (simplified) interpreter:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Syntax description&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;params body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; app&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;fn-expr args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;op-name arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; if-expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;test-expr t-case f-case&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Closure values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; closure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;params body env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Core interpreter routine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;interpret&lt;&#x2F;span&gt;&lt;span&gt; expr env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;    ;; Literal values: booleans and numbers evaluate to themselves&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; number?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; boolean?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;    ;; Look up variables in the environment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; symbol?&lt;&#x2F;span&gt;&lt;span&gt; var-name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;lookup-env env var-name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;    ;; Evaluating a function expression yields a closure value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;func params body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;closure params body env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;    ;; Application: evaluate the function expression to get a closure.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;    ;; Next, evaluate the arguments, and then extend the environment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;    ;; and evaluate the body of the closure.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;app fn-expr args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;interpret fn-expr env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;eval-args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;interpret e env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span&gt;interpret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;closure-body fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                  (&lt;&#x2F;span&gt;&lt;span&gt;extend-env env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;closure-params fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; eval-args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;    ;; Built-in operators&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;op op-name a1 a2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;arg1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;interpret a1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;interpret a2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;case&lt;&#x2F;span&gt;&lt;span&gt; op-name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;Undefined operator!&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;    ;; Conditionals&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;if-expr test tcase fcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;interpret test env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span&gt;interpret tcase env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span&gt;interpret fcase env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can now build and run simple programs:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;interpret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;app&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;#39;+ &amp;#39;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; =&amp;gt; 42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is nothing particularly special about this interpreter: there’s a basic representation for programs, and the &lt;code&gt;interpret&lt;&#x2F;code&gt; function walks the AST recursively to evaluate the program.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;threading-the-environment&quot;&gt;Threading the environment&lt;&#x2F;h2&gt;
&lt;p&gt;To make this interpreter go faster, we need bypass the &lt;code&gt;match&lt;&#x2F;code&gt; statement by pre-computing the code to run. We can do this by building up a closure that calls the next thing to run in tail-position. Racket has a proper tail-call optimization, so function calls in tail position will be optimized to &lt;code&gt;jump&lt;&#x2F;code&gt; instructions and they won’t grow the stack. Having known jump targets is also really good for modern CPUs which do speculative execution; known jump targets means no branch mis-predictions.&lt;&#x2F;p&gt;
&lt;p&gt;We do this by breaking up the &lt;code&gt;interpret&lt;&#x2F;code&gt; function: instead of taking an expression and an environment, we want a function that just takes an expression. This should return a function that we can give an environment, which will the compute the value of the program. We will call this new function &lt;code&gt;compile&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; number?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; boolean?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; symbol?&lt;&#x2F;span&gt;&lt;span&gt; var-name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;lookup-env env var-name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;func params body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;comp-body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;closure params comp-body env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;app fn-expr args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; fn-expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;comp-args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map compile&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;fn env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           ((&lt;&#x2F;span&gt;&lt;span&gt;closure-body c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;extend-env env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;closure-params c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;a env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span&gt; comp-args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;op op-name a1 a2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;arg1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; a1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; a2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;case&lt;&#x2F;span&gt;&lt;span&gt; op-name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;Undefined operator!&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;if-expr test tcase fcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;comp-test&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; test&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;comp-tcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; tcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;comp-fcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; fcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;comp-test env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span&gt;comp-tcase env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span&gt;comp-fcase env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note how the code follows the same structure as the basic interpreter, but the return type has changed: instead of a value, you get a function in the form of &lt;code&gt;(λ (env) …)&lt;&#x2F;code&gt;. Also, instead of calling &lt;code&gt;interpret&lt;&#x2F;code&gt; on subexpressions, you call &lt;code&gt;compile&lt;&#x2F;code&gt;, and pass the environment to those subexpressions to get the value out.&lt;&#x2F;p&gt;
&lt;p&gt;There’s a lot more that we could here to improve things. The easiest thing would be to track where variables will be in the environment and optimize variable lookups with direct jumps into the environment structure. This saves us from having to walk the environment linearly on every variable lookup. I won’t implement that here, but that’s some pretty low-hanging fruit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-tricky-part-of-bf-mutual-recursion&quot;&gt;The tricky part of BF: mutual recursion&lt;&#x2F;h2&gt;
&lt;p&gt;So, we get a lot of oomph by turning everything into tail calls. But loops (which, in BF, are the only branching mechanism) present a tricky problem: you either need to call the function that encodes the loop body repeatedly &lt;em&gt;or&lt;&#x2F;em&gt; call the function that encodes whatever comes after the loop. Moreover, once the loop body is done, it needs to jump back to the first function that encodes the choice of whether to keep going in the loop or exit.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s my &lt;code&gt;compile&lt;&#x2F;code&gt; function for &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ashton314&#x2F;brainfreeze&#x2F;blob&#x2F;0a7a5d011c9576a4800edfe56d1e174d5ca638ac&#x2F;interp_threaded.rkt#L40&quot;&gt;my basic threaded interpreter&lt;&#x2F;a&gt; for BF:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; program c-ip jmp-targets inst-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; c-ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-length&lt;&#x2F;span&gt;&lt;span&gt; program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-ref&lt;&#x2F;span&gt;&lt;span&gt; program c-ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;#\+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;rest-progn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; c-ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; jmp-targets inst-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-set!&lt;&#x2F;span&gt;&lt;span&gt; state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-ref&lt;&#x2F;span&gt;&lt;span&gt; state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span&gt;rest-progn state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;#\-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;rest-progn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; c-ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; jmp-targets inst-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-set!&lt;&#x2F;span&gt;&lt;span&gt; state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-ref&lt;&#x2F;span&gt;&lt;span&gt; state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span&gt;rest-progn state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;#\&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;rest-progn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; c-ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; jmp-targets inst-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span&gt;rest-progn state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;#\&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;rest-progn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; c-ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; jmp-targets inst-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span&gt;rest-progn state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;#\.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;rest-progn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; c-ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; jmp-targets inst-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;display&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;integer-&amp;gt;char&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-ref&lt;&#x2F;span&gt;&lt;span&gt; state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span&gt;rest-progn state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;#\,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;rest-progn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; c-ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; jmp-targets inst-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-set!&lt;&#x2F;span&gt;&lt;span&gt; state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;char-&amp;gt;integer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;read-char&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span&gt;rest-progn state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        [(&lt;&#x2F;span&gt;&lt;span&gt;jmp-forward target&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;letrec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;loop-start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                                (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;zero?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-ref&lt;&#x2F;span&gt;&lt;span&gt; state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                                    (&lt;&#x2F;span&gt;&lt;span&gt;loop-end state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                                    (&lt;&#x2F;span&gt;&lt;span&gt;loop-body state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                  [&lt;&#x2F;span&gt;&lt;span&gt;loop-past-end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; c-ip target&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; jmp-targets inst-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                  [&lt;&#x2F;span&gt;&lt;span&gt;loop-end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; c-ip target&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cons&lt;&#x2F;span&gt;&lt;span&gt; loop-start loop-past-end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; inst-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                  [&lt;&#x2F;span&gt;&lt;span&gt;loop-body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; c-ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt; inst-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           loop-start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        [(&lt;&#x2F;span&gt;&lt;span&gt;jmp-backward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;zero?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-ref&lt;&#x2F;span&gt;&lt;span&gt; state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cdr&lt;&#x2F;span&gt;&lt;span&gt; jmp-targets&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;car&lt;&#x2F;span&gt;&lt;span&gt; jmp-targets&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; state sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_state _sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;           ; finished compiling program&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;        void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I match on each of the characters of the program. In my interpreter I do a little bit of preprocessing to turn &lt;code&gt;[&lt;&#x2F;code&gt; and &lt;code&gt;]&lt;&#x2F;code&gt; into &lt;code&gt;jmp-forward&lt;&#x2F;code&gt; and &lt;code&gt;jmp-backward&lt;&#x2F;code&gt; structs respectively. That way, I don’t have to spend a ton of time scanning the program for matching brackets.&lt;&#x2F;p&gt;
&lt;p&gt;The interesting bit is the clause for the &lt;code&gt;jmp-forward&lt;&#x2F;code&gt; construct: to build the closure I need at a &lt;code&gt;loop-start&lt;&#x2F;code&gt;, I need to be able to refer to the loop body (computed and stored in &lt;code&gt;loop-body&lt;&#x2F;code&gt;) as well as the end of the loop (computed and stored in &lt;code&gt;loop-end&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;When I build the &lt;code&gt;loop-end&lt;&#x2F;code&gt; closure, pass &lt;code&gt;loop-start&lt;&#x2F;code&gt; and &lt;code&gt;loop-past-end&lt;&#x2F;code&gt; (which is the rest of the program &lt;em&gt;after&lt;&#x2F;em&gt; the loop) into the &lt;code&gt;compile&lt;&#x2F;code&gt; function as the &lt;code&gt;jmp-targets&lt;&#x2F;code&gt; parameter. When the compiler encounters the matching &lt;code&gt;jmp-backward&lt;&#x2F;code&gt; instruction, it uses the &lt;code&gt;jmp-targets&lt;&#x2F;code&gt; parameter to get the &lt;code&gt;loop-start&lt;&#x2F;code&gt; and &lt;code&gt;loop-past-end&lt;&#x2F;code&gt; to decide whether or not to redo the loop or not.&lt;&#x2F;p&gt;
&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;I’ve since improved this code, and now the &lt;code&gt;zero?&lt;&#x2F;code&gt; check only happens once. I also parse the program so that every instruction gets turned into a struct—rather than left as a bare character. See &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ashton314&#x2F;brainfreeze&#x2F;blob&#x2F;main&#x2F;interp_threaded_opt.rkt&quot;&gt;interp_threaded_opt.rkt&lt;&#x2F;a&gt; in my Brainfreeze repo for the current version.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The &lt;code&gt;loop-start&lt;&#x2F;code&gt; and &lt;code&gt;loop-end&lt;&#x2F;code&gt; functions need to reference each other to be able to continue or abort the loop. &lt;code&gt;letrec&lt;&#x2F;code&gt; lets me build functions that can reference each other in a clean, functional way.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;let-s-see-some-numbers&quot;&gt;Let’s see some numbers!&lt;&#x2F;h2&gt;
&lt;p&gt;So how much faster does threading make the code go? &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cwfitzgerald&#x2F;brainfuck-benchmark&#x2F;blob&#x2F;2e10658581ce0c81b02e858e292984cf8e5df96a&#x2F;benches&#x2F;mandel.b&quot;&gt;Here&lt;&#x2F;a&gt; is a BF program that renders a Mandelbrot set. I can run this with my basic and my threaded interpreter on my M1 Pro MacBook Pro to get an idea:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;racket&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; interp_basic.rkt bench&#x2F;benches&#x2F;mandel.b  43.25s user 0.77s system 93% cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 47.138&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; total&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;racket&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; interp_threaded.rkt bench&#x2F;benches&#x2F;mandel.b  17.62s user 0.38s system 92% cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 19.461&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; total&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;43.25 seconds&lt;&#x2F;code&gt; vs &lt;code&gt;17.62 seconds&lt;&#x2F;code&gt; is a big difference! That’s a solid 2× speedup! This actually put my threaded Racket interpreter on par with a C-based threaded interpreter that one of my classmates built and ran with the same benchmarks. If I recall, his was only about a second or two faster.&lt;&#x2F;p&gt;
&lt;p&gt;The compile step opens up a big opportunity for optimizations. I’ve been working on some domain-specific optimizations for BF and my interpreter can run the same benchmark in a blazing &lt;code&gt;9.94 seconds&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;racket&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; runner.rkt bench&#x2F;benches&#x2F;mandel.b  9.94s user 0.18s system 94% cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 10.707&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; total&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(And, of course, none of this really holds a candle to a proper compiler; I’ve to a compiler that takes the optimized code from the threaded interpreter and emits machine code. It can run &lt;code&gt;mandel.b&lt;&#x2F;code&gt; in a mere &lt;code&gt;0.5 seconds&lt;&#x2F;code&gt;!)&lt;&#x2F;p&gt;
&lt;p&gt;I hope you take away a few things from this post:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Proper tail-calls make stuff go fast. If your language supports proper tail-call optimization, take advantage of it.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Racket is &lt;em&gt;really good&lt;&#x2F;em&gt; for writing interpreters and compilers! You can get very fast performance in the comfort of a high-level garbage-collected functional programming language.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Racket will never be able to match the best-written C code in terms of speed. But Racket is far easier to debug and a lot more fun to write—and for a lot of applications, Racket is still more than fast enough.&lt;&#x2F;p&gt;
&lt;div class=&quot;epigraph&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;A bad day writing code in Scheme is better than a good day writing code in C.&lt;&#x2F;p&gt;
&lt;footer&gt;
&lt;p&gt;David Stigant&lt;&#x2F;p&gt;
&lt;&#x2F;footer&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;appendix-full-code-for-basic-interpreter&quot;&gt;Appendix: Full code for basic interpreter&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#lang&lt;&#x2F;span&gt;&lt;span&gt; racket&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Syntax description&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;params body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; app&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;fn-expr args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;op-name arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; if-expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;test-expr t-case f-case&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Closure values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; closure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;params body env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Environment helpers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;extend-env&lt;&#x2F;span&gt;&lt;span&gt; base-env vars vals&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;foldl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;var val env-acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cons&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cons&lt;&#x2F;span&gt;&lt;span&gt; var val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; env-acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span&gt; base-env vars vals&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;lookup-env&lt;&#x2F;span&gt;&lt;span&gt; env var&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;assoc&lt;&#x2F;span&gt;&lt;span&gt; var env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cons _&lt;&#x2F;span&gt;&lt;span&gt; val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;Undefined variable!&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Core interpreter routine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;interpret&lt;&#x2F;span&gt;&lt;span&gt; expr env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; number?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; boolean?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; symbol?&lt;&#x2F;span&gt;&lt;span&gt; var-name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;lookup-env env var-name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;func params body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;closure params body env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;app fn-expr args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;interpret fn-expr env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;eval-args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;interpret e env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span&gt;interpret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;closure-body fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                  (&lt;&#x2F;span&gt;&lt;span&gt;extend-env env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;closure-params fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; eval-args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;op op-name a1 a2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;arg1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;interpret a1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;interpret a2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;case&lt;&#x2F;span&gt;&lt;span&gt; op-name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;Undefined operator!&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;if-expr test tcase fcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;interpret test env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span&gt;interpret tcase env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span&gt;interpret fcase env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;appendix-full-code-for-threading-interpreter&quot;&gt;Appendix: Full code for threading interpreter&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#lang&lt;&#x2F;span&gt;&lt;span&gt; racket&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Syntax description&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;params body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; app&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;fn-expr args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;op-name arg1 arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; if-expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;test-expr t-case f-case&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Closure values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; closure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;params body env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Environment helpers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;extend-env&lt;&#x2F;span&gt;&lt;span&gt; base-env vars vals&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;foldl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;var val env-acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cons&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cons&lt;&#x2F;span&gt;&lt;span&gt; var val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; env-acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span&gt; base-env vars vals&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;lookup-env&lt;&#x2F;span&gt;&lt;span&gt; env var&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;assoc&lt;&#x2F;span&gt;&lt;span&gt; var env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cons _&lt;&#x2F;span&gt;&lt;span&gt; val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;Undefined variable!&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Threading interpreter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; number?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; boolean?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; symbol?&lt;&#x2F;span&gt;&lt;span&gt; var-name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;lookup-env env var-name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;func params body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;comp-body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;closure params comp-body env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;app fn-expr args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; fn-expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;comp-args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map compile&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;fn env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           ((&lt;&#x2F;span&gt;&lt;span&gt;closure-body c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;extend-env env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;closure-params c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;a env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span&gt; comp-args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;op op-name a1 a2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;arg1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; a1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; a2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;case&lt;&#x2F;span&gt;&lt;span&gt; op-name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;arg1 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;arg2 env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;Undefined operator!&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span&gt;if-expr test tcase fcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;comp-test&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; test&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;comp-tcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; tcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           [&lt;&#x2F;span&gt;&lt;span&gt;comp-fcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt; fcase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;comp-test env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span&gt;comp-tcase env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span&gt;comp-fcase env&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; compute 42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span&gt; p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;app&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;#39;+ &amp;#39;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;style&gt;.csl-left-margin{float: left; padding-right: 0em;}
 .csl-right-inline{margin: 0 0 0 1em;}&lt;&#x2F;style&gt;&lt;div class=&quot;csl-bib-body&quot;&gt;
  &lt;div class=&quot;csl-entry&quot;&gt;&lt;a id=&quot;citeproc_bib_item_1&quot;&gt;&lt;&#x2F;a&gt;
    &lt;div class=&quot;csl-left-margin&quot;&gt;[1]&lt;&#x2F;div&gt;&lt;div class=&quot;csl-right-inline&quot;&gt;Feeley, M. and Lapalme, G. 1987. Using closures for code generation. &lt;i&gt;Computer languages&lt;&#x2F;i&gt;. 12, 1 (Jan. 1987), 47–66. DOI:&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1016&#x2F;0096-0551(87)90012-9&quot;&gt;https:&#x2F;&#x2F;doi.org&#x2F;10.1016&#x2F;0096-0551(87)90012-9&lt;&#x2F;a&gt;.&lt;&#x2F;div&gt;
  &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why You Should Resist Surveillance</title>
        <published>2024-09-26T00:00:00+00:00</published>
        <updated>2024-09-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-09-26_resist_surveillance/"/>
        <id>https://beta.lambdaland.org/posts/2024-09-26_resist_surveillance/</id>
        
        <summary type="html">&lt;p&gt;I got to visit the Stasi museum in Berlin this week, and it gave me a newfound appreciation for why it’s important to resist surveillance. Interestingly, surveillance is not exclusively limited to one kind of government: it can appeal to both left- and right-wing governments, and corporations in the digital age use surveillance to make money. In every form, surveillance is evil and must be resisted.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>First-Class Helper Functions</title>
        <published>2024-09-11T00:00:00+00:00</published>
        <updated>2024-09-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-09-11_parameterized_decisions/"/>
        <id>https://beta.lambdaland.org/posts/2024-09-11_parameterized_decisions/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-09-11_parameterized_decisions/">&lt;p&gt;We’re going to be writing a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Brainfuck&quot;&gt;BF&lt;&#x2F;a&gt; compiler for a class I’m in. Last night I threw together a little interpreter for the program in about an hour; it doesn’t do input—that should be easy to add—but it’s enough to handle &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cwfitzgerald&#x2F;brainfuck-benchmark&quot;&gt;some benchmarks&lt;&#x2F;a&gt; for the language, albeit slowly. You can see my repository &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;brainfreeze&quot;&gt;on Codeberg&lt;&#x2F;a&gt; for the source code.&lt;&#x2F;p&gt;
&lt;p&gt;I needed one function to do two closely related jobs—the logic was identical, but some parameters needed to change. Fortunately, first-class functions in your language make it trivial to parameterize your programs in elegant ways.&lt;&#x2F;p&gt;
&lt;p&gt;For those unfamiliar, a BF program looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;++++++++++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;+++++++&amp;gt;++++++++++&amp;gt;+++&amp;gt;+&amp;lt;&amp;lt;&amp;lt;&amp;lt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;++.&amp;gt;+.+++++++..+++.&amp;gt;++.&amp;lt;&amp;lt;+++++++++++++++.&amp;gt;.+++.------.--------.&amp;gt;+.&amp;gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That program prints &lt;code&gt;Hello, World!&lt;&#x2F;code&gt;. Here’s the spec for the language, taken from &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sunjay&#x2F;brainfuck&#x2F;blob&#x2F;master&#x2F;brainfuck.md&quot;&gt;this repo&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;gt;&lt;&#x2F;code&gt;  move the pointer right&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;&lt;&#x2F;code&gt;  move the pointer left&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;+&lt;&#x2F;code&gt;  increment the current cell&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;-&lt;&#x2F;code&gt;  decrement the current cell&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;.&lt;&#x2F;code&gt;  output the value of the current cell&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;,&lt;&#x2F;code&gt;  replace the value of the current cell with input&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;[&lt;&#x2F;code&gt;  jump to the matching &lt;code&gt;]&lt;&#x2F;code&gt; instruction if the current value is zero&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;]&lt;&#x2F;code&gt;  jump to the matching &lt;code&gt;[&lt;&#x2F;code&gt; instruction if the current value is &lt;strong&gt;not&lt;&#x2F;strong&gt; zero&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Basically, BF is a little Turing machine: you have a big array of memory and a pointer into that array. The commands move the pointer around and can set or check the value pointed at.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;[&lt;&#x2F;code&gt; and &lt;code&gt;]&lt;&#x2F;code&gt; characters form loops and need to be balanced. In my interpreter I wanted to run a preprocessing step so that when I encountered a &lt;code&gt;[&lt;&#x2F;code&gt; or a &lt;code&gt;]&lt;&#x2F;code&gt; I would know how far to jump instead of having to search the program for the matching bracket. Here’s the top-level function to modify the program vector to replace &lt;code&gt;[&lt;&#x2F;code&gt; and &lt;code&gt;]&lt;&#x2F;code&gt; with a struct containing how far to jump:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; jmp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;amount&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; jmp-forward jmp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;  ; replaces a [ command&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; jmp-backward jmp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt; ; replaces a ] command&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;preprocess-loops!&lt;&#x2F;span&gt;&lt;span&gt; prog&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;in-range&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-length&lt;&#x2F;span&gt;&lt;span&gt; prog&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-ref&lt;&#x2F;span&gt;&lt;span&gt; prog i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;#\[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-set!&lt;&#x2F;span&gt;&lt;span&gt; prog i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;find-matching prog i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;#39;close&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;#\]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-set!&lt;&#x2F;span&gt;&lt;span&gt; prog i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;find-matching prog i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; -1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;#39;open&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;])))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That &lt;code&gt;find-matching&lt;&#x2F;code&gt; function was a little tricky: in the case of searching for a &lt;code&gt;]&lt;&#x2F;code&gt; it would have to walk &lt;em&gt;forward&lt;&#x2F;em&gt; looking for a &lt;code&gt;]&lt;&#x2F;code&gt; character or a &lt;code&gt;(jmp-backward …)&lt;&#x2F;code&gt; struct, and it would have to walk &lt;em&gt;backward&lt;&#x2F;em&gt; looking for a &lt;code&gt;[&lt;&#x2F;code&gt; character or &lt;code&gt;(jmp-forward …)&lt;&#x2F;code&gt; struct. The naïve way to do this would be to have a bunch of &lt;code&gt;if&lt;&#x2F;code&gt; expressions dispatching on the &lt;code&gt;&#x27;close&lt;&#x2F;code&gt; or &lt;code&gt;&#x27;open&lt;&#x2F;code&gt; passed to &lt;code&gt;find-matching&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;find-matching&lt;&#x2F;span&gt;&lt;span&gt; prog start offset kind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; start offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         [&lt;&#x2F;span&gt;&lt;span&gt;current-instr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-ref&lt;&#x2F;span&gt;&lt;span&gt; prog addr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;eq?&lt;&#x2F;span&gt;&lt;span&gt; kind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;#39;close&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;eqv?&lt;&#x2F;span&gt;&lt;span&gt; current-instr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; #\]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;jmp-backward? current-instr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;zero?&lt;&#x2F;span&gt;&lt;span&gt; stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                (&lt;&#x2F;span&gt;&lt;span&gt;jmp-forward offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                (&lt;&#x2F;span&gt;&lt;span&gt;find-matching prog start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; kind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;  ; this isn&amp;#39;t our close ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;eqv?&lt;&#x2F;span&gt;&lt;span&gt; current-instr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; #\[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;jmp-forward? current-instr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                (&lt;&#x2F;span&gt;&lt;span&gt;find-matching prog start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; kind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;   ; deepen stack because we found another [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                (&lt;&#x2F;span&gt;&lt;span&gt;find-matching prog start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; kind stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;eqv?&lt;&#x2F;span&gt;&lt;span&gt; current-instr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; #\[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;jmp-forward? current-instr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;zero?&lt;&#x2F;span&gt;&lt;span&gt; stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;                ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;eqv?&lt;&#x2F;span&gt;&lt;span&gt; current-instr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; #\]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;jmp-backward? current-instr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;                ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;                ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The need for a stack to find matching delimiters should be pretty obvious: if I have an open bracket &lt;code&gt;[&lt;&#x2F;code&gt; and am looking for the matching close bracket &lt;code&gt;]&lt;&#x2F;code&gt;, then I need to make sure I don’t get confused by other open-close pairs in between.&lt;&#x2F;p&gt;
&lt;p&gt;The function above is pretty clunky: all the logic for checking if the stack is empty gets duplicated, and the logic for adding&#x2F;decrementing the stack is a mirror image between the two branches of &lt;code&gt;if (eq? kind &#x27;close)&lt;&#x2F;code&gt;. There might be a few ways to rearrange this example so that it’s a little better, but there’s one big change we can make.&lt;&#x2F;p&gt;
&lt;p&gt;The key insight is this: we have first-class functions, so why not parameterize the condition we use to check the current command to know if we should push the stack, pop the stack, or return a new struct? Here’s how we do it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;find-matching&lt;&#x2F;span&gt;&lt;span&gt; prog start offset kind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;close?&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;jmp-backward? x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;eqv?&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; #\]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;open?&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;jmp-forward? x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;eqv?&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; #\[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span&gt; addr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; start offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let-values&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([(&lt;&#x2F;span&gt;&lt;span&gt;needle-pred other-pred bump jmp-maker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;eq?&lt;&#x2F;span&gt;&lt;span&gt; kind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;#39;close&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;values&lt;&#x2F;span&gt;&lt;span&gt; close? open?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; jmp-forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;values&lt;&#x2F;span&gt;&lt;span&gt; open? close?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; -1&lt;&#x2F;span&gt;&lt;span&gt; jmp-backward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;needle-pred&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-ref&lt;&#x2F;span&gt;&lt;span&gt; prog addr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;zero?&lt;&#x2F;span&gt;&lt;span&gt; stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;jmp-maker offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;find-matching prog start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; bump offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; kind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;other-pred&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;vector-ref&lt;&#x2F;span&gt;&lt;span&gt; prog addr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;find-matching prog start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; bump offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; kind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;find-matching prog start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; bump offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; kind stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we have &lt;code&gt;needle-pred&lt;&#x2F;code&gt;, which returns true if the current command is the current thing we’re looking for; &lt;code&gt;other-pred&lt;&#x2F;code&gt;, which tells us if we need to increase the stack; &lt;code&gt;bump&lt;&#x2F;code&gt;, which just tells us which way to move the offset; and &lt;code&gt;jmp-maker&lt;&#x2F;code&gt; which we use to build the right kind of struct to return when we’ve found the matching delimiter and the stack is empty.&lt;&#x2F;p&gt;
&lt;p&gt;I really like that &lt;code&gt;let-values&lt;&#x2F;code&gt; lets me bind a bunch of variables on a single condition; other languages can do something similar if they have e.g. tuples and rich pattern matching.&lt;&#x2F;p&gt;
&lt;p&gt;First-class functions are a powerful way to parameterize your code, and it doesn’t just have to be with higher-order functions. Clearly, generic functions like &lt;code&gt;map&lt;&#x2F;code&gt; and &lt;code&gt;filter&lt;&#x2F;code&gt; would be basically useless without the ability to take functions as parameters. But you can also tailor the behavior of your program by pushing the differences between two or more possible scenarios into functions, and then select the proper set of functions in one conditional.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fancy lightweight prompts for Eshell and Zsh</title>
        <published>2024-08-19T00:00:00+00:00</published>
        <updated>2024-08-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-08-19_fancy_eshell_prompt/"/>
        <id>https://beta.lambdaland.org/posts/2024-08-19_fancy_eshell_prompt/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-08-19_fancy_eshell_prompt/">&lt;p&gt;I started using the Zsh a few years ago and I’ve liked its completion features. I tried out Oh-my-zsh for a while and I liked the stock Robby Russel prompt. It gave me all the information I cared about: the status of the last command, current directory, and the state of the current Git repository.&lt;&#x2F;p&gt;
&lt;p&gt;However, I didn’t like how slow Oh-my-zsh was making my shell startup. This mattered especially, I think, because my Emacs config would fire up a shell on startup to read the &lt;code&gt;ENV&lt;&#x2F;code&gt; so it could configure some language servers properly. Irked at how long stuff was taking, I set out to build my own.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fancy-zsh-prompt-no-extra-packages-needed&quot;&gt;Fancy Zsh prompt, no extra packages needed&lt;&#x2F;h2&gt;
&lt;p&gt;Here’s the code for my Zsh prompt:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;# This is important to make some things play nicely with Emacs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;# They&amp;#39;re not critical to the shell prompt per se, but I think they&amp;#39;re&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;# pretty useful.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;# Bail out of rest of setup if we&amp;#39;re coming in from TRAMP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;[[&lt;&#x2F;span&gt;&lt;span&gt; $TERM&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;dumb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; ]] &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; unsetopt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; zle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; PS1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;$ &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$EAT_SHELL_INTEGRATION_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; ] &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; source&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$EAT_SHELL_INTEGRATION_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&#x2F;zsh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;# This tells the shell to expand the call to $(git_prompt_info)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;setopt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; PROMPT_SUBST&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;# This is a function that gathers information about the current HEAD.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;# It will show the name of the branch if there is one, otherwise the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;# short hash of the currently checked-out commit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;git_prompt_info&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; () {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    local&lt;&#x2F;span&gt;&lt;span&gt; ref&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; symbolic-ref HEAD&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; 2&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &#x2F;dev&#x2F;null&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; rev-parse --short HEAD&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; 2&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &#x2F;dev&#x2F;null&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; || return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    local&lt;&#x2F;span&gt;&lt;span&gt; STATUS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    local&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; -a&lt;&#x2F;span&gt;&lt;span&gt; FLAGS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    FLAGS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;--porcelain&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; [[ &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;DISABLE_UNTRACKED_FILES_DIRTY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;:-}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; ]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    FLAGS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;--untracked-files=no&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;GIT_STATUS_IGNORE_SUBMODULES&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;:-}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBCB8B;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;)  ;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; FLAGS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;--ignore-submodules=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;GIT_STATUS_IGNORE_SUBMODULES&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;:-&lt;&#x2F;span&gt;&lt;span&gt;dirty&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  ;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    esac&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    STATUS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; status&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ${&lt;&#x2F;span&gt;&lt;span&gt;FLAGS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;} 2&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &#x2F;dev&#x2F;null&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; tail&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; -n1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span&gt; $STATUS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; %F{red}[%F{yellow}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span&gt;refs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&#x2F;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;%F{red}]%f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; %F{green}(%F{yellow}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span&gt;refs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&#x2F;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;%F{green})%f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;# If I&amp;#39;m on my home machine, don&amp;#39;t show the hostname in the prompt.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; [[ `&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;hostname&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =~&lt;&#x2F;span&gt;&lt;span&gt; ^my-home-machine.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    PROMPT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;%(?:%F{green}➤:%F{red}!%?)%f %F{cyan}%~%f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBCB8B;&quot;&gt;\$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;(git_prompt_info) %(!:# :)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;    # Add &amp;quot;%m&amp;quot; to print the short hostname on other servers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    PROMPT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;%(?:%F{green}➤:%F{red}!%?)%f %F{blue}%m%f:%F{cyan}%~%f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBCB8B;&quot;&gt;\$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;(git_prompt_info) %(!:# :)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here’s what the shell looks like in a clean repository:&lt;&#x2F;p&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;fancy_shells&#x2F;clean.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;And here’s what it looks like in a repository with some uncommitted changes:&lt;&#x2F;p&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;fancy_shells&#x2F;dirty.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;The green prompt will change to a red &lt;code&gt;!&lt;&#x2F;code&gt; and show the exit status of the last command if it was anything other than 0.&lt;&#x2F;p&gt;
&lt;p&gt;This should run pretty quick. The Git functions take almost no time to run, and the rest is straight-line Zsh script. Using this I was able to stop using Oh-my-zsh and dramatically reduce my shell startup time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;eshell-prompt&quot;&gt;Eshell prompt&lt;&#x2F;h2&gt;
&lt;p&gt;I recently started using &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.masteringemacs.org&#x2F;article&#x2F;complete-guide-mastering-eshell&quot;&gt;Eshell&lt;&#x2F;a&gt; in Emacs, and I wanted the same prompt there as I had in my terminal. Here’s how I got the same prompt, using some functions for the incomparable &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;magit.vc&#x2F;&quot;&gt;Magit&lt;&#x2F;a&gt; Git porcelain.&lt;&#x2F;p&gt;
&lt;p&gt;First, you need to define a function that generates the prompt for the current directory:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defun&lt;&#x2F;span&gt;&lt;span&gt; fancy-shell&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;A pretty shell with git status&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span&gt;cwd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;abbreviate-file-name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;eshell&#x2F;pwd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span&gt;ref &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;magit-get-shortname &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;HEAD&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span&gt;stat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;magit-file-status&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span&gt;x-stat eshell-last-command-status&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;         (&lt;&#x2F;span&gt;&lt;span&gt;git-chunk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ref&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;%s%s%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;propertize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; stat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;font-lock-face&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt;foreground&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; stat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;red&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;green&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;propertize&lt;&#x2F;span&gt;&lt;span&gt; ref &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;font-lock-face&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;(:&lt;&#x2F;span&gt;&lt;span&gt;foreground&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;yellow&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;propertize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; stat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;font-lock-face&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt;foreground&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; stat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;red&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;green&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            &amp;quot;&amp;quot;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;propertize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;%s %s %s$ &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; x-stat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;propertize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;!%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;font-lock-face&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;(:&lt;&#x2F;span&gt;&lt;span&gt;foreground&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;red&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))&lt;&#x2F;span&gt;&lt;span&gt; x-stat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;propertize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;➤&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;font-lock-face&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt;foreground&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; x-stat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;red&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;green&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;propertize&lt;&#x2F;span&gt;&lt;span&gt; cwd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;font-lock-face&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;(:&lt;&#x2F;span&gt;&lt;span&gt;foreground&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;#45babf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             git-chunk&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;read-only t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;front-sticky&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   &amp;#39;(&lt;&#x2F;span&gt;&lt;span&gt;font-lock-face read-only&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;rear-nonsticky&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;(&lt;&#x2F;span&gt;&lt;span&gt;font-lock-face read-only&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now that that function is defined, you can tell Eshell to use that to make the shell prompt. (It’s also good to set &lt;code&gt;eshell-prompt-regexp&lt;&#x2F;code&gt; so it knows where the prompt begins and ends.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;setopt eshell-prompt-function &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;fancy-shell&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;setopt eshell-prompt-regexp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;^[^#$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;\&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;n]* [$#] &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;setopt eshell-highlight-prompt &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It looks basically the same as the Zsh prompt, except there’s always a &lt;code&gt;$&lt;&#x2F;code&gt; character at the end of the prompt. This is just to make Emacs’ prompt-parsing easier.&lt;&#x2F;p&gt;
&lt;p&gt;If you are curious about using Eshell, you should use Eshell in concert with &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;akib&#x2F;emacs-eat&quot;&gt;Eat&lt;&#x2F;a&gt;, which runs commands in a little terminal emulator. This makes interactive programs like code REPLs or programs that use character escape codes work correctly. (You can even run &lt;code&gt;emacs -nw&lt;&#x2F;code&gt; and have it work! Madness!) I can use Eshell for more than 90% of what I need to do in a shell now, and that’s pretty nice.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Notes on Zero-Knowledge Proofs and Secure Remote Password (SRP) Protocol</title>
        <published>2024-08-06T00:00:00+00:00</published>
        <updated>2024-08-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-08-06_zkp/"/>
        <id>https://beta.lambdaland.org/posts/2024-08-06_zkp/</id>
        
        <summary type="html">&lt;p&gt;Today I learned about using zero-knowledge proofs in the context of passwords. These are my rough-and-ready notes from reading. Apparently OpenSSL has an implementation of the SRP algorithm.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>How, Where, and Why I Take Notes</title>
        <published>2024-07-29T00:00:00+00:00</published>
        <updated>2024-07-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-07-29_note_mediums/"/>
        <id>https://beta.lambdaland.org/posts/2024-07-29_note_mediums/</id>
        
        <summary type="html">&lt;p&gt;I take a blend of digital and hand-written notes. It’s a bit of a hodgepodge, but it’s working. I used to lean heavily into full-digital notes, but I started drifting towards a mixture of digital and hand-written notes. Initially it was complicated, but I think I’m converging on a good setup. What I describe here will continue to evolve I am sure, but I am enjoying where it’s currently at.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Evolving Languages Faster with Type Tailoring</title>
        <published>2024-07-15T00:00:00+00:00</published>
        <updated>2024-07-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-07-15_type_tailoring/"/>
        <id>https://beta.lambdaland.org/posts/2024-07-15_type_tailoring/</id>
        
        <summary type="html">&lt;p&gt;Programming languages are too slow! I’m not talking about &lt;em&gt;execution&lt;&#x2F;em&gt; speed—I’m talking about &lt;em&gt;evolution&lt;&#x2F;em&gt; speed. Programmers are always building new libraries and embedded DSLs, but the host programming language—particularly its type system—doesn’t understand the domain-specific aspects of these things.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Skills That I Needed When I Started My PhD</title>
        <published>2024-07-09T00:00:00+00:00</published>
        <updated>2024-07-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-07-09_phd_tools/"/>
        <id>https://beta.lambdaland.org/posts/2024-07-09_phd_tools/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-07-09_phd_tools/">&lt;p&gt;I’m starting my third year as a PhD student. I thought it would be good to look back on some of the things that have helped me to this point. I study programming languages, but I imagine these things will help anyone in computer science—and some might have application to other STEM fields as well.&lt;&#x2F;p&gt;
&lt;p&gt;There are &lt;em&gt;many&lt;&#x2F;em&gt; softer skills that you need as a PhD student: curiosity, good work ethic, organization, etc. These are essential and nothing can replace them. (Note: that was &lt;em&gt;not&lt;&#x2F;em&gt; an exhaustive list.) I’m going to focus on some of the tools and hard skills that made the ride a little more comfortable. These compliment, rather than compete with, the softer skills that one develops as a beginning researcher.&lt;&#x2F;p&gt;
&lt;p&gt;This is a rough list, and not a how-to article. This is mostly just a collection of things I’ve seen other people &lt;em&gt;lacking&lt;&#x2F;em&gt; that have caused them to struggle. If you are considering doing a PhD, you might want to pick up some of these skills as you get ready to start to help you hit the ground running.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;software-engineering&quot;&gt;Software engineering&lt;&#x2F;h2&gt;
&lt;p&gt;I recommend reading &lt;em&gt;The Pragmatic Programmer&lt;&#x2F;em&gt; (Thomas, David and Hunt, Andrew, 2019). It’s written primarily for industry programmers, but there’s a lot in there that applies to anyone in CS research. All of the things I mention in this section are covered in detail in there.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;version-control&quot;&gt;Version Control&lt;&#x2F;h3&gt;
&lt;p&gt;You have got to know Git. If you cannot wrangle versions of your software and papers (yes, put the papers you write under version control) you will waste much time shooting yourself in the foot and trying to recover work you lost. You will also be laughed to scorn should you ever depart academia for a stint in industry if you do not know Git.&lt;&#x2F;p&gt;
&lt;p&gt;In all of the papers I have worked on, we have used Git to collaborate. We’ve typically used GitHub, which is fine as forges go, but I’ve also worked with a self-hosted GitLab instance, and that was fine too.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;scripting&quot;&gt;Scripting&lt;&#x2F;h3&gt;
&lt;p&gt;It is incredibly helpful to know a scripting language. I grew up on Perl, which makes munging large amounts of text a piece of cake. You don’t have to learn Perl; you should get really comfortable with a language that makes it easy to manipulate text and files.&lt;&#x2F;p&gt;
&lt;p&gt;Makefiles are also super helpful. I like using Makefiles to simply give names to a particular workflow. A Makefile for building a paper might look like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;make&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;paper.pdf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; paper.tex&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    latexmk -lualatex paper&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;.PHONY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; clean&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;clean&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @echo Cleanup time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    latexmk -c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rm -f paper.pdf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, instead of remembering all the incantations necessary to do some task, I have given that task a &lt;em&gt;name&lt;&#x2F;em&gt; by which I can call it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;command-line&quot;&gt;Command line&lt;&#x2F;h3&gt;
&lt;p&gt;You must become proficient with the command line. If you are doing research, you will likely need to run software that other researchers have produced. And more likely than not, this will be &lt;em&gt;rough&lt;&#x2F;em&gt; software with bugs and sharp edges that is meant to demonstrate some research concept than be some practical tool ready for developers who only know how to code through YouTube videos and ChatGPT. That this software is rough is a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;matt.might.net&#x2F;articles&#x2F;crapl&#x2F;&quot;&gt;feature of research software&lt;&#x2F;a&gt;, not a bug. &lt;strong&gt;There is &lt;em&gt;rarely&lt;&#x2F;em&gt;, if ever, a GUI available.&lt;&#x2F;strong&gt; You are going to have to do stuff on the command line, so get used to it.&lt;&#x2F;p&gt;
&lt;p&gt;Getting used to the command line helps with &lt;a href=&quot;https:&#x2F;&#x2F;beta.lambdaland.org&#x2F;posts&#x2F;2024-07-09_phd_tools&#x2F;#scripting&quot;&gt;Scripting&lt;&#x2F;a&gt; as well. Any task you do on the command line, you can write a script to automate. Building little scripts to e.g. build your paper, your homework, your experiments, etc. will save you time in the long run.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;know-thy-editor&quot;&gt;Know thy editor&lt;&#x2F;h3&gt;
&lt;p&gt;Emacs or Vim—pick one and learn it &lt;em&gt;really&lt;&#x2F;em&gt; well. VS Code is flashy and all, but it doesn’t have the same depth and breadth of customizations that Emacs and Vim give you. Also, Emacs and Vim are free software. You are in control!&lt;&#x2F;p&gt;
&lt;p&gt;I, of course, &lt;a href=&quot;&#x2F;tags&#x2F;emacs&#x2F;&quot;&gt;love Emacs&lt;&#x2F;a&gt; and I even made a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;emacs-bedrock&quot;&gt;starter kit called Bedrock&lt;&#x2F;a&gt; to help some of my friends in my research lab get started with Emacs. I use Emacs to program, write papers, take notes, manage email, track tasks, and more. I made a list of &lt;a href=&quot;&#x2F;posts&#x2F;2024-05-30_top_emacs_packages&#x2F;&quot;&gt;my top Emacs packages&lt;&#x2F;a&gt; a few weeks ago if you’d like more ideas on what is possible.&lt;&#x2F;p&gt;
&lt;p&gt;Vim is fine too and I will still respect you if you choose to go that route. ;)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;authoring-papers&quot;&gt;Authoring papers&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;latex&quot;&gt;LaTeX&lt;&#x2F;h3&gt;
&lt;p&gt;Familiarity with LaTeX has definitely helped me. Fighting with LaTeX is no fun, but you &lt;em&gt;will&lt;&#x2F;em&gt; have to do a little bit of it at some point. Lots of people like using Overleaf; I prefer the command line. Don’t get me wrong: Overleaf is awesome and makes collaborating in a Google Docs sort of way possible, but you loose some flexibility, and if something goes wrong on Overleaf right before your deadline, you’re toast.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bibliographies&quot;&gt;Bibliographies&lt;&#x2F;h3&gt;
&lt;p&gt;There is a lovely computer science bibliography hosted at &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dblp.org&#x2F;&quot;&gt;dblp.org&lt;&#x2F;a&gt;. When I was going through the bibliography for &lt;a href=&quot;&#x2F;posts&#x2F;2024-06-21_writing_a_paper&#x2F;&quot;&gt;my last paper&lt;&#x2F;a&gt; I was able to find lots of missing DOIs simply by putting in the title of the paper into the search bar; DBLP found all the bibliographic information that I needed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;organization-and-communication&quot;&gt;Organization and communication&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;note-taking&quot;&gt;Note taking&lt;&#x2F;h3&gt;
&lt;p&gt;Take notes whenever you learn how to do something that wasn’t obvious to you when you started out doing it. I like the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zettelkasten&quot;&gt;Zettelkasten&lt;&#x2F;a&gt; method for taking notes: whenever I learn how to e.g. do some complex layout in LaTeX or learn a neat Makefile trick, I write it down. You can think of it as writing your own personal &lt;code&gt;man&lt;&#x2F;code&gt; pages&lt;&#x2F;p&gt;
&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;If you don’t know what a &lt;code&gt;man&lt;&#x2F;code&gt; page is, this is the standard manual system available on UNIX-like systems (e.g. FreeBSD, macOS, and Linux). Open a terminal and run &lt;code&gt;man man&lt;&#x2F;code&gt; to read the manual page for &lt;code&gt;man&lt;&#x2F;code&gt; itself. You really need to get comfortable with the &lt;a href=&quot;https:&#x2F;&#x2F;beta.lambdaland.org&#x2F;posts&#x2F;2024-07-09_phd_tools&#x2F;#command-line&quot;&gt;Command line&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Some of these notes I rarely look back at. Others I revisit regularly. But even though I might not review some notes that frequently, there are cases where something on my system will break and a years-old note comes to my rescue from the &lt;em&gt;last&lt;&#x2F;em&gt; time I had to solve that problem. For example, I took notes on how to upgrade my language server for Elixir. I don’t upgrade that thing very often, but there is a little tweak I need to do just because of how my system is set up that is not obvious. It took me a few hours of debugging the first time, but, because I took notes, it now only takes me a few minutes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;email&quot;&gt;Email&lt;&#x2F;h3&gt;
&lt;p&gt;Academics generally love email. It’s simple, robust, and doesn’t change its UI every few weeks, unlike &lt;em&gt;some&lt;&#x2F;em&gt; popular chat platforms. Unfortunately many universities are forcing everyone to move to Outlook. &lt;a href=&quot;&#x2F;posts&#x2F;2022-08-28_keep_email_federated&#x2F;&quot;&gt;This is a very bad thing.&lt;&#x2F;a&gt; Fortunately, there are &lt;a href=&quot;&#x2F;posts&#x2F;2023-05-03_email_with_outlook&#x2F;&quot;&gt;some workarounds&lt;&#x2F;a&gt; that you can use to reclaim some control over your email.&lt;&#x2F;p&gt;
&lt;p&gt;I have a sweet workflow with my email. That’s right, I do it all from Emacs. Now, while I &lt;em&gt;do&lt;&#x2F;em&gt; recommend you learn how to use Emacs, I understand that not everyone will start using Emacs. Everyone &lt;em&gt;should&lt;&#x2F;em&gt; get proficient with their email client and know how to use it well. I recommend anything that you can control entirely from the keyboard.&lt;&#x2F;p&gt;
&lt;p&gt;You should also get comfortable with editing replies. You know how, when you reply to an email, you usually see something like this:&lt;&#x2F;p&gt;
&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;Some mail clients will make the &lt;code&gt;&amp;gt;&lt;&#x2F;code&gt; at the beginning of the line pretty with different colored lines and whatnot. It’s all angle brackets under the hood, and you can still edit it as described here.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Hey here is my reply!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;On Tuesday, 9 July 2024, Slartibartfast said:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; Hey,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; You were asking me where I found that elvish blade of great&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; antiquity. Turns out it was just sitting on a shelf in the living&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; room the whole time! I had the darndest time escaping the theif&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; though; I think he locked me into the cellar as soon as I went down&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; there. …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Just typing your reply above the email is called “top-posting”, and it’s considered bad form. You can actually edit the bit that was sent to interleave your reply with bits of the prior email. This makes it easier for people to know what you’re replying to.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Hey Slarti&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; Turns out it was just sitting on a shelf in the living room the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; whole time!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;What!? No way! I must have missed it. I&amp;#39;ll grab it once I figure out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;how to get up this chimney in the art studio.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; I had the darndest time escaping the theif though; I think he locked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; me into the cellar as soon as I went down there.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Yeah, I cornered the guy in his hideout. I won the knife fight though.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When used appropriately, this makes emails much more pleasant to read. It doesn’t break the email thread either; you can still see the chain of replies.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;task-tracking&quot;&gt;Task tracking&lt;&#x2F;h3&gt;
&lt;p&gt;You need some way to keep track of tasks. I have a workflow based off of &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;orgmode.org&#x2F;&quot;&gt;Org-mode&lt;&#x2F;a&gt;, which I will not detail here. The short of it is that you need to be spending at least a little time with some regularity “sharpening the saw”&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:1-1&quot;&gt;&lt;a href=&quot;#fn-fn:1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; by making sure that whatever tool you use to keep track of tasks is working for you.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;Thomas, David and Hunt, Andrew (2019). &lt;em&gt;The Pragmatic Programmer&lt;&#x2F;em&gt;, Addison-Wesley.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-fn:1&quot;&gt;
&lt;p&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_7_Habits_of_Highly_Effective_People&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_7_Habits_of_Highly_Effective_People&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-fn:1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I Probably Hate Writing Code in Your Favorite Language</title>
        <published>2024-06-27T00:00:00+00:00</published>
        <updated>2024-06-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-06-27_language_hate/"/>
        <id>https://beta.lambdaland.org/posts/2024-06-27_language_hate/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-06-27_language_hate/">&lt;div class=&quot;epigraph&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;The Tao gave birth to machine language. Machine language gave birth to the assembler.&lt;&#x2F;p&gt;
&lt;p&gt;The assembler gave birth to the compiler. Now there are ten thousand languages.&lt;&#x2F;p&gt;
&lt;p&gt;Each language has its purpose, however humble. Each language expresses the Yin and Yang of software. Each language has its place within the Tao.&lt;&#x2F;p&gt;
&lt;p&gt;But do not program in COBOL if you can avoid it.&lt;&#x2F;p&gt;
&lt;footer&gt;
&lt;p&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.mit.edu&#x2F;~xela&#x2F;tao.html&quot;&gt;The Tao of Programming&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;footer&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;I probably hate writing code in your favorite programming language, whatever it may be. This is because I get frustrated by basically all of the top 10 languages you’ll find listed anywhere for various reasons. Do I hate programming in Python? You bet I do. “But it’s &lt;em&gt;Python&lt;&#x2F;em&gt;! Python is the best programming language on earth!” I can hear you say. I grant that it has its place. Python wins because its ecosystem of libraries is so huge and because there are so many resources for new users. It’s also garbage collected, which means memory safety is not an issue. It the current hot thing, because there is so much support for machine learning in Python.&lt;&#x2F;p&gt;
&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;I don’t consider Python quite as &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.plover.com&#x2F;prog&#x2F;Java.html&quot;&gt;boring as Java&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;But &lt;em&gt;my&lt;&#x2F;em&gt; problem is that Python is a boring language. This isn’t a bad thing necessarily. If you’re interested in solving a problem with a known solution and you’re doing it for business, the a boring language is probably better for you than, say, Haskell.&lt;&#x2F;p&gt;
&lt;p&gt;Why do I think Python is boring? In part because of its philosophy:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;There should be one—and preferably only one—obvious way to do it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0020&#x2F;&quot;&gt;The Zen of Python&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Python has a model of how it wants you to solve problems. That’s right: it wants you to solve problems with objects, classes, and explicit loops. Got a problem that’s the perfect fit for a functional paradigm? Well, I guess you can use &lt;code&gt;map&lt;&#x2F;code&gt; and &lt;code&gt;filter&lt;&#x2F;code&gt;, but you only get a single expression inside of lambdas, data structures are all mutable, and you can’t use recursion to handle lists. Ugh.&lt;&#x2F;p&gt;
&lt;p&gt;I could tell similar stories for other languages that I don’t like programming in. These languages include JavaScript, Go, Java, and C++. Go and Java seem to have been made with huge teams of programmers in mind: make the language and syntax as simple as possible, and then even simpler at the expense of expressivity! This guards against programmers coming up with a clever way to express their problem in a domain-specific way—that’s probably a virtue in large companies. But that’s not how I like to program.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;no-local-reasoning&quot;&gt;No local reasoning&lt;&#x2F;h2&gt;
&lt;p&gt;The thing I hate about &lt;em&gt;all&lt;&#x2F;em&gt; of the languages I listed is their emphasis on mutation. When I call a function and pass it a list or object or whatever, I have &lt;em&gt;no&lt;&#x2F;em&gt; guarantees about that thing’s value when the function returns. That means, to understand some code, I have to understand all of the functions that get called.&lt;&#x2F;p&gt;
&lt;p&gt;In contrast, when I write in a language like Elixir or Haskell, which have &lt;em&gt;immutable&lt;&#x2F;em&gt; data structures, I can look at some code like this:&lt;&#x2F;p&gt;
&lt;div class=&quot;book-tabs&quot; id=&quot;tabs-1&quot;&gt;&lt;input
      type=&quot;radio&quot;
      class=&quot;toggle&quot;
      name=&quot;group-1&quot;
      id=&quot;tab-1-0&quot;
      checked=&quot;checked&quot;
    &#x2F;&gt;
    &lt;label for=&quot;tab-1-0&quot;&gt;Haskell&lt;&#x2F;label&gt;
    &lt;div class=&quot;book-tabs-content markdown-inner&quot;&gt;
      &lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;winningTeam&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; :: GameLog -&amp;gt; Team&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;winningTeam g &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;team_a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; team_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; getTeams g&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      points_a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; getPoints g team_a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      points_b &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; getPoints g team_b &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; points_a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; points_b &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt; team_a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; team_b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;&#x2F;div&gt;&lt;input
      type=&quot;radio&quot;
      class=&quot;toggle&quot;
      name=&quot;group-1&quot;
      id=&quot;tab-1-1&quot;
      
    &#x2F;&gt;
    &lt;label for=&quot;tab-1-1&quot;&gt;Elixir&lt;&#x2F;label&gt;
    &lt;div class=&quot;book-tabs-content markdown-inner&quot;&gt;
      &lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;font-weight: bold;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;spec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; winning_team&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;g &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; GameLog&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Team&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; winning_team&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;span&gt;team_a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; team_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get_teams&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  points_a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get_points&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; team_a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  points_b &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get_points&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; team_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; points_a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; points_b &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    team_a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    team_b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;&#x2F;div&gt;&lt;&#x2F;div&gt;

&lt;p&gt;and I don’t have to know what &lt;code&gt;getTeams&lt;&#x2F;code&gt; or &lt;code&gt;getPoints&lt;&#x2F;code&gt; do to their arguments; I just know they return a value of some kind; I’m free to continue using &lt;code&gt;g&lt;&#x2F;code&gt;, &lt;code&gt;team_a&lt;&#x2F;code&gt;, and &lt;code&gt;team_b&lt;&#x2F;code&gt; as much as I like because their value has not changed.&lt;&#x2F;p&gt;
&lt;p&gt;It might not seem like much in this example, but it is a big deal when you’re neck-deep in a debugging session. I once worked on a codebase that was half in Elixir and half in Ruby. I spent most of my time on the Elixir side. One time when I had to do some debugging in Ruby, I found it so difficult to trace the execution of the program because data was being changed in method calls. If this doesn’t make much sense to you, you might have to experience it first: once you’ve worked in a large functional codebase, you will find yourself bewildered by all the spooky-action-at-a-distance that goes on inside a large OO codebase.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-gripes&quot;&gt;Other gripes&lt;&#x2F;h2&gt;
&lt;p&gt;Other things that frustrate me in programming languages include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Automatic type conversion (looking at you JavaScript).&lt;&#x2F;li&gt;
&lt;li&gt;No type inference (if you’re gonna be statically typed, don’t make me write out the type every time Java).&lt;&#x2F;li&gt;
&lt;li&gt;No structural typing (type is determined by the shape, not the class name).&lt;&#x2F;li&gt;
&lt;li&gt;No good functional data structures.&lt;&#x2F;li&gt;
&lt;li&gt;No metaprogramming.&lt;&#x2F;li&gt;
&lt;li&gt;No TCO&#x2F;limits on stack depth.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That last one is something that &lt;em&gt;really&lt;&#x2F;em&gt; bothers me about Python: stack frames in Racket cost 2 words.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Either do proper tail-call elimination &lt;em&gt;or&lt;&#x2F;em&gt;, if you &lt;em&gt;really absolutely must&lt;&#x2F;em&gt; have &lt;em&gt;all&lt;&#x2F;em&gt; of your precious stack frames &lt;em&gt;performance and elegance be darned&lt;&#x2F;em&gt;, then &lt;em&gt;allocate your stack frames on the heap and stop worrying about it already!&lt;&#x2F;em&gt; (I seem to recall a conversation where someone with knowledge of these things implied that this was in the works. I don’t know any details about it though.)&lt;&#x2F;p&gt;
&lt;p&gt;Seriously though: some solutions lend themselves &lt;em&gt;really&lt;&#x2F;em&gt; well to a nice tail-recursive solution. But can you rely on such an implementation to be performant or even &lt;em&gt;run&lt;&#x2F;em&gt; in Python? Nope. Argh!!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;my-favorite-language&quot;&gt;My favorite language&lt;&#x2F;h2&gt;
&lt;p&gt;Clearly, I like functional programming: it fits how my mind works, and I think it is in a lot of ways objectively better than other paradigms for software engineering. Immutability gives you the ability to reason &lt;em&gt;locally&lt;&#x2F;em&gt; about your code—not to mention not having to worry about race conditions when mutating data in concurrent environments! To parallel the first list that I wrote, here are things that I like in a language:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Easy, explicit conversions between different types of data.&lt;&#x2F;li&gt;
&lt;li&gt;Dynamic typing &lt;em&gt;or&lt;&#x2F;em&gt; powerful type inference &lt;em&gt;or&lt;&#x2F;em&gt; gradual typing!&lt;&#x2F;li&gt;
&lt;li&gt;Structural typing (having nominal typing too can be nice when needed; but given one or the other I’ll take structural over nominal any day).&lt;&#x2F;li&gt;
&lt;li&gt;Functional data structures like cons cells, maps and sets supporting functional updates, and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OxSon&#x2F;rrb.rhm&#x2F;discussions&#x2F;1&quot;&gt;RRB trees&lt;&#x2F;a&gt;!&lt;&#x2F;li&gt;
&lt;li&gt;Powerful macros that let me extend the language.&lt;&#x2F;li&gt;
&lt;li&gt;Proper TCO.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Macros can be a two-edged sword. That said, a lot of the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lambdaland.org&#x2F;posts&#x2F;2023-10-17_fearless_macros&#x2F;&quot;&gt;danger around macros&lt;&#x2F;a&gt; has largely been ameliorated. Elixir is a great example of this: Elixir has a small core and uses macros a &lt;em&gt;lot&lt;&#x2F;em&gt; to define basic things like &lt;code&gt;if&lt;&#x2F;code&gt; in terms of simpler constructs.&lt;&#x2F;p&gt;
&lt;p&gt;What languages do I &lt;em&gt;enjoy&lt;&#x2F;em&gt; programming in? Racket is my favorite: it’s designed to be flexible and give the programmer maximum ability to express their intent to the computer. Racket is a &lt;em&gt;programmable programming language&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Other languages I enjoy include Haskell, Elixir, and Rust. Haskell is the ur-functional language, and it’s really fun to use the type system to describe your domain. Pretty soon the compiler starts keeping you from making all sorts of mistakes that would be hard to catch with basic testing. In Elixir, you get lots of nice functional data structures, proper TCO, pattern matching, and soon gradual typing! Rust is great because it has a phenomenal type system with good type inference; its metaprogramming story could be improved though.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;not-a-flame-war&quot;&gt;Not a flame war&lt;&#x2F;h2&gt;
&lt;p&gt;I want to make it clear that I am &lt;em&gt;not&lt;&#x2F;em&gt; attempting to start a flame-war or saying that Python, Java, et al. are useless: they have their place and are very respectable works of engineering. All I am saying is that, given a choice of language for a hobby project, I will pick something else because I don’t want to be frustrated by the language when I work.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, that’s the end of my griping about languages. (For today, at least.)&lt;&#x2F;p&gt;
&lt;div class=&quot;epigraph&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;There will always be things we wish to say in our programs that in all known languages can only be said poorly.&lt;&#x2F;p&gt;
&lt;p&gt;A language that doesn’t affect the way you think about programming, is not worth knowing.&lt;&#x2F;p&gt;
&lt;footer&gt;
&lt;p&gt;Alan Perlis&lt;&#x2F;p&gt;
&lt;&#x2F;footer&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;div&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Source: I asked Matthew Flatt about Racket’s stack frame size once. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Lessons From Writing My First Academic Paper</title>
        <published>2024-06-21T00:00:00+00:00</published>
        <updated>2024-06-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-06-21_writing_a_paper/"/>
        <id>https://beta.lambdaland.org/posts/2024-06-21_writing_a_paper/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-06-21_writing_a_paper/">&lt;p&gt;I got a paper published at &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;2024.ecoop.org&#x2F;&quot;&gt;ECOOP&lt;&#x2F;a&gt; this year! This is my first big paper published at a big conference. As such, I wanted to write down some things that I learned so that in the future I can remember a bit better what was hard for me. That way, should I one day advise PhD students working on &lt;em&gt;their&lt;&#x2F;em&gt; first papers, I can help them through the learning curve better.&lt;&#x2F;p&gt;
&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;For us, this artifact took the form of a Docker container with a bash script that ran all the code examples from our paper to support the claims we made. I really like that reproducibility like this is often an option in CS.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;dl&gt;
&lt;dt&gt;Conference deadlines may be flexible if you talk to the right people.&lt;&#x2F;dt&gt;
&lt;dd&gt;
&lt;p&gt;We submitted an artifact along with our paper But some of the deadlines were &lt;em&gt;really&lt;&#x2F;em&gt; close. My advisor reached out to the folks in charge of the conference&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:1-1&quot;&gt;&lt;a href=&quot;#fn-fn:1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and asked if the artifact submission date could be moved back. The organizers agreed, and everyone got a little more breathing room between when the paper was due and when the artifact was supposed to be submitted.&lt;&#x2F;p&gt;
&lt;&#x2F;dd&gt;
&lt;dt&gt;Conferences are run by humans—you can talk to them.&lt;&#x2F;dt&gt;
&lt;dd&gt;
&lt;p&gt;Along the same lines, the conferences are run by &lt;em&gt;people&lt;&#x2F;em&gt;, and you can talk to the organizers to request clarification. You shouldn’t be a whiny jerk, of course, but the people running these things &lt;em&gt;want&lt;&#x2F;em&gt; people to submit good papers and will work to help you overcome blockers.&lt;&#x2F;p&gt;
&lt;&#x2F;dd&gt;
&lt;dt&gt;The Call for Papers has everything you need.&lt;&#x2F;dt&gt;
&lt;dd&gt;
&lt;p&gt;The “Call for Papers” describes what kinds of submissions fit the conference, as well as &lt;em&gt;how&lt;&#x2F;em&gt; to format and submit your paper. You can see the CfP for ECOOP &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;2024.ecoop.org&#x2F;track&#x2F;ecoop-2024-papers#Call-for-Papers&quot;&gt;here&lt;&#x2F;a&gt;. Absorbing everything in the CfP can be challenging for first-timers. I was unclear about something and my advisor asked me if I had read the CfP. I had, but that didn’t mean that I remembered &lt;em&gt;everything&lt;&#x2F;em&gt; from it. It takes time and experience to absorb the salient parts of the CfP.&lt;&#x2F;p&gt;
&lt;&#x2F;dd&gt;
&lt;dt&gt;Papers get easier to read as time goes on.&lt;&#x2F;dt&gt;
&lt;dd&gt;
&lt;p&gt;When I first started research, I struggled to make it through a single paper. Moreover, I had a hard time understanding the point the paper was trying to make.&lt;&#x2F;p&gt;
&lt;p&gt;I think part of the difficulty stems from the sheer amount of new terminology and dense technical material present in a typical paper. Everything is new and therefore requires effort to comprehend. As you get familiar with the field, however, previously arcane concepts become easy to grasp. This also makes it easier to see the main idea of the paper: you can tune out the noise and focus on what is novel.&lt;&#x2F;p&gt;
&lt;p&gt;Part of it comes from how unfamiliar the &lt;em&gt;form&lt;&#x2F;em&gt; of papers is. When I started research, papers felt arbitrarily formulaic. Now, I can recognize common structures in papers and use these patterns to understand the paper quicker. I actually find that papers are an efficient way for me to learn about cutting-edge research. I hoped, but did not know, that that would eventually be the case when I started.&lt;&#x2F;p&gt;
&lt;&#x2F;dd&gt;
&lt;dt&gt;Keep track of where &lt;em&gt;every&lt;&#x2F;em&gt; claim comes from.&lt;&#x2F;dt&gt;
&lt;dd&gt;
&lt;p&gt;I did not do a very good job keeping a lab notebook for this paper. When I started writing the paper, I had to go back to my work and try and remember where I got a particular number or why I made a particular claim. I am doing a lot better with my current project, I think. I hope the next paper is a little smoother in this regard.&lt;&#x2F;p&gt;
&lt;&#x2F;dd&gt;
&lt;dt&gt;Writing takes a long time!&lt;&#x2F;dt&gt;
&lt;dd&gt;
&lt;p&gt;We started working on this paper about 7 months ago, according to &lt;code&gt;git log&lt;&#x2F;code&gt;. There were so many drafts, edits, and revisions.&lt;&#x2F;p&gt;
&lt;&#x2F;dd&gt;
&lt;dt&gt;Get your contributions clear.&lt;&#x2F;dt&gt;
&lt;dd&gt;
&lt;p&gt;Simon Peyton-Jones &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;simon.peytonjones.org&#x2F;great-research-paper&#x2F;&quot;&gt;gives this advice&lt;&#x2F;a&gt;: your list of contributions should drive the paper. Moreover, writing the paper drives the research. Research is useless unless shared!&lt;&#x2F;p&gt;
&lt;&#x2F;dd&gt;
&lt;dt&gt;Collaboration is challenging.&lt;&#x2F;dt&gt;
&lt;dd&gt;
&lt;p&gt;Writing joint papers can be tricky. I am really glad we were using &lt;code&gt;git&lt;&#x2F;code&gt; to track changes. I met with my advisor twice a week in person, as well as a few times remotely to hammer out the ideas and drafts in the paper. We sent lots of messages in Slack.&lt;&#x2F;p&gt;
&lt;p&gt;Asking for feedback can be hard—and I don’t just mean in the emotional pride-bruising sense: prompting the people you ask for feedback can be tricky. I asked someone for some help on a different piece of writing, and they weren’t able to give me much useful help and instead focused on trivial issues. Part of that is on me: I should have prompted better. But it is hard to prompt well.&lt;&#x2F;p&gt;
&lt;p&gt;I find it a little curious that different kinds of people have different affinities to methods of giving feedback. With this paper, there’s a flag in LaTeX that adds line numbers to the PDF. So, if someone wants to comment on something, they can write:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;l 42: &amp;quot;that&amp;quot; → &amp;quot;which&amp;quot;; the phrase is not essential, so use &amp;quot;which&amp;quot; instead of &amp;quot;that&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;l 46: &amp;quot;rocks are a kind of vegetable&amp;quot; do we have a citation for this?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This seems natural to me. I like that it’s software-agnostic. I guess some fields are tied to particular technologies (e.g. suggested edits in Word) and that seems burdensome to me.&lt;&#x2F;p&gt;
&lt;&#x2F;dd&gt;
&lt;&#x2F;dl&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-fn:1&quot;&gt;
&lt;p&gt;Specifically, the program chair. &lt;a href=&quot;#fr-fn:1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chorex: Guaranteeing Deadlock Freedom in Elixir</title>
        <published>2024-06-03T00:00:00+00:00</published>
        <updated>2024-06-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-06-03_chorex_0_1/"/>
        <id>https://beta.lambdaland.org/posts/2024-06-03_chorex_0_1/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-06-03_chorex_0_1/">&lt;p&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;utahplt&#x2F;chorex&quot;&gt;Chorex&lt;&#x2F;a&gt; is a brand-new Elixir library for &lt;em&gt;choreographic programming&lt;&#x2F;em&gt; [&lt;a href=&quot;#citeproc_bib_item_3&quot;&gt;3&lt;&#x2F;a&gt;]: Chorex provides a macro-based DSL that lets you describe how processes communicate to perform a computation. This top-down description of interacting processes is called a &lt;em&gt;choreography&lt;&#x2F;em&gt;. From this choreography, Chorex creates modules for each process that handle all the message-passing in the system. The interactions performed by the generated code will never deadlock &lt;em&gt;by construction&lt;&#x2F;em&gt; because the choreographic DSL ensures that no processes will be waiting on each other at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;This is a research project; if you like experimenting with new things, please try this out! The best way to leave feedback is by &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;utahplt&#x2F;chorex&#x2F;issues&quot;&gt;opening an issue&lt;&#x2F;a&gt; on the Chorex repository. Chorex is still in active development, and we would love to see whatever you make with Chorex.&lt;&#x2F;p&gt;
&lt;p&gt;Chorex is available on &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hex.pm&#x2F;packages&#x2F;chorex&quot;&gt;hex.pm&lt;&#x2F;a&gt;. Development is on &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;utahplt&#x2F;chorex&quot;&gt;GitHub&lt;&#x2F;a&gt;. Try it out!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-does-chorex-do&quot;&gt;What does Chorex do?&lt;&#x2F;h2&gt;
&lt;p&gt;Chorex enables &lt;em&gt;choreographic programming&lt;&#x2F;em&gt; in Elixir. A &lt;em&gt;choreography&lt;&#x2F;em&gt; is a birds-eye view of communicating parties in a concurrent system: you describe the different actors and how they send messages to each other. From this choreography you can create an &lt;em&gt;endpoint projection&lt;&#x2F;em&gt;, which just means you create some code for each of the concurrent actors that handles all the communication.&lt;&#x2F;p&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;chorex_announcement&#x2F;figures&#x2F;EPP.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;Choreographic programming ensures &lt;em&gt;deadlock freedom by construction&lt;&#x2F;em&gt;. That means you will not be able to accidentally create a system of actors that accidentally deadlock. It’s still possible to have other kinds of bugs that freeze the system (e.g. one of the actors hangs on an infinite loop) but it eliminates an entire class of bug that is difficult to track down in real applications.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, Chorex implements &lt;em&gt;higher-order choreographies&lt;&#x2F;em&gt; [&lt;a href=&quot;#citeproc_bib_item_1&quot;&gt;1&lt;&#x2F;a&gt;] which let you treat choreographies as first-class citizens in your language. This improves the modularity of code built with choreographies.&lt;&#x2F;p&gt;
&lt;p&gt;Chorex does all this by leveraging Elixir’s macro system: you write down a choreography using the &lt;code&gt;defchor&lt;&#x2F;code&gt; macro provided by Chorex. The macro expands into several modules: one for each actor in your system. You then create another module for each actor in the system which &lt;code&gt;use&lt;&#x2F;code&gt;​s the respective macro-generated module; the macro-generated module handles the communication between the different parties in the choreography, and your hand-written module handles all the internal bits to that node. Let’s look at an example.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example-of-a-choreography&quot;&gt;Example of a choreography&lt;&#x2F;h2&gt;
&lt;p&gt;Here’s a simple, classic example: someone wants to buy a book, so they ask the seller for the price. The seller responds with the price. Here’s a diagram of that communication:&lt;&#x2F;p&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;chorex_announcement&#x2F;figures&#x2F;booksell_flow.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;And here is the corresponding choreography describing that:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defmodule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; BookSellerChor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  defchor &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Buyer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Seller&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;    Buyer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;get_book_title&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ~&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Seller&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.(&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;    Seller&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;get_price&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ~&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Buyer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.(&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;    Buyer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.(&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;defchor&lt;&#x2F;code&gt; macro will create (roughly) the following code:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defmodule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; BookSellerChor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  defmodule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Chorex&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    defmodule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Buyer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;font-weight: bold;&quot;&gt;      @&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;callback&lt;&#x2F;span&gt;&lt;span&gt; get_book_title&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;      ..&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    defmodule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Seller&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;font-weight: bold;&quot;&gt;      @&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;callback&lt;&#x2F;span&gt;&lt;span&gt; get_price&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;      ..&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    ..&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;along with a &lt;code&gt;__using__&lt;&#x2F;code&gt; macro. Now we create modules for each of our actors (&lt;code&gt;Buyer&lt;&#x2F;code&gt;, &lt;code&gt;Seller&lt;&#x2F;code&gt;) and we use the generated &lt;code&gt;Chorex&lt;&#x2F;code&gt; module to handle the communication:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defmodule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; MyBuyer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  use&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; BookSellerChor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Chorex&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;buyer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get_book_title&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span&gt; do:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Zen and the Art of Motorcycle Maintenance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defmodule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; MySeller&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  use&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; BookSellerChor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Chorex&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;seller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get_price&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;book_title&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span&gt; do:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ..&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To kick off the choreography, start up a process for each actor and send them everyone’s PID:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;buyer_process  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; spawn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;MyBuyer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;, [])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;seller_process &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; spawn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;MySeller&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;, [])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;config &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Buyer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; buyer_process&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Seller&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; seller_process&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;super&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;buyer_process&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;seller_process&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now you can wait for the processes to send you (the parent that started the choreography) their return values. From the choreography, we expect the &lt;code&gt;Buyer&lt;&#x2F;code&gt; actor to finish with the price &lt;code&gt;p&lt;&#x2F;code&gt;. We can get that like so after sending the actors the config for the network:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;receive do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;choreography_return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Buyer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; the_price&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; IO&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;puts&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Got price at buyer: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;the_price&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In sum, this is how you use Chorex:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Write a choreography to describe your system&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;defchor&lt;&#x2F;code&gt; macro will create modules for each endpoint&lt;&#x2F;li&gt;
&lt;li&gt;Implement each endpoint’s derived behaviour&lt;&#x2F;li&gt;
&lt;li&gt;Fire of the choreography&lt;&#x2F;li&gt;
&lt;li&gt;Await replies&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;chorex_announcement&#x2F;figures&#x2F;using_chorex.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;Choreographies can get a &lt;em&gt;lot&lt;&#x2F;em&gt; more complicated than this puny example here. See the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hexdocs.pm&#x2F;chorex&#x2F;readme.html&quot;&gt;Chorex README&lt;&#x2F;a&gt; and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hexdocs.pm&#x2F;chorex&#x2F;Chorex.html&quot;&gt;module documentation&lt;&#x2F;a&gt; for more extensive examples with Chorex. Lugović and Montesi built an IRC client and server in Java with a choreography [&lt;a href=&quot;#citeproc_bib_item_2&quot;&gt;2&lt;&#x2F;a&gt;]—I’m excited to see what’s possible in Elixir!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chorex-goals-non-goals-and-roadmap&quot;&gt;Chorex goals, non-goals, and roadmap&lt;&#x2F;h2&gt;
&lt;p&gt;Chorex is a &lt;em&gt;research project&lt;&#x2F;em&gt;, meaning that its primary function is to prove out new ideas. Development speed takes priority over stability of features and API. This is a scout and a trailblazer, not a surveyor and road-laying machine.&lt;&#x2F;p&gt;
&lt;p&gt;We would like to make Chorex as useful as possible; historically choreographic programming libraries have been cutting-edge research projects. Chorex &lt;em&gt;is&lt;&#x2F;em&gt; still research-oriented, but if we can make it useful to people other than ourselves, then that’s a big win. :) Moreover, no one has done choreographic programming with Elixir-style concurrency, where processes have mailboxes and where there are existing idioms around processes and communication.&lt;&#x2F;p&gt;
&lt;p&gt;This is &lt;em&gt;not&lt;&#x2F;em&gt; intended to be a production-grade system. Maybe some day, but not today. Please don’t use this to build a production system then blame us when your system goes down. Please &lt;em&gt;do&lt;&#x2F;em&gt; use this in hobby projects and let us know what you manage to build!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;feedback&quot;&gt;Feedback&lt;&#x2F;h2&gt;
&lt;p&gt;Please send us any feedback you have! You can &lt;a href=&quot;&#x2F;#contact&quot;&gt;contact me directly&lt;&#x2F;a&gt; or &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;utahplt&#x2F;chorex&#x2F;issues&quot;&gt;open an issue&lt;&#x2F;a&gt; on the Chorex repository. We would &lt;em&gt;love&lt;&#x2F;em&gt; to see anything you make with Chorex.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fun-details-on-the-implementation&quot;&gt;Fun details on the implementation&lt;&#x2F;h2&gt;
&lt;p&gt;While building the &lt;code&gt;defchor&lt;&#x2F;code&gt; macro, I realized I needed to walk an AST and gather up a list of functions an an endpoint would need to define. This inspired me to create a writer monad; I documented how I stumbled upon a pattern that a monad solved quite elegantly &lt;a href=&quot;&#x2F;posts&#x2F;2024-05-01_definitely_not_about_monads&#x2F;&quot;&gt;earlier on my blog&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;style&gt;.csl-left-margin{float: left; padding-right: 0em;}
 .csl-right-inline{margin: 0 0 0 1em;}&lt;&#x2F;style&gt;&lt;div class=&quot;csl-bib-body&quot;&gt;
  &lt;div class=&quot;csl-entry&quot;&gt;&lt;a id=&quot;citeproc_bib_item_1&quot;&gt;&lt;&#x2F;a&gt;
    &lt;div class=&quot;csl-left-margin&quot;&gt;[1]&lt;&#x2F;div&gt;&lt;div class=&quot;csl-right-inline&quot;&gt;Hirsch, A.K. and Garg, D. 2022. Pirouette: Higher-order typed functional choreographies. &lt;i&gt;Proceedings of the acm on programming languages&lt;&#x2F;i&gt;. 6, (Jan. 2022), 1–27. DOI:&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1145&#x2F;3498684&quot;&gt;https:&#x2F;&#x2F;doi.org&#x2F;10.1145&#x2F;3498684&lt;&#x2F;a&gt;.&lt;&#x2F;div&gt;
  &lt;&#x2F;div&gt;
  &lt;div class=&quot;csl-entry&quot;&gt;&lt;a id=&quot;citeproc_bib_item_2&quot;&gt;&lt;&#x2F;a&gt;
    &lt;div class=&quot;csl-left-margin&quot;&gt;[2]&lt;&#x2F;div&gt;&lt;div class=&quot;csl-right-inline&quot;&gt;Lugović, L. and Montesi, F. 2023. Real-World Choreographic Programming: Full-Duplex Asynchrony and Interoperability. &lt;i&gt;The art, science, and engineering of programming&lt;&#x2F;i&gt;. 8, 2 (Oct. 2023), 8. DOI:&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.22152&#x2F;programming-journal.org&#x2F;2024&#x2F;8&#x2F;8&quot;&gt;https:&#x2F;&#x2F;doi.org&#x2F;10.22152&#x2F;programming-journal.org&#x2F;2024&#x2F;8&#x2F;8&lt;&#x2F;a&gt;.&lt;&#x2F;div&gt;
  &lt;&#x2F;div&gt;
  &lt;div class=&quot;csl-entry&quot;&gt;&lt;a id=&quot;citeproc_bib_item_3&quot;&gt;&lt;&#x2F;a&gt;
    &lt;div class=&quot;csl-left-margin&quot;&gt;[3]&lt;&#x2F;div&gt;&lt;div class=&quot;csl-right-inline&quot;&gt;Montesi, F. 2023. &lt;i&gt;&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1017&#x2F;9781108981491&quot;&gt;Introduction to Choreographies&lt;&#x2F;a&gt;&lt;&#x2F;i&gt;. Cambridge University Press.&lt;&#x2F;div&gt;
  &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My Top Emacs Packages</title>
        <published>2024-05-30T00:00:00+00:00</published>
        <updated>2024-05-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-05-30_top_emacs_packages/"/>
        <id>https://beta.lambdaland.org/posts/2024-05-30_top_emacs_packages/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-05-30_top_emacs_packages/">&lt;p&gt;If you ask anyone what the best Emacs packages are, you’ll almost definitely hear &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;magit.vc&#x2F;&quot;&gt;Magit&lt;&#x2F;a&gt; (the only Git porcelain worth using) and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;orgmode.org&#x2F;&quot;&gt;Org Mode&lt;&#x2F;a&gt; (a way to organize anything and everything in plain text) listed as #1 and #2. And they’re right! I use those packages extensively every day.&lt;&#x2F;p&gt;
&lt;p&gt;Besides those two powerhouses, there are a handful of packages that make using Emacs a delight. If I had to ever use something else, I would miss these packages most:&lt;&#x2F;p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abo-abo&#x2F;avy&quot;&gt;Avy&lt;&#x2F;a&gt;&lt;&#x2F;dt&gt;
&lt;dd&gt;Jump around your screen crazy fast. Teleport to any character with ~5 key presses. See &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;karthinks.com&#x2F;software&#x2F;avy-can-do-anything&#x2F;&quot;&gt;this blog post by Karthink&lt;&#x2F;a&gt; for more reasons why it’s awesome. I almost exclusively rely on &lt;code&gt;avy-goto-char-timer&lt;&#x2F;code&gt; and have it bound to &lt;code&gt;s-j&lt;&#x2F;code&gt;.&lt;&#x2F;dd&gt;
&lt;dt&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;oantolin&#x2F;embark&quot;&gt;Embark&lt;&#x2F;a&gt;&lt;&#x2F;dt&gt;
&lt;dd&gt;Kind of like a super-charged right-click for Emacs. Works beautifully in dired, when selecting files in the minibuffer. There’s an easy way to make it play well with Avy which is just the best.&lt;&#x2F;dd&gt;
&lt;dt&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;akib&#x2F;emacs-eat&quot;&gt;Eat&lt;&#x2F;a&gt;&lt;&#x2F;dt&gt;
&lt;dd&gt;Eat is a terminal emulator that’s faster almost all the other terminal emulators for Emacs.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Additionally, it can make a terminal emulator &lt;em&gt;in a particular region&lt;&#x2F;em&gt;, so if you use Eshell, you can get a little terminal emulator for every command you run. Normally, if you run, say, &lt;code&gt;cal&lt;&#x2F;code&gt;, you see the ugly terminal escape characters printed as text. With Eat, however, those terminal escape characters get interpreted correctly. Interactive programs (e.g. the Julia and Elixir REPLs) work flawlessly with it.&lt;&#x2F;dd&gt;
&lt;dt&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;jinx&quot;&gt;Jinx&lt;&#x2F;a&gt;&lt;&#x2F;dt&gt;
&lt;dd&gt;Best spellchecking ever. It can spellcheck based off of the fontlock face; I keep this on when I program to get on-the-fly spellchecking of code comments and strings. I keep &lt;code&gt;jinx-correct&lt;&#x2F;code&gt; bound to &lt;code&gt;C-;&lt;&#x2F;code&gt; à la flyspell because it is so darn helpful. Supports checking documents with mixed languages. This is one of the packages I miss most when I’m editing text outside of Emacs.&lt;&#x2F;dd&gt;
&lt;dt&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;emacs-citar&#x2F;citar&quot;&gt;Citar&lt;&#x2F;a&gt;&lt;&#x2F;dt&gt;
&lt;dd&gt;The best way to add citations in Emacs, hands-down. Reads bibtex, inserts in org-mode, LaTeX, whatever.&lt;&#x2F;dd&gt;
&lt;&#x2F;dl&gt;
&lt;h2 id=&quot;user-interface-enhancement&quot;&gt;User interface enhancement&lt;&#x2F;h2&gt;
&lt;p&gt;These next packages are all by &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&quot;&gt;Daniel Mendler&lt;&#x2F;a&gt;. These packages improve selecting commands, buffers, files, etc. from the &lt;code&gt;completing-read&lt;&#x2F;code&gt; and &lt;code&gt;completion-at-point&lt;&#x2F;code&gt; interfaces. These make Emacs insanely ergonomic and excellent.&lt;&#x2F;p&gt;
&lt;p&gt;These replace packages like &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;emacs-helm&#x2F;helm&quot;&gt;Helm&lt;&#x2F;a&gt;, &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abo-abo&#x2F;swiper&quot;&gt;Ivy&#x2F;Counsel&#x2F;Swiper&lt;&#x2F;a&gt;, and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;company-mode&#x2F;company-mode&quot;&gt;Company&lt;&#x2F;a&gt;. In comparison to these packages, Vertico + Consult + Corfu are lighter-weight, faster, less buggy (in my experience; I’ve tried them all!), and work better with other Emacs packages because they follow the default built-in APIs.&lt;&#x2F;p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;vertico&quot;&gt;Vertico&lt;&#x2F;a&gt;&lt;&#x2F;dt&gt;
&lt;dd&gt;Lighter-weight, less buggy vertical completing-read interface. Replaces Ivy. Incredibly flexible. Works out-of-the-box with everything that has a &lt;code&gt;completing-read&lt;&#x2F;code&gt; interface, so you don’t need special &lt;code&gt;*-ivy&lt;&#x2F;code&gt; packages to make it play nice. Recommend adding &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;marginalia&#x2F;&quot;&gt;Marginalia&lt;&#x2F;a&gt; as well by the same author to add extra infos.&lt;&#x2F;dd&gt;
&lt;dt&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;consult&quot;&gt;Consult&lt;&#x2F;a&gt;&lt;&#x2F;dt&gt;
&lt;dd&gt;Better than counsel. The live preview is amazing; I use &lt;code&gt;consult-buffer&lt;&#x2F;code&gt; instead of &lt;code&gt;switch-to-buffer&lt;&#x2F;code&gt;, &lt;code&gt;consult-line&lt;&#x2F;code&gt; instead of Swiper. &lt;code&gt;consult-ripgrep&lt;&#x2F;code&gt; is :fire: for searching large projects with instant previewable results. Pairs well with Embark to save results to a buffer.&lt;&#x2F;dd&gt;
&lt;dt&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;corfu&quot;&gt;Corfu&lt;&#x2F;a&gt;&lt;&#x2F;dt&gt;
&lt;dd&gt;Lightweight pop-up library. Pairs well with &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;cape&quot;&gt;Cape&lt;&#x2F;a&gt; by the same author.&lt;&#x2F;dd&gt;
&lt;&#x2F;dl&gt;
&lt;p&gt;See also &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;oantolin&#x2F;orderless&quot;&gt;Orderless&lt;&#x2F;a&gt; which enhances everything from &lt;code&gt;M-x&lt;&#x2F;code&gt; to &lt;code&gt;consult-line&lt;&#x2F;code&gt; to the Corfu popup. Vertico + Consult + Orderless + Marginalia + Corfu + Cape + Embark is sometimes called the “minad stack”.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; It’s the new hotness—that said, it’s gotten really really stable over the past two years.&lt;&#x2F;p&gt;
&lt;p&gt;If you like these packages, consider sponsoring their maintainers! These are some of my favorite open-source projects and I try to support them when I can.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-starter-kit-built-on-these&quot;&gt;A starter kit built on these&lt;&#x2F;h2&gt;
&lt;p&gt;If you like these packages, you might like my &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;emacs-bedrock&quot;&gt;Emacs Bedrock&lt;&#x2F;a&gt; starter kit which, unlike many other starter kits, is meant to be a no-nonsense no-fluff no-abstraction bare-bones start for you to fork and tinker with to your liking. The stock configuration only installs &lt;em&gt;one&lt;&#x2F;em&gt; package (&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;justbur&#x2F;emacs-which-key&quot;&gt;which-key&lt;&#x2F;a&gt;, which is amazing) but includes some extra example configuration. The &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;emacs-bedrock&#x2F;src&#x2F;branch&#x2F;main&#x2F;extras&#x2F;base.el&quot;&gt;extras&#x2F;base.el&lt;&#x2F;a&gt; file includes sample starter configuration for most of the above packages. (I should add &lt;code&gt;eat&lt;&#x2F;code&gt; to it, come to think of it…)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;errata&quot;&gt;Errata&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Eat is not the fastest terminal emulator, Vterm is. Thanks to a Redditor who pointed this out.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;The only emulator it’s &lt;em&gt;not&lt;&#x2F;em&gt; faster than is Vterm, which is pretty dang speedy. Eat has been more than fast enough for all my needs however. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;Embark and Orderless are both developed by &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;oantolin&quot;&gt;Omar Camarena&lt;&#x2F;a&gt; (oantolin) who frequently collaborates with Daniel Mendler. When I asked Omar on Reddit about the name, Omar replied that “minad stack” is fine; another name they’ve tried for the stack is “iceberg”, which I think is a good name too. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Boilerplate Busting in Functional Languages</title>
        <published>2024-05-06T00:00:00+00:00</published>
        <updated>2024-05-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-05-01_definitely_not_about_monads/"/>
        <id>https://beta.lambdaland.org/posts/2024-05-01_definitely_not_about_monads/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-05-01_definitely_not_about_monads/">&lt;p&gt;This is the story of how I solved a problem (ugly, cumbersome boilerplate code) that I ran into while writing a program in a functional language (Elixir). Functional programming languages often pride themselves on expressiveness and elegance; but occasionally they are not amenable to the most obvious solutions to the problems we wish to solve. In this case, the simplest solution to my problem would have been to have a global mutable variable. But no one likes those.&lt;&#x2F;p&gt;
&lt;p&gt;The solution most programmers would have found obviates mutation, but the code ends up being rather clunky. This inelegance stems from two intertwined issues pulling the code in different directions. However, the two concerns are &lt;em&gt;so&lt;&#x2F;em&gt; intertwined that it can be difficult to see them as separate issues at all! In this blog post, I hope I can show you a new way of looking at this class of problem that will let you see what those two issues are, and how to cleanly split them apart to get nice, maintainable, functional code.&lt;&#x2F;p&gt;
&lt;div class=&quot;epigraph&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;You take your analytic knife, put the point directly on the term Quality and just tap, not hard, gently, and the whole world splits, cleaves, right in two… and the split is clean. There’s no mess. No slop. No little items that could be one way or the other. Not just a skilled break but a very lucky break. Sometimes the best analysts, working with the most obvious lines of cleavage, can tap and get nothing but a pile of trash. And yet here was Quality; a tiny, almost unnoticeable fault line; a line of illogic in our concept of the universe; and you tapped it, and the whole universe came apart, so neatly it was almost unbelievable.&lt;&#x2F;p&gt;
&lt;footer&gt;
&lt;p&gt;&lt;em&gt;Zen and the Art of Motorcycle Maintenance&lt;&#x2F;em&gt;, Robert M. Pirsig&lt;&#x2F;p&gt;
&lt;&#x2F;footer&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;the-setup&quot;&gt;The Setup&lt;&#x2F;h2&gt;
&lt;p&gt;I will use a concrete example to describe my specific problem, though the issue is general enough that you likely have encountered it. After I walk through the example I’ll cover the essential elements that make my solution work, and how it generalizes to similar problems.&lt;&#x2F;p&gt;
&lt;p&gt;Suppose that you are writing an application that lets people track their workout habits. Every time that they succeed in meeting a goal, they register what they accomplished. Now you have a database full of logged events like “went to the gym” or “swam 1000 m” or “ran a mile”, etc. Now you need some way to convert this set of events into reward points—preferably in a way that the user finds motivating.&lt;&#x2F;p&gt;
&lt;div class=&quot;table-caption&quot;&gt;
  &lt;span class=&quot;table-number&quot;&gt;Table 1:&lt;&#x2F;span&gt;
  An example of such habit records for a user.
&lt;&#x2F;div&gt;
&lt;div align=&quot;center&quot; style=&quot;overflow-x:auto;&quot;&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: right&quot;&gt;&lt;code&gt;user_id&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;&lt;code&gt;date&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;&lt;code&gt;event_type&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;&lt;code&gt;event_amount&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;69105&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2024-05-01&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;gym&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;69105&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2024-05-02&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;swim&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1000&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;69105&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2024-05-03&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;gym&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;69105&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2024-05-04&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;run&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1.61&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;But every user is different, so let’s say that you make it so that users can customize exactly how goal completions translate into reward points. Somewhere in your app you let users write a little equation that your program will then evaluate against the events that they have logged. In the end, the user gets a single point value.&lt;&#x2F;p&gt;
&lt;div class=&quot;book-tabs&quot; id=&quot;tabs-1&quot;&gt;&lt;input
      type=&quot;radio&quot;
      class=&quot;toggle&quot;
      name=&quot;group-1&quot;
      id=&quot;tab-1-0&quot;
      checked=&quot;checked&quot;
    &#x2F;&gt;
    &lt;label for=&quot;tab-1-0&quot;&gt;Surface syntax&lt;&#x2F;label&gt;
    &lt;div class=&quot;book-tabs-content markdown-inner&quot;&gt;
      &lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;points&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;gym&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;swim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;gym&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;&#x2F;div&gt;&lt;input
      type=&quot;radio&quot;
      class=&quot;toggle&quot;
      name=&quot;group-1&quot;
      id=&quot;tab-1-1&quot;
      
    &#x2F;&gt;
    &lt;label for=&quot;tab-1-1&quot;&gt;Parsed AST&lt;&#x2F;label&gt;
    &lt;div class=&quot;book-tabs-content markdown-inner&quot;&gt;
      &lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;{ &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;gym&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      ] },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;swim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;gym&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;          ] }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      ] }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  ] }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;&#x2F;div&gt;&lt;input
      type=&quot;radio&quot;
      class=&quot;toggle&quot;
      name=&quot;group-1&quot;
      id=&quot;tab-1-2&quot;
      
    &#x2F;&gt;
    &lt;label for=&quot;tab-1-2&quot;&gt;Evaluation result&lt;&#x2F;label&gt;
    &lt;div class=&quot;book-tabs-content markdown-inner&quot;&gt;
      &lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;points&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;gym&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;swim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;gym&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;      2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;     *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;     1000&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    *&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;   1.16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;      2&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 3180&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;&#x2F;div&gt;&lt;&#x2F;div&gt;

&lt;div class=&quot;figure&quot;&gt;
  &lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; interpret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;user_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;, {&lt;&#x2F;span&gt;&lt;span&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;: [&lt;&#x2F;span&gt;&lt;span&gt;arg1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  arg1_eval &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; interpret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;user_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; arg1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  arg2_eval &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; interpret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;user_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; arg2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  case&lt;&#x2F;span&gt;&lt;span&gt; op &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; arg1_eval &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; arg2_eval&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; arg1_eval &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; arg2_eval&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; interpret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;_user_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;, {&lt;&#x2F;span&gt;&lt;span&gt;num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}),&lt;&#x2F;span&gt;&lt;span&gt; do: n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; interpret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;user_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;, {&lt;&#x2F;span&gt;&lt;span&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; q&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}),&lt;&#x2F;span&gt;&lt;span&gt; do:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; query_db&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;user_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; q&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;Sample interpreter for the simple language&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;This is, in essence, a little interpreter. I will not go over how to build an interpreter here, but the gist of it is that you walk down the AST of the equation and evaluate the leaves and nodes recursively until you wind up with a single number of points at the end.&lt;&#x2F;p&gt;
&lt;p&gt;Now let’s say that you are processing a large number of such requests, and you would like to batch all of the database calls. In the previous example, there were four database queries, one of which (&lt;code&gt;&quot;gym&quot;&lt;&#x2F;code&gt;) was a duplicate. (Each &lt;code&gt;get&lt;&#x2F;code&gt; in the surface syntax or &lt;code&gt;query&lt;&#x2F;code&gt; node in the AST induces a database query.) To improve performance, you could batch all of these database calls—thereby also eliminating duplicate queries—and then have this data on hand as you walk the AST.&lt;&#x2F;p&gt;
&lt;p&gt;So here is the new operation we would like to perform: we want to walk through AST, collect all of the database calls into a set, and replace each instance of a database query (&lt;code&gt;query&lt;&#x2F;code&gt; nodes) in the expression to a &lt;em&gt;reference&lt;&#x2F;em&gt; (&lt;code&gt;query_ref&lt;&#x2F;code&gt; nodes) that we can link to the batched results. We will create a fresh identifier every time we encounter a new query; duplicate queries will use the first reference.&lt;&#x2F;p&gt;
&lt;div class=&quot;book-tabs&quot; id=&quot;tabs-2&quot;&gt;&lt;input
      type=&quot;radio&quot;
      class=&quot;toggle&quot;
      name=&quot;group-2&quot;
      id=&quot;tab-2-0&quot;
      checked=&quot;checked&quot;
    &#x2F;&gt;
    &lt;label for=&quot;tab-2-0&quot;&gt;Before optimization&lt;&#x2F;label&gt;
    &lt;div class=&quot;book-tabs-content markdown-inner&quot;&gt;
      &lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;{ &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;gym&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      ] },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;swim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;gym&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;          ] }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      ] }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  ] }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;&#x2F;div&gt;&lt;input
      type=&quot;radio&quot;
      class=&quot;toggle&quot;
      name=&quot;group-2&quot;
      id=&quot;tab-2-1&quot;
      
    &#x2F;&gt;
    &lt;label for=&quot;tab-2-1&quot;&gt;After optimization&lt;&#x2F;label&gt;
    &lt;div class=&quot;book-tabs-content markdown-inner&quot;&gt;
      &lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;{ &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query_ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      ] },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query_ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;op&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query_ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;            { &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;query_ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;          ] }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      ] }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  ] }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;{ &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;: [&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;gym&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;swim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;] }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;&#x2F;div&gt;&lt;&#x2F;div&gt;

&lt;p&gt;Now we need to implement it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;first-attempt&quot;&gt;First attempt&lt;&#x2F;h3&gt;
&lt;p&gt;We could just create a variable that we can mutate as we walk down the tree: every time we encounter a node that looks like &lt;code&gt;{ &quot;query&quot;: _ }&lt;&#x2F;code&gt;, we generate a fresh identifier (or look up an old one if it’s a duplicate query) and replace it with &lt;code&gt;{ &quot;query_ref&quot;: _id }&lt;&#x2F;code&gt;. Once we’re done walking the tree, we have a new AST with &lt;code&gt;query_ref&lt;&#x2F;code&gt; nodes instead of &lt;code&gt;query&lt;&#x2F;code&gt; nodes, and a list of queries that we can execute in one go.&lt;&#x2F;p&gt;
&lt;p&gt;This could work, but the fact that we are using &lt;em&gt;global mutable state&lt;&#x2F;em&gt; should ring alarm bells for &lt;em&gt;anyone&lt;&#x2F;em&gt;—not just functional programmers. Whenever we call our transform function, we would have to ensure that we clear out the old list of accumulated information. Don’t forget about all the &lt;em&gt;other&lt;&#x2F;em&gt; problems that global mutable state brings. There must be a better way.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;second-attempt&quot;&gt;Second attempt&lt;&#x2F;h3&gt;
&lt;p&gt;How might our function be more pure? Instead of just returning a modified tree, we can return a tuple of the new AST node plus a list of queries. (I’ll call this specific shape an &lt;em&gt;AST-queries-tuple&lt;&#x2F;em&gt; throughout.) This eliminates the need for a global variable, and now every call to our optimization function is pure. It’s easier to test and reason about.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; query_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  query_id &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; fresh_query_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;query_ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; query_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}, [{&lt;&#x2F;span&gt;&lt;span&gt;query_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; query_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}]}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;span&gt;new_ast_l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queries_l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;span&gt;new_ast_r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queries_r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_ast_l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_ast_r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;},&lt;&#x2F;span&gt;&lt;span&gt; queries_l &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt; queries_r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, this means that we have to take care to combine this information whenever we do a recursive call. It becomes even more cumbersome when we recur over elements in a list and we need to combine all their results together. A well-crafted &lt;code&gt;reduce&lt;&#x2F;code&gt; makes things work OK, but I think you can agree the following code isn’t the most &lt;em&gt;straightforward&lt;&#x2F;em&gt; to read and understand what’s going on.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt; # args is a list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  args&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;reduce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; qs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}, {&lt;&#x2F;span&gt;&lt;span&gt;max_acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; q_acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                      {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; max_acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span&gt; qs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt; q_acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is quite a bit of boilerplate. It’s not the &lt;em&gt;worst&lt;&#x2F;em&gt; code ever—it’s certainly better than our first solution with a global variable—but we seem to be saying more than we need to here.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finding-the-cleavage-point&quot;&gt;Finding the cleavage point&lt;&#x2F;h2&gt;
&lt;p&gt;How can we clean up this code? The code is messy because there are actually &lt;em&gt;two competing concerns&lt;&#x2F;em&gt; here: we have some &lt;em&gt;main computation&lt;&#x2F;em&gt; that we care about (transforming the tree) and some &lt;em&gt;side information&lt;&#x2F;em&gt; (the set of database queries) that we’d like to collect in parallel. If we can separate these concerns, our code will improve.&lt;&#x2F;p&gt;
&lt;p&gt;Now that we see the two intertwined issues, how do we go about separating them? We will still carry around the AST-queries-tuple, but we are going to pull out the logic that governs how we keep track of the list of queries and keep it separate from the AST transformation logic.&lt;&#x2F;p&gt;
&lt;p&gt;First, let’s define a module, a type to help us keep track of an AST-queries-tuple, and a function &lt;code&gt;wrap&lt;&#x2F;code&gt; that takes some AST and pairs it with an empty list of queries:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defmodule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; AstList&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;font-weight: bold;&quot;&gt;  @&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(), [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()]}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;font-weight: bold;&quot;&gt;  @&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;spec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; wrap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; wrap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span&gt; do:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;, []}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Second, the clever bit: we write a function that lets us manipulate the AST value inside the tuple &lt;em&gt;without worrying about how to combine the sets of queries&lt;&#x2F;em&gt;. We’ll call this function &lt;code&gt;thread&lt;&#x2F;code&gt;, and it takes an AST-queries-tuple and gives it to a function argument that expects &lt;em&gt;just&lt;&#x2F;em&gt; the AST bit. That function argument should return a new AST-queries-tuple. Our function &lt;code&gt;thread&lt;&#x2F;code&gt; will then merge the two lists of queries together without the function parameter ever having to worry about it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;font-weight: bold;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;spec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; thread&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(), (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; thread&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span&gt;ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;},&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;span&gt;new_ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.(&lt;&#x2F;span&gt;&lt;span&gt;ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;span&gt;new_ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_queries &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt; queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can use this to write our &lt;code&gt;transform_queries&lt;&#x2F;code&gt; function! Before we get there, remember that Elixir has a handy set of &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hexdocs.pm&#x2F;elixir&#x2F;1.12&#x2F;operators.html#custom-and-overridden-operators&quot;&gt;customizable infix operators&lt;&#x2F;a&gt; that we can use as shorthand&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; m&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ~&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; do:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; thread&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That means that instead of writing this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;span&gt;new_ast_l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queries_l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;span&gt;new_ast_r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queries_r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_ast_l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_ast_r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;},&lt;&#x2F;span&gt;&lt;span&gt; queries_l &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt; queries_r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can just write:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;  transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ~&amp;gt; fn&lt;&#x2F;span&gt;&lt;span&gt; new_lhs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;    transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ~&amp;gt; fn&lt;&#x2F;span&gt;&lt;span&gt; new_rhs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;      wrap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You might be able to see now how this would make writing this little optimization pass a lot cleaner. We can go a step further on the syntax though: with a little metaprogramming imagination, we can write some shorthand for the &lt;code&gt;~&amp;gt;&lt;&#x2F;code&gt; notation that looks more like variable assignment in a &lt;code&gt;with&lt;&#x2F;code&gt;. It’s not that hard to do.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_threading&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;([{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&amp;lt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;, [&lt;&#x2F;span&gt;&lt;span&gt;var&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; rst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  quote do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;    unquote&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ~&amp;gt;&amp;gt; fn unquote&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;var&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; unquote&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;transform_threading&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_threading&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span&gt;expr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]),&lt;&#x2F;span&gt;&lt;span&gt; do: expr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defmacro&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; threading&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;do:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;__block__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; lines&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;  transform_threading&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lines&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can write the handler for &lt;code&gt;+&lt;&#x2F;code&gt; like so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  threading &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    new_lhs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&amp;lt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    new_rhs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&amp;lt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;    wrap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that gets transformed into the nested anonymous function notation we saw previously.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-do-we-get&quot;&gt;What do we get?&lt;&#x2F;h3&gt;
&lt;p&gt;Now we don’t have to think about merging the list of queries any more: the &lt;code&gt;~&amp;gt;&amp;gt;&lt;&#x2F;code&gt; operator handles all that for us. Bigger savings come if we think about making a version of &lt;code&gt;map&lt;&#x2F;code&gt; that works with our AST-queries-tuples. We’ll call it &lt;code&gt;mapM&lt;&#x2F;code&gt; since it’s like a &lt;code&gt;map&lt;&#x2F;code&gt; that we’re &lt;em&gt;mashing&lt;&#x2F;em&gt; the results together:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;font-weight: bold;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;spec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; mapM&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;vs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.()],&lt;&#x2F;span&gt;&lt;span&gt; f &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Ast&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; mapM&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;vs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  results &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    results&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;elem&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    results&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;elem&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;reduce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;([],&lt;&#x2F;span&gt;&lt;span&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;++&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here we map over a list of &lt;code&gt;Ast&lt;&#x2F;code&gt; values, collect all the resulting sets of queries, and merge them together. This gives us a big savings when we write something like the &lt;code&gt;max&lt;&#x2F;code&gt; function:&lt;&#x2F;p&gt;
&lt;div class=&quot;book-tabs&quot; id=&quot;tabs-3&quot;&gt;&lt;input
      type=&quot;radio&quot;
      class=&quot;toggle&quot;
      name=&quot;group-3&quot;
      id=&quot;tab-3-0&quot;
      checked=&quot;checked&quot;
    &#x2F;&gt;
    &lt;label for=&quot;tab-3-0&quot;&gt;New version&lt;&#x2F;label&gt;
    &lt;div class=&quot;book-tabs-content markdown-inner&quot;&gt;
      &lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  args &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; mapM&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ~&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;wrap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;&#x2F;div&gt;&lt;input
      type=&quot;radio&quot;
      class=&quot;toggle&quot;
      name=&quot;group-3&quot;
      id=&quot;tab-3-1&quot;
      
    &#x2F;&gt;
    &lt;label for=&quot;tab-3-1&quot;&gt;Old version&lt;&#x2F;label&gt;
    &lt;div class=&quot;book-tabs-content markdown-inner&quot;&gt;
      &lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt; # args is a list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  args&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;transform_queries&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;reduce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; qs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}, {&lt;&#x2F;span&gt;&lt;span&gt;max_acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; q_acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                      {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; max_acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span&gt; qs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt; q_acc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;&#x2F;div&gt;&lt;&#x2F;div&gt;

&lt;p&gt;Notice that all the handling of the extra information has been lifted out of our code. Not only does it make it clearer what the &lt;em&gt;core intent&lt;&#x2F;em&gt; of the functions are, but we also get some added flexibility around how we structure that extra data. If we wanted to use a map or a set instead of a list of tuples as the second element in the AST-queries-tuple, then with this refactoring we only have to modify the &lt;code&gt;wrap&lt;&#x2F;code&gt;, &lt;code&gt;thread&lt;&#x2F;code&gt;, and &lt;code&gt;mapM&lt;&#x2F;code&gt; functions. The rest of the code can stay the same!&lt;&#x2F;p&gt;
&lt;p&gt;So, with a little bit of work, we’ve gone from a solution using global mutable state 🤢 to passing around a AST-queries-tuple 😐 to abstracting out the tuple entirely, gaining clarity and flexibility along the way. 🤩 Our threading-related functions are actually generic enough that they don’t need to be about ASTs and lists of queries—as long as we are doing some main computation with a little extra data gathering on the side, this pattern should apply.&lt;&#x2F;p&gt;
&lt;p&gt;Wouldn’t it be nice if this pattern had a name?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;it-was-a-monad-all-along&quot;&gt;It was a monad all along!&lt;&#x2F;h2&gt;
&lt;p&gt;Surprise! This is exactly the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.haskell.org&#x2F;All_About_Monads#The_Writer_monad&quot;&gt;writer monad&lt;&#x2F;a&gt;! This whole post has been a monad tutorial in disguise!&lt;&#x2F;p&gt;
&lt;p&gt;If you’ve been exposed to monads before, you might recognize &lt;code&gt;wrap&lt;&#x2F;code&gt; as &lt;code&gt;return&lt;&#x2F;code&gt; and &lt;code&gt;thread&lt;&#x2F;code&gt; as &lt;code&gt;bind&lt;&#x2F;code&gt; or—as the Haskell programmers like to call it—&lt;code&gt;&amp;gt;&amp;gt;=&lt;&#x2F;code&gt;. The &lt;code&gt;thread do … end&lt;&#x2F;code&gt; macro is just &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learnyouahaskell.com&#x2F;a-fistful-of-monads#do-notation&quot;&gt;&lt;code&gt;do&lt;&#x2F;code&gt; notation&lt;&#x2F;a&gt;. (I couldn’t think of a clever name for &lt;code&gt;mapM&lt;&#x2F;code&gt;, so I just pretended the &lt;code&gt;M&lt;&#x2F;code&gt; stood for &lt;em&gt;mash&lt;&#x2F;em&gt; instead of &lt;em&gt;monad&lt;&#x2F;em&gt;.)&lt;&#x2F;p&gt;
&lt;div&gt;&lt;span class=&quot;marginnote&quot;&gt;&lt;p&gt;There are certain properties (called the “monad laws”—don’t worry, they’re not that scary even though the name sounds ominous) that these functions need to satisfy, but they’re pretty easy to hit. If you don’t satisfy these laws, your monad won’t behave predictably in certain circumstances. If you’re getting started with monads, don’t worry about it right now.&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;div&gt;
&lt;p&gt;“Monad” is just an interface.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; That’s all there is to it. To make your data structure (like our AST-queries-tuple) conform to the Monad interface, you need functions like &lt;code&gt;wrap&lt;&#x2F;code&gt; and &lt;code&gt;thread&lt;&#x2F;code&gt;. Once you have those, you have a monad.
That’s pretty much all there is to it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;different-kinds-of-monads&quot;&gt;Different kinds of monads&lt;&#x2F;h3&gt;
&lt;p&gt;There isn’t a fixed number of monads; there are however a set of more-or-less “standard” monads which have been discovered to be generally useful; the Haskell Wiki has a nice list &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.haskell.org&#x2F;All_About_Monads#A_Catalog_of_Standard_Monads&quot;&gt;here&lt;&#x2F;a&gt;. Among these is the “maybe” monad, which lets you focus on the happy-path of computation and abstracts away the failure path. In Elixir, you can see this pattern with the &lt;code&gt;{:ok, term()} | :error&lt;&#x2F;code&gt; idiom. (The &lt;code&gt;with&lt;&#x2F;code&gt; notation commonly seen in this idiom closely follows Haskell’s &lt;code&gt;do&lt;&#x2F;code&gt; notation.) There are many other useful monads besides the writer and maybe monads. Some of these (like the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.haskell.org&#x2F;All_About_Monads#The_IO_monad&quot;&gt;IO monad&lt;&#x2F;a&gt;) are pretty specific to Haskell and other pure functional languages that don’t support the same kinds of control flow or constructs; others have wider application.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-monad-tutorials-get-wrong&quot;&gt;What monad tutorials get wrong&lt;&#x2F;h3&gt;
&lt;p&gt;Most of the value (I think) of monads is not having &lt;code&gt;return&lt;&#x2F;code&gt; and &lt;code&gt;bind&lt;&#x2F;code&gt;, but all the helper functions like &lt;code&gt;mapM&lt;&#x2F;code&gt;, &lt;code&gt;do&lt;&#x2F;code&gt; notation, and friends. While I was &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;ysue&quot;&gt;writing some Haskell&lt;&#x2F;a&gt;, I got to know all the monad-related functions and how useful they were. These helper functions are what make programming with monads &lt;em&gt;natural&lt;&#x2F;em&gt; and &lt;em&gt;powerful&lt;&#x2F;em&gt;. The core functions &lt;code&gt;bind&lt;&#x2F;code&gt; and &lt;code&gt;return&lt;&#x2F;code&gt; are all you “need” to make a monad, but no one would actually program with just those.&lt;&#x2F;p&gt;
&lt;p&gt;If you ever find something that you think would work well modeled as a monad, be sure to implement additional functions &lt;em&gt;beyond&lt;&#x2F;em&gt; &lt;code&gt;bind&lt;&#x2F;code&gt; and &lt;code&gt;return&lt;&#x2F;code&gt;. You can see a list of functions Haskell implements for monads &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackage.haskell.org&#x2F;package&#x2F;base-4.19.0.0&#x2F;docs&#x2F;Control-Monad.html#g:4&quot;&gt;here&lt;&#x2F;a&gt; if you want some inspiration.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-haskell-uses-monads-so-much&quot;&gt;Why Haskell uses monads so much&lt;&#x2F;h2&gt;
&lt;p&gt;You hear a lot about monads with languages like Haskell, but not so much with other functional languages like Elixir or Rust. Part of this is need, and part is because of ergonomics.&lt;&#x2F;p&gt;
&lt;p&gt;Haskell needs monads to implement effectful computation. Effects include exceptions (modeled by the maybe monad) or logging information (the writer monad). Languages that have these effects natively don’t strictly &lt;em&gt;need&lt;&#x2F;em&gt; these monads. (Though, as we’ve seen, writing a monad can help other languages, even when they have uncontrolled side-effects, like Elixir.)&lt;&#x2F;p&gt;
&lt;p&gt;Haskell makes using monads ergonomic through its &lt;em&gt;typeclass&lt;&#x2F;em&gt; mechanism. Other languages have more constrained method dispatching mechanisms, so you have to jump through some hoops to get monads to work as seamlessly as they do in Haskell.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;typeclasses-vs-dot-interfaces&quot;&gt;Typeclasses vs. interfaces&lt;&#x2F;h3&gt;
&lt;p&gt;If you’re familiar with an OO language, you’ve almost certainly come across the idea of an interface: it’s just a specification of methods an object needs to implement. &lt;em&gt;Typeclasses&lt;&#x2F;em&gt; are similar: they specify a set of functions needed for a type to belong to a typeclass. There are a few key differences between typeclasses and interfaces however:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Interfaces are &lt;em&gt;closed&lt;&#x2F;em&gt;, meaning, if an object doesn’t implement the interface, you can’t do anything about it, unless you modify the definition of the object itself.&lt;&#x2F;p&gt;
&lt;p&gt;In contrast, typeclasses are &lt;em&gt;open&lt;&#x2F;em&gt;, meaning that I can implement the requisite functions to turn a datatype into a monad, even if I can’t modify the definition of the datatype itself.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Interfaces specify methods that dispatch on their object. If I call &lt;code&gt;thing.dance()&lt;&#x2F;code&gt;, then I will look up the &lt;code&gt;dance&lt;&#x2F;code&gt; method in whatever class &lt;code&gt;thing&lt;&#x2F;code&gt; belongs to.&lt;&#x2F;p&gt;
&lt;p&gt;Typeclass functions can dispatch on the &lt;em&gt;return type&lt;&#x2F;em&gt; of the function. For example, the &lt;code&gt;wrap&lt;&#x2F;code&gt; (i.e. &lt;code&gt;return&lt;&#x2F;code&gt;) function needs to dispatch on whatever type it’s expected to return. If I said something like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;thing1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; :: Robot =&lt;&#x2F;span&gt;&lt;span&gt; return &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Marvin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;thing2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; :: Person =&lt;&#x2F;span&gt;&lt;span&gt; return &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Arthur&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;return&lt;&#x2F;code&gt; would dispatch to the version specified for the &lt;code&gt;Robot&lt;&#x2F;code&gt; type for &lt;code&gt;thing1&lt;&#x2F;code&gt;, and &lt;code&gt;Person&lt;&#x2F;code&gt;’s implementation for &lt;code&gt;thing2&lt;&#x2F;code&gt;. This makes the monad functions really generic; with a &lt;code&gt;return&lt;&#x2F;code&gt; that can dispatch on the expected return type, you can write &lt;code&gt;return&lt;&#x2F;code&gt; without thinking much about which monad exactly you’re using.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;using-monads-in-non-haskell-languages&quot;&gt;Using monads in non-Haskell languages&lt;&#x2F;h3&gt;
&lt;p&gt;In languages that don’t have typeclasses, you need to take special steps to ensure that you dispatch to the proper variant of the monad. Racket has a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.racket-lang.org&#x2F;functional&#x2F;interfaces.html&quot;&gt;monad library&lt;&#x2F;a&gt; that works via a generics interface system, plus a few tricks to teach &lt;code&gt;return&lt;&#x2F;code&gt; (called &lt;code&gt;pure&lt;&#x2F;code&gt; in this library) what type it should return. I am sure the same tricks would apply to Elixir. Indeed, Elixir has &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hexdocs.pm&#x2F;elixir&#x2F;protocols.html&quot;&gt;protocols&lt;&#x2F;a&gt;, which are like interfaces, but they are open. They still dispatch on the shape of the first argument passed to them, you would need to pull a trick like Racket’s &lt;code&gt;pure&lt;&#x2F;code&gt; function and pass an argument to ignore just to get the dispatch right.&lt;&#x2F;p&gt;
&lt;p&gt;Elixir has less need for monads than Haskell because its functions are impure. (A function can do arbitrary IO, send messages, throw exceptions, etc.) but there are still cases (as we have seen) where a monad can make life easier. Consider using a monad library the next time you need to avoid ugly side-effects!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;breaking-boilerplate-in-your-functional-projects&quot;&gt;Breaking boilerplate in your functional projects&lt;&#x2F;h2&gt;
&lt;p&gt;Functional languages are not immune to sprouting boilerplate. And while most of the design patterns in a certain OO cookbook are “invisible or simpler” in functional languages,&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-1&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; some patterns crop up when similar problems arise.&lt;&#x2F;p&gt;
&lt;p&gt;Monads are a powerful tool for dividing the &lt;em&gt;essential&lt;&#x2F;em&gt; from the &lt;em&gt;incidental&lt;&#x2F;em&gt; in a program. Exactly what constitutes the essential versus incidental parts—along with how to separate them—can be tricky to see at first. I think this is because separating these concerns in mainstream functional languages get less visibility, and not because of any &lt;em&gt;inherent&lt;&#x2F;em&gt; difficulty of the problem. Perhaps if everyone started out programming by learning Racket and got comfortable with functional idioms, monads would be as natural as the Visitor pattern&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-5-1&quot;&gt;&lt;a href=&quot;#fn-5&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I was surprised and delighted when a monadic solution appeared as the most natural solution to a problem I was working on. Now, you might say that’s because I work as a programming languages researcher. &lt;em&gt;However&lt;&#x2F;em&gt;, the last &lt;em&gt;two&lt;&#x2F;em&gt; times I was working in industry, we had some sort of language interpreter, and I had to walk an AST. Knowing the writer monad would have saved me a lot of time and effort. I hope you can start seeing some monadic patterns in your code, and that you’ll be able to make a monad to make it easier to reason about and refactor your code as well.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.haskell.org&#x2F;All_About_Monads&quot;&gt;https:&#x2F;&#x2F;wiki.haskell.org&#x2F;All_About_Monads&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learnyouahaskell.com&#x2F;a-fistful-of-monads&quot;&gt;https:&#x2F;&#x2F;learnyouahaskell.com&#x2F;a-fistful-of-monads&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;&#x2F;h2&gt;
&lt;p&gt;Thanks to Scott Wiersdorf for the initial impetus to write this, as well as some thoughtful feedback on the prose and outline. Thanks also to Mark Ericksen for some additional comments.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;It would be nice if we could use &lt;code&gt;&amp;gt;&amp;gt;=&lt;&#x2F;code&gt; for this shorthand… but I’m getting ahead of myself. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;There’s a subtle difference between interfaces and typeclasses, and I’ll get to that shortly. This is meant to build intuition. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-4&quot;&gt;
&lt;p&gt;Quote from Peter Norvig. See: &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norvig.com&#x2F;design-patterns&#x2F;design-patterns.pdf&quot;&gt;https:&#x2F;&#x2F;norvig.com&#x2F;design-patterns&#x2F;design-patterns.pdf&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-4-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-5&quot;&gt;
&lt;p&gt;Certainly it would be more comfortable than the &lt;code&gt;AbstractSingletonProxyFactoryBean&lt;&#x2F;code&gt;! &lt;a href=&quot;#fr-5-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Building a Text Editor in Haskell, Part 1</title>
        <published>2024-03-27T00:00:00+00:00</published>
        <updated>2024-03-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2024-03-27_haskell_editor_part_1/"/>
        <id>https://beta.lambdaland.org/posts/2024-03-27_haskell_editor_part_1/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2024-03-27_haskell_editor_part_1/">&lt;p&gt;I am building a little text editor in Haskell.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:1-1&quot;&gt;&lt;a href=&quot;#fn-fn:1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Why would I do such a thing? Because I’m in a class and this fulfills the requirement, and building a text editor is the kind of thing that I’ve always wanted to take a crack at.&lt;&#x2F;p&gt;
&lt;p&gt;This is part 1, and I will describe how to build a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rope_(data_structure)&quot;&gt;rope&lt;&#x2F;a&gt; data structure in Haskell. A rope is a bunch of strings (literally, and in the CS sense) and is optimized for cheap edits. You can see my implementation &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;ysue&#x2F;src&#x2F;branch&#x2F;main&#x2F;src&#x2F;Rope.hs&quot;&gt;on Codeberg&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-ropes&quot;&gt;Why ropes?&lt;&#x2F;h2&gt;
&lt;p&gt;This has probably been discussed &lt;em&gt;ad nauseam&lt;&#x2F;em&gt;, but I’ll throw a brief justification for using a rope here to save you a click&#x2F;search. Warning: this is not going to be in-depth or anything, so if you’re not persuaded that e.g. ropes are a good idea, it’s probably because I am trying to be brief here.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s the problem: when you’re working in a text editor, you usually are doing edits somewhere in the &lt;em&gt;middle&lt;&#x2F;em&gt; of the file. If you were to store a buffer of &lt;script type=&quot;math&#x2F;tex&quot;&gt;n&lt;&#x2F;script&gt;
 characters in an array, inserting a character at position &lt;script type=&quot;math&#x2F;tex&quot;&gt;i&lt;&#x2F;script&gt;
 would mean that you have t&lt;&#x2F;p&gt;
&lt;p&gt;Ropes, on the other hand, store bits of text in a balanced binary tree. Inserting some text never mutates existing nodes; instead, new nodes from the modified leaf up to the root (so, roughly &lt;script type=&quot;math&#x2F;tex&quot;&gt;\log(n)&lt;&#x2F;script&gt;
 nodes) need to be allocated on insertion.&lt;&#x2F;p&gt;
&lt;p&gt;This comes with two benefits: first, insertion and deletion scale extremely well. Second, since the structure is immutable, you could store the last &lt;script type=&quot;math&#x2F;tex&quot;&gt;k&lt;&#x2F;script&gt;
 copies of the string to implement an “undo” feature in your editor.
Moreover, all the chunks that &lt;em&gt;didn’t&lt;&#x2F;em&gt; get changed don’t take up any extra space, since the data structure enjoys nice structural sharing.&lt;&#x2F;p&gt;
&lt;p&gt;“But what about all those nodes you need to allocate?” you might well ask. Modern garbage collectors are so good these days you won’t even notice. As soon as you’re working with a new copy of the string, or as soon as a copy of the string you’ve been holding onto in your undo buffer gets bumped out, the garbage collector is sure to swiftly reclaim any nodes no longer in use.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;benchmarks&quot;&gt;Benchmarks&lt;&#x2F;h3&gt;
&lt;p&gt;I implemented a rope and ran some benchmarks, comparing it with a naïve string insertion algorithm. Note: reproducing these in other languages will differ based on how your language implements strings. I’m using Haskell, which represents strings as linked lists of characters. This has some trade-offs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Indexing into the &lt;script type=&quot;math&#x2F;tex&quot;&gt;n&lt;&#x2F;script&gt;
-th element takes &lt;script type=&quot;math&#x2F;tex&quot;&gt;O(n)&lt;&#x2F;script&gt;
 time, which isn’t great.&lt;&#x2F;li&gt;
&lt;li&gt;However, joining a string onto the head of another only requires that you walk the first string to its end; you do not have to walk the entire length of the end string.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;haskell_rope_benchmarks.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;Benchmark comparing a series of random edits applied to a rope vs. a string. The rope shows minimal difference in time taken to perform 10 random edits (4.03 μs = 0.004 ms) to 10,000 edits (28.1ms). In contrast, the naïve string implementation jumps from 2.56 μs = 0.002 ms for 10 edits all the way to 3.6 s = 3600 ms for 10,000 edits.&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;I tried running the benchmarks for 100,000 random edits, and the last benchmark never finished even though I let it sit for over an hour. Arrays of characters are not sustainable for editors.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;building-a-rope&quot;&gt;Building a rope&lt;&#x2F;h2&gt;
&lt;p&gt;The original rope paper [&lt;a href=&quot;#citeproc_bib_item_1&quot;&gt;1&lt;&#x2F;a&gt;] and the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rope_(data_structure)&quot;&gt;Wikipedia article on ropes&lt;&#x2F;a&gt; both do a fine job of explaining the data structure. I’ll just outline some gotchas here.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-data-structure&quot;&gt;The data structure&lt;&#x2F;h3&gt;
&lt;p&gt;Here’s my definition of a rope:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;data Rope&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt;  Concat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; Int Int Rope Rope&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt; -- Concat length height left right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  |&lt;&#x2F;span&gt;&lt;span&gt;  Leaf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; Int String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;          -- Leaf length content&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  deriving&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;Show&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; Eq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A rope is either a &lt;code&gt;Leaf&lt;&#x2F;code&gt; node or a &lt;code&gt;Concat&lt;&#x2F;code&gt;​enation of two rope nodes. The &lt;code&gt;Leaf&lt;&#x2F;code&gt; variant contains two fields: a regular ol’ string as well as how long the string is.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:2-1&quot;&gt;&lt;a href=&quot;#fn-fn:2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; The &lt;code&gt;Concat&lt;&#x2F;code&gt; variant holds left and right subtrees, the total length of its subtrees, and how high up in the tree it is. (This is important for balancing later on.)&lt;&#x2F;p&gt;
&lt;p&gt;The string gets broken up between the leaves and the concat nodes hold everything together.&lt;&#x2F;p&gt;
&lt;p&gt;Why do &lt;code&gt;Concat&lt;&#x2F;code&gt; nodes need to hold their length? This is to speed up searching through the tree: since every node knows how long the string underneath it is, we don’t need to go all the way down to the leaves to figure out where in the string we should jump if we’re looking for, say, the 1000th character. This keeps accesses &lt;script type=&quot;math&#x2F;tex&quot;&gt;O(\log(n))&lt;&#x2F;script&gt;
 which is pretty fast.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;balancing-algorithm&quot;&gt;Balancing algorithm&lt;&#x2F;h3&gt;
&lt;p&gt;The balancing algorithm is the trickiest part of implementing a rope, and it’s a bit of a shame that the paper doesn’t have better examples. I did use the paper as a reference to implement the algorithm, so it was &lt;em&gt;clear enough&lt;&#x2F;em&gt;, but more examples are always good!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alternatives-to-ropes&quot;&gt;Alternatives to ropes&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.racket-lang.org&#x2F;rhombus&#x2F;index.html&quot;&gt;Rhombus&lt;&#x2F;a&gt; language uses an RRB tree [&lt;a href=&quot;#citeproc_bib_item_2&quot;&gt;2&lt;&#x2F;a&gt;] for it’s primary list data structure. RRB trees would probably work pretty well for text editing. You can see the Rhombus implementation &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;racket&#x2F;rhombus-prototype&#x2F;blob&#x2F;master&#x2F;design&#x2F;treelist&#x2F;treelist.rhm&quot;&gt;on GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;style&gt;.csl-left-margin{float: left; padding-right: 0em;}
 .csl-right-inline{margin: 0 0 0 1em;}&lt;&#x2F;style&gt;&lt;div class=&quot;csl-bib-body&quot;&gt;
  &lt;div class=&quot;csl-entry&quot;&gt;&lt;a id=&quot;citeproc_bib_item_1&quot;&gt;&lt;&#x2F;a&gt;
    &lt;div class=&quot;csl-left-margin&quot;&gt;[1]&lt;&#x2F;div&gt;&lt;div class=&quot;csl-right-inline&quot;&gt;Boehm Hans‐J., Atkinson, R. and Plass, M. 1995. Ropes: An alternative to strings. &lt;i&gt;Software: Practice and experience&lt;&#x2F;i&gt;. 25, 12 (Dec. 1995), 1315–1330. DOI:&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1002&#x2F;spe.4380251203&quot;&gt;https:&#x2F;&#x2F;doi.org&#x2F;10.1002&#x2F;spe.4380251203&lt;&#x2F;a&gt;.&lt;&#x2F;div&gt;
  &lt;&#x2F;div&gt;
  &lt;div class=&quot;csl-entry&quot;&gt;&lt;a id=&quot;citeproc_bib_item_2&quot;&gt;&lt;&#x2F;a&gt;
    &lt;div class=&quot;csl-left-margin&quot;&gt;[2]&lt;&#x2F;div&gt;&lt;div class=&quot;csl-right-inline&quot;&gt;Stucki, N., Rompf, T., Ureche, V. and Bagwell, P. 2015. &lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1145&#x2F;2784731.2784739&quot;&gt;RRB vector: A practical general purpose immutable sequence&lt;&#x2F;a&gt;. &lt;i&gt;Proceedings of the 20th ACM SIGPLAN International Conference on Functional Programming&lt;&#x2F;i&gt; (Vancouver BC Canada, Aug. 2015), 342–354.&lt;&#x2F;div&gt;
  &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-fn:1&quot;&gt;
&lt;p&gt;I call it “ysue”, for &lt;strong&gt;Y&lt;&#x2F;strong&gt;​ou &lt;strong&gt;S&lt;&#x2F;strong&gt;​hould be &lt;strong&gt;U&lt;&#x2F;strong&gt;​sing &lt;strong&gt;E&lt;&#x2F;strong&gt;​macs. It actually works! I used it to edit its own source code! Get it here: &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;ysue&quot;&gt;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;ysue&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-fn:1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-fn:2&quot;&gt;
&lt;p&gt;Haskell strings are linked lists. This is nice for all sorts of functional operations, but it means that they don’t track how long they are. (As far as I know.) If you use a language that can get the length of the string in &lt;script type=&quot;math&#x2F;tex&quot;&gt;O(1)&lt;&#x2F;script&gt;
 time, you might not need this. &lt;a href=&quot;#fr-fn:2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Functional Languages Need Not Be Slow</title>
        <published>2023-12-20T00:00:00+00:00</published>
        <updated>2023-12-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-12-20_functional_langauge_speed/"/>
        <id>https://beta.lambdaland.org/posts/2023-12-20_functional_langauge_speed/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-12-20_functional_langauge_speed/">&lt;p&gt;Somewhere in my adolescence I got stuck with the notion that functional languages were slow while languages like C were fast. Now, a good C programmer can eke more performance out of their code than probably anyone else, but the cost you pay to keep your code correct goes exponential as you get closer and closer to the machine.&lt;&#x2F;p&gt;
&lt;p&gt;Functional languages abstract a lot away from the machine. Higher languages in general abstract away the machine and make code easier to maintain. So I think I had it in my head that functional languages, being far away from the bare metal, must necessarily be slow. It didn’t help that I also thought of functional languages as being necessarily interpreted languages.&lt;&#x2F;p&gt;
&lt;p&gt;Turns out, functional languages are just as amenable to compilation as imperative ones. Many popular&#x2F;well-known functional are in fact compiled. (E.g. Haskell, Scala, Rust, Julia, etc.) Moreover, these languages can be just as fast—if not faster—than their more “mainstream” counterparts.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to pit my favorite language (Racket) against a &lt;em&gt;slightly&lt;&#x2F;em&gt; more well-known language (Python) to see how they handled a simple single-threaded program. For good measure I threw Rust, Julia, and JavaScript into the mix for comparison.&lt;&#x2F;p&gt;
&lt;p&gt;If you’re impatient, just jump to &lt;a href=&quot;https:&#x2F;&#x2F;beta.lambdaland.org&#x2F;posts&#x2F;2023-12-20_functional_langauge_speed&#x2F;#the-results&quot;&gt;the results&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-programs&quot;&gt;The programs&lt;&#x2F;h2&gt;
&lt;p&gt;I wrote the original program in Racket, then had ChatGPT help me rewrite it in Python. ChatGPT did astoundingly well. I eventually rewrote the program to be a little more idiomatic—I wanted it to use a loop instead of tail recursion, as Python is much better with loops than it is with lots and lots of function calls. I also had ChatGPT help me rewrite the program to Rust, Julia, and JavaScript. Impressive—and unsettling.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#lang&lt;&#x2F;span&gt;&lt;span&gt; racket&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;count-collatz&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cond&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;even?&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;count-collatz&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;count-collatz&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;count-collatz-upto&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;for&#x2F;fold&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      ([&lt;&#x2F;span&gt;&lt;span&gt;max-seen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      ([&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;in-range&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span&gt; max-seen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;count-collatz i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;displayln&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBCB8B;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Done ~a&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;count-collatz-upto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 5000000&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div class=&quot;src-block-caption&quot;&gt;
  &lt;span class=&quot;src-block-number&quot;&gt;Code Snippet 1:&lt;&#x2F;span&gt;
  &lt;code&gt;collatz_check.rkt&lt;&#x2F;code&gt;
&lt;&#x2F;div&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; count_collatz&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; cnt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;max_seen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; count_collatz_upto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    global&lt;&#x2F;span&gt;&lt;span&gt; max_seen&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        the_count&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; count_collatz&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        max_seen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;max_seen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; the_count&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;count_collatz_upto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;5000000&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBCB8B;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Done&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span&gt; max_seen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div class=&quot;src-block-caption&quot;&gt;
  &lt;span class=&quot;src-block-number&quot;&gt;Code Snippet 2:&lt;&#x2F;span&gt;
  &lt;code&gt;collatz_check.py&lt;&#x2F;code&gt;
&lt;&#x2F;div&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; count_collatz&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; &#x2F;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cnt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; count_collatz_upto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; max_seen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        max_seen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; max_seen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;count_collatz&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    max_seen&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;font-weight: bold;&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Done &lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBCB8B;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; count_collatz_upto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;5000000&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div class=&quot;src-block-caption&quot;&gt;
  &lt;span class=&quot;src-block-number&quot;&gt;Code Snippet 3:&lt;&#x2F;span&gt;
  &lt;code&gt;collatz_check.rs&lt;&#x2F;code&gt;
&lt;&#x2F;div&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;julia&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; count_collatz&lt;&#x2F;span&gt;&lt;span&gt;(n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cnt &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;÷&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cnt &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cnt &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; cnt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;max_seen &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; count_collatz_upto&lt;&#x2F;span&gt;&lt;span&gt;(n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        the_count &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; count_collatz&lt;&#x2F;span&gt;&lt;span&gt;(i)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        global&lt;&#x2F;span&gt;&lt;span&gt; max_seen &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; max&lt;&#x2F;span&gt;&lt;span&gt;(max_seen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; the_count)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;count_collatz_upto&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;5000000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;println&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBCB8B;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Done &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span&gt; max_seen)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div class=&quot;src-block-caption&quot;&gt;
  &lt;span class=&quot;src-block-number&quot;&gt;Code Snippet 4:&lt;&#x2F;span&gt;
  &lt;code&gt;collatz_check.jl&lt;&#x2F;code&gt;
&lt;&#x2F;div&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; countCollatz&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  while&lt;&#x2F;span&gt;&lt;span&gt; (n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; !==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ===&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;++;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; cnt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; countCollatzUpto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; maxSeen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    maxSeen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Math&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span&gt;(maxSeen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; countCollatz&lt;&#x2F;span&gt;&lt;span&gt;(i))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; maxSeen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBCB8B;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Done &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;countCollatzUpto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;5000000&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div class=&quot;src-block-caption&quot;&gt;
  &lt;span class=&quot;src-block-number&quot;&gt;Code Snippet 5:&lt;&#x2F;span&gt;
  &lt;code&gt;collatz_check.js&lt;&#x2F;code&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;the-results&quot;&gt;The results&lt;&#x2F;h2&gt;
&lt;p&gt;I ran these programs on my M1 Pro MacBook Pro. Here’s what I got:&lt;&#x2F;p&gt;
&lt;style&gt;.table-nocaption table { text-align: right;  }&lt;&#x2F;style&gt;
&lt;div class=&quot;ox-hugo-table table-nocaption&quot;&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Language&lt;&#x2F;th&gt;&lt;th&gt;Time (seconds)&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Racket&lt;&#x2F;td&gt;&lt;td&gt;4.68&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Python&lt;&#x2F;td&gt;&lt;td&gt;34.27&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Rust&lt;&#x2F;td&gt;&lt;td&gt;3.03&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Julia&lt;&#x2F;td&gt;&lt;td&gt;2.34&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;JavaScript&lt;&#x2F;td&gt;&lt;td&gt;11.92&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;In graphical form:&lt;&#x2F;p&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;benchmark_shootout.svg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;Wow! I did not expect Python to get so pummeled by everything else! It makes sense that Julia with its sweet JIT engine is the fastest. Rust does well—no surprise there. (Note that I’m not counting compilation time here—all the more impressive for Julia!) Racket holds its own though, coming in third place by a wide margin. If you did take Rust’s compile time into account, I think that would make it switch places with Racket. Of course, you use Rust for compile-once-run-lots sorts of scenarios.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;discussion&quot;&gt;Discussion&lt;&#x2F;h2&gt;
&lt;p&gt;Are these authoritative? No, of course not. This is a simple synthetic benchmark. I don’t consider myself expert programmer in &lt;em&gt;any&lt;&#x2F;em&gt; of these languages, so there are likely some performance tweaks that could make the respective language’s benchmark run faster. (Maybe I should in Racket… it’s kind of hard to consider yourself an expert in a language when its creator works down the hall from you though.)&lt;&#x2F;p&gt;
&lt;p&gt;That said, I hope this dispels the myth that functional languages are &lt;em&gt;necessarily&lt;&#x2F;em&gt; slow. That is not the case. If Python is fast enough for your use-case, then there’s no reason you shouldn’t consider using Racket on performance grounds.&lt;&#x2F;p&gt;
&lt;p&gt;Library support is a different matter: of all the programming that goes on in the world, the majority is probably just gluing libraries together to do the thing you want. This is a good thing: it means we’re not reinventing so many wheels and people are getting good work done.&lt;&#x2F;p&gt;
&lt;p&gt;That said, there’s plenty of exciting work for which no library exists! If you find yourself in one of these exciting cases, consider using the tool of maximum power: in this regard, nothing beats Racket for its flexibility and &lt;a href=&quot;&#x2F;posts&#x2F;2023-10-17_fearless_macros&#x2F;&quot;&gt;extensibility&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus-building-the-graph-in-racket&quot;&gt;Bonus: building the graph in Racket&lt;&#x2F;h2&gt;
&lt;p&gt;I love the Racket &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.racket-lang.org&#x2F;plot&#x2F;&quot;&gt;Plot&lt;&#x2F;a&gt; library. So easy to use, so powerful. If you run it inside of DrRacket, the graphs are actually interactive: you can rotate 3D graphs and zoom in on sections of 2D graphs. So neat!&lt;&#x2F;p&gt;
&lt;p&gt;Here’s the code I used to generate the above graph:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;#lang&lt;&#x2F;span&gt;&lt;span&gt; racket&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt; plot&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span&gt; *data*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; #(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&amp;quot;Racket&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 4.68&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) #(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&amp;quot;Python&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 34.27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) #(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&amp;quot;Rust&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 3.03&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) #(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&amp;quot;Julia&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2.34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) #(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&amp;quot;JavaScript&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 11.92&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;parameterize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;plot-font-face&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;Charter&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               [&lt;&#x2F;span&gt;&lt;span&gt;plot-font-size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 14.0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               [&lt;&#x2F;span&gt;&lt;span&gt;plot-x-ticks&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;linear-ticks&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; #:divisors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1 2 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;plot&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;discrete-histogram&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;reverse&lt;&#x2F;span&gt;&lt;span&gt; *data*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;                                  #:gap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;                                  #:invert? #true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        #:title&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;Simple benchmark results&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        #:out-kind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;#39;svg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        #:out-file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;benchmark_shootout.svg&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        #:x-max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 35&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        #:x-label&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;Seconds&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        #:width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 800&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;        #:height&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 200&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why Don&#x27;t More Languages Have a call&#x2F;cc Operator?</title>
        <published>2023-10-30T00:00:00+00:00</published>
        <updated>2023-10-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-10-30_why_no_callcc/"/>
        <id>https://beta.lambdaland.org/posts/2023-10-30_why_no_callcc/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-10-30_why_no_callcc/">&lt;p&gt;Something I’ve wondered about for a little while: why don’t more languages have a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Call-with-current-continuation&quot;&gt;&lt;code&gt;call&#x2F;cc&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; operator? Having &lt;a href=&quot;&#x2F;posts&#x2F;2022-11-17_continutations&#x2F;&quot;&gt;first-class continuations&lt;&#x2F;a&gt; in your programming language gives your programmers a powerful construct. So why do only a handful of languages have it?&lt;&#x2F;p&gt;
&lt;p&gt;The short answer is: it’s tricky to implement efficiently. One way to get &lt;code&gt;call&#x2F;cc&lt;&#x2F;code&gt; is to convert your code into continuation-passing style. Then, &lt;code&gt;call&#x2F;cc&lt;&#x2F;code&gt; simply takes the continuation in that representation and binds it to a variable. Most languages don’t seem to go through a continuation-passing style conversion pass though, so there’s no continuation to grab.&lt;&#x2F;p&gt;
&lt;p&gt;I asked &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;users.cs.utah.edu&#x2F;~mflatt&#x2F;&quot;&gt;Matthew Flatt&lt;&#x2F;a&gt; about this today, and his answer was that most languages use the C model of functions: when you call a function, you push the arguments to the function onto a stack along with the return address. Then, when you return, you pop those element back off the stack. To get &lt;code&gt;call&#x2F;cc&lt;&#x2F;code&gt;, you’ve have to copy the entire stack and pass that around.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Deriving Recursion from First Principles</title>
        <published>2023-10-02T00:00:00+00:00</published>
        <updated>2023-10-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-10-03_recursion_from_first_principles/"/>
        <id>https://beta.lambdaland.org/posts/2023-10-03_recursion_from_first_principles/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-10-03_recursion_from_first_principles/">&lt;div class=&quot;info&quot;&gt;
&lt;p&gt;These are some of my class notes. Learning to derive the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fixed-point_combinator#Y_combinator&quot;&gt;Y Combinator&lt;&#x2F;a&gt; from first principles is something I’ve always wanted to do. This isn’t &lt;em&gt;quite&lt;&#x2F;em&gt; the Y Combinator, but it’s very close and it still gets you recursion without relying on recursive structures to begin with.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;In the beginning, we write a recursive function to compute the length of a list:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;null?&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;                 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cdr&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1 2 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.racket-lang.org&#x2F;reference&#x2F;let.html&quot;&gt;&lt;code&gt;let*&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; syntax allows us to create local variable bindings that can reference themselves. But let’s suppose we don’t have &lt;code&gt;let*&lt;&#x2F;code&gt;—what do we do?&lt;&#x2F;p&gt;
&lt;p&gt;We can make a function that we give to itself. That then returns the function we want, with the outer function in scope. So, the outer function &lt;code&gt;len&lt;&#x2F;code&gt; in this example has “type”[^fn:1] &lt;code&gt;$self → Int → Int&lt;&#x2F;code&gt;. That makes it clear that to get the &lt;code&gt;Int → Int&lt;&#x2F;code&gt; function we want, we have to pass the function to itself.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;null?&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;                   0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                   (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span&gt;len len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cdr&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  ((&lt;&#x2F;span&gt;&lt;span&gt;len len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1 2 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But it’d be nice if we could pull out that &lt;code&gt;(len len)&lt;&#x2F;code&gt; in the body of the function. Let’s call that &lt;code&gt;len1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) ((&lt;&#x2F;span&gt;&lt;span&gt;len len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;null?&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;                     0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cdr&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               ))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  ((&lt;&#x2F;span&gt;&lt;span&gt;len len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1 2 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that what we &lt;em&gt;can’t&lt;&#x2F;em&gt; do is this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;    ; problem here!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;null?&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;                     0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cdr&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               ))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  ((&lt;&#x2F;span&gt;&lt;span&gt;len len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1 2 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Because this is an &lt;em&gt;eager&lt;&#x2F;em&gt; language, so that’d loop forever.&lt;&#x2F;p&gt;
&lt;p&gt;Let’s do that same trick for the outer &lt;code&gt;len len&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) ((&lt;&#x2F;span&gt;&lt;span&gt;len len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;null?&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;                     0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cdr&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               ))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;               ; type of len1 is Int → Int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1 2 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that the &lt;code&gt;(len len)&lt;&#x2F;code&gt; at the end of that is OK because we’re not doing another self application.&lt;&#x2F;p&gt;
&lt;p&gt;Let’s change that inner &lt;code&gt;let&lt;&#x2F;code&gt; to a &lt;code&gt;λ&lt;&#x2F;code&gt; just for fun.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;null?&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cdr&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) ((&lt;&#x2F;span&gt;&lt;span&gt;len len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span&gt;len1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1 2 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;len len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Rename &lt;code&gt;len&lt;&#x2F;code&gt; → &lt;code&gt;self&lt;&#x2F;code&gt;, &lt;code&gt;len1&lt;&#x2F;code&gt; → &lt;code&gt;rec&lt;&#x2F;code&gt;, and just return the function without calling it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;              ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;rec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                   (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;null?&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;rec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cdr&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) ((&lt;&#x2F;span&gt;&lt;span&gt;self self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;self self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok, we are ready… let’s go ahead an extract that part &lt;code&gt;(λ (lst) ...)&lt;&#x2F;code&gt;: that’s the only part of this that knows anything about computing the length of lists. We’ll wrap the whole thing in a function called &lt;code&gt;mk_rec&lt;&#x2F;code&gt; which takes a function of two arguments: the first argument we will pass &lt;code&gt;rec&lt;&#x2F;code&gt; to, and the second is the actual argument to the function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;mk_rec&lt;&#x2F;span&gt;&lt;span&gt; fn_x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt; ; takes two args: the recursive thingy and the argument&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;rec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                   (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span&gt;fn_x rec x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) ((&lt;&#x2F;span&gt;&lt;span&gt;self self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span&gt;self self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span&gt; len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;mk_rec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;rec lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;null?&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;rec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;cdr&lt;&#x2F;span&gt;&lt;span&gt; lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1 2 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;                          ; returns 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span&gt; fact&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;mk_rec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;rec x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;zero?&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;rec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;fact&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;                                ; returns 120&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that that isn’t actually the the Y combinator exactly. But hey we have recursion without using recursion!&lt;&#x2F;p&gt;
&lt;p&gt;+++
&lt;em&gt;Source = “FreeBSD &lt;code&gt;fortune&lt;&#x2F;code&gt; files; this is probably my favorite quine ever.&lt;&#x2F;em&gt;”&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My Commitment to Intellectual Integrity</title>
        <published>2023-09-23T00:00:00+00:00</published>
        <updated>2023-09-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-09-23_all_original/"/>
        <id>https://beta.lambdaland.org/posts/2023-09-23_all_original/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-09-23_all_original/">&lt;p&gt;I got a strange email the other day. Here it is, with parts redacted:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hi there,&lt;&#x2F;p&gt;
&lt;p&gt;My name is G—, I am the main editor at —————.&lt;&#x2F;p&gt;
&lt;p&gt;While browsing your site, I noticed you have an amazing article from this page:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Link to an extremely old post of mine&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;My team actually just published a comprehensive article on “&lt;em&gt;Semi-related title&lt;&#x2F;em&gt;” which I think your visitors would truly
appreciate and add value to your awesome article.&lt;&#x2F;p&gt;
&lt;p&gt;You can check it out here: ———————&lt;&#x2F;p&gt;
&lt;p&gt;If you were willing to add our link to that page, I would be more than happy to share it to more than a thousand of our social followers to help you
gain some visibility in exchange.&lt;&#x2F;p&gt;
&lt;p&gt;Let me know what you think and thank you for your consideration!&lt;&#x2F;p&gt;
&lt;p&gt;Cheers,&lt;&#x2F;p&gt;
&lt;p&gt;G— ———&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;My mail program correctly marked it as spam, which I appreciate. (Besides the spammy feel of the text, the article of mine they reference is an “amazing” &amp;gt;300 word blurb about a one-day project I did in 2017. Sheesh…) I was a little shocked that someone would ask me to engage in the kind of social-metrics-engineering which I feel has contributed directly to many of the social problems plaguing us today.&lt;&#x2F;p&gt;
&lt;p&gt;I decided to make a public promise that I would hold myself to. Here it is:&lt;&#x2F;p&gt;
&lt;div class=&quot;info&quot;&gt;
&lt;p&gt;I am a scholar. As such, I have a sacred duty to uphold truth at all times and to share knowledge freely. I will never do anything that might compromise my ability to do such. If there is anything beautiful, truthful, or honorable, I will promote it. I will never accept bribery or engage in influence peddling; I find it intellectually and morally repugnant to use my station as an academic for personal gain.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;I’ll make mistakes—and I won’t stop talking about tools and services that I think genuinely serve my desires for greater knowledge, understanding, and freedom—but I will never do this in exchange for money, social clout, or whatever. If I attain any fame, it will not be because it was my end goal.&lt;&#x2F;p&gt;
&lt;p&gt;So, G—, here is what I think of your offer: &lt;em&gt;get lost—your proposal disgusts me&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Reflections one year into a PhD program</title>
        <published>2023-08-05T00:00:00+00:00</published>
        <updated>2023-08-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-08-05_one_year_into_phd/"/>
        <id>https://beta.lambdaland.org/posts/2023-08-05_one_year_into_phd/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-08-05_one_year_into_phd/">&lt;p&gt;I started my PhD program about a year ago. In my first year I have:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Taken 4 “normal” 3-credit-hour classes&lt;&#x2F;li&gt;
&lt;li&gt;Participated in 3 seminars&lt;&#x2F;li&gt;
&lt;li&gt;Switched advisors&lt;&#x2F;li&gt;
&lt;li&gt;Attended 2 conferences (PLDI @ FCRC, JuliaCon)&lt;&#x2F;li&gt;
&lt;li&gt;Presented my work at JuliaCon&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It’s been a lot of work, and there’s been a lot of stress. I’m in a much better place now than when I started, and over all I’m happy where I’m at and where I’m headed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;changing-advisors&quot;&gt;Changing advisors&lt;&#x2F;h2&gt;
&lt;p&gt;Some of the stress has come from finances: it’s hard to support a family on a PhD stipend with rising costs of living.&lt;&#x2F;p&gt;
&lt;p&gt;The most stress I felt was in my first semester. I got hired on as an RA&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:1-1&quot;&gt;&lt;a href=&quot;#fn-fn:1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; with a nice researcher and we hit it off well. But I discovered half way through the semester that I was not enjoying the work. This wasn’t anyone’s fault—I had to do a little bit of the work to find out that I wasn’t that interested in what I was doing.&lt;&#x2F;p&gt;
&lt;p&gt;At first I thought that I might be able to power through. I didn’t want to be the kind of student that hops from advisor to advisor or from project to project just as the going gets tough, boring, or unpleasant. But I talked with &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kimball.germane.net&#x2F;&quot;&gt;my advisor from undergrad&lt;&#x2F;a&gt;, and he explained that a PhD sets the tone of your research basically until you get tenure. That’s a long time—and I didn’t want to work in that area for a decade or better. I realized that I either had to change what I was working on, or I needed to quit and go back to industry.&lt;&#x2F;p&gt;
&lt;p&gt;I started looking around at what my options were. My school assigns every grad student a “faculty mentor”—a faculty member who is not your advisor that’s “assigned” to you. In my experience, most professors are more than happy to talk to you if you need help—this one just happened to be assigned to me. At some point I discovered that &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cs.brown.edu&#x2F;people&#x2F;bgreenma&#x2F;&quot;&gt;Ben Greenman&lt;&#x2F;a&gt; was coming to the U as a professor. I called him, we talked, and we figured out that our interests were much more closely aligned. Problem was, Ben wasn’t starting at the U until the fall. I found a fellowship for one semester, and was able to do work with Ben and another professor through the summer.&lt;&#x2F;p&gt;
&lt;p&gt;Finding an advisor whose interests aligned with mine was a &lt;em&gt;huge&lt;&#x2F;em&gt; improvement for my work and my mental health. If you are looking into going to grad school, I would make that your top priority. And it wasn’t that my first advisor was &lt;em&gt;bad&lt;&#x2F;em&gt; in any way—we’re still friends, we chat when we run into each other in the hall, and I learned a lot from him—it’s just that our interests were less aligned than I originally thought, and it took a little time to discover that. Better sooner rather than later, though.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reading-papers&quot;&gt;Reading papers&lt;&#x2F;h2&gt;
&lt;p&gt;One thing I noticed this week that made me really happy: reading research papers is a lot easier for me now. When I started getting interested in research back in my undergrad, I found reading papers to be &lt;em&gt;so&lt;&#x2F;em&gt; arduous. It took me a week or more to get through a single paper, and I never got a lot out of them. I felt like it was difficult for me to even understand the questions that the paper was trying to answer.&lt;&#x2F;p&gt;
&lt;p&gt;Now I’m more familiar with the context and the jargon, and I can grasp the questions the paper is trying to answer better. The format of research papers is familiar to me now, and that familiarity reduces the amount of friction I encounter when reading. It took time and exposure, and I don’t think there’s a substitute for that. Reading papers and discussing them with my advisors was a big help too.&lt;&#x2F;p&gt;
&lt;p&gt;The paper &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.stanford.edu&#x2F;class&#x2F;ee384m&#x2F;Handouts&#x2F;HowtoReadPaper.pdf&quot;&gt;How to Read a Paper&lt;&#x2F;a&gt; is probably the single most valuable bit of help an aspiring researcher can get. You should read it. (It’s short: 2 pages)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;classes&quot;&gt;Classes&lt;&#x2F;h2&gt;
&lt;p&gt;Grad classes have a different tone than undergrad classes. As one of my professors put it, you will get an A or a B unless you persuade the professor that you should get a lower grade. This is nice because I have to keep a particular GPA to qualify for tuition benefit.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:2-1&quot;&gt;&lt;a href=&quot;#fn-fn:2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; That means I can do the minimum to learn the material and spend the majority of my time and energy on research.&lt;&#x2F;p&gt;
&lt;p&gt;After switching research projects, I noticed a switch in my priorities: my first semester, I would do my class work and then do research if I had time left over. My second semester, I did research first and class work happened when I had nothing else to do. I like the second balance better.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conferences-and-speaking&quot;&gt;Conferences and speaking&lt;&#x2F;h2&gt;
&lt;p&gt;I got to present my work at JuliaCon 2023. I’ll put up a link to the video when it comes out, but if you poke around &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;juliacon.org&#x2F;2023&#x2F;&quot;&gt;the recordings&lt;&#x2F;a&gt; you should be able to find the talk in the middle of a long recording.&lt;&#x2F;p&gt;
&lt;p&gt;It was fun to prepare and present our work at a conference. It was also a &lt;em&gt;ton&lt;&#x2F;em&gt; of effort. I have never put that much time and energy into preparing a talk as I did for that conference. And it turned out pretty well, if I do say so myself. Hopefully subsequent talks will be less stressful, less effort, &lt;em&gt;and&lt;&#x2F;em&gt; even higher-quality!&lt;&#x2F;p&gt;
&lt;p&gt;JuliaCon was hosted in Boston; before that I went to PLDI in Orlando. Boston is &lt;em&gt;far&lt;&#x2F;em&gt; superior to Orlando. Orlando is a wasteland of hotels and conference centers and has nothing walkable anywhere. In contrast, Boston is a vibrant city that is a delight to walk around with plenty of interesting things to see.&lt;&#x2F;p&gt;
&lt;p&gt;It has been satisfying getting to know people in the PL community. It’s also been nice to work more closely with professors in my department. I’m lucky I get to hang around with so many curious, intelligent, and friendly people.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;satisfaction&quot;&gt;Satisfaction&lt;&#x2F;h2&gt;
&lt;p&gt;I’m happy with where I am. The PhD program was hard at first—and it’s still hard—but it’s a different, more interesting kind of hard, and I like that.&lt;&#x2F;p&gt;
&lt;p&gt;I think I’ll like the next few years. I still don’t know if I want to go into industry for a few years after or find a post-doc position in academia. Long-term I want to be a professor. We’ll see how it pans out though.&lt;&#x2F;p&gt;
&lt;p&gt;If you are looking for interns to study topics related to static analysis, macro systems, type systems, and language design, please &lt;a href=&quot;&#x2F;#contact&quot;&gt;drop me a line&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-fn:1&quot;&gt;
&lt;p&gt;Research Assistant. At least where I attend, there are Research Assistants, Graduate Assistants, and Teaching Assistants. RAs have funding and get paid to do research. GAs either have some kind of fellowship (some kind of grant&#x2F;fund&#x2F;pool of money from the school rather than a research grant) or are paying their own way. TAs teach classes in exchange for tuition and stipend money. &lt;a href=&quot;#fr-fn:1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-fn:2&quot;&gt;
&lt;p&gt;Tuition benefit: PhD students at my school in my field (CS) get their tuition paid for by the school. There are some obligations around this, such as taking a certain number of credit-hours each semester and maintaining a decent GPA. &lt;a href=&quot;#fr-fn:2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Warp Factor Refactoring in Emacs</title>
        <published>2023-06-01T00:00:00+00:00</published>
        <updated>2023-06-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-05-31_warp_factor_refactor/"/>
        <id>https://beta.lambdaland.org/posts/2023-05-31_warp_factor_refactor/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-05-31_warp_factor_refactor/">&lt;p&gt;Here’s a nifty Emacs workflow for doing a project-wide search-and-replace on steroids. While I do use refactor tools that come with language servers,&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:1-1&quot;&gt;&lt;a href=&quot;#fn-fn:1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; sometimes those aren’t enough. Consider the case where you not only need to change the name of a function, but also e.g. need to swap the order of two of its arguments. Or you’ve broken one function out into two that need to be chained together. Whatever—there are plenty of ways where the IDE won’t be able to do everything that you need. Enter: Emacs.&lt;&#x2F;p&gt;
&lt;p&gt;Here is what it looks like in action:&lt;&#x2F;p&gt;
&lt;video width=&quot;730&quot; height=&quot;458&quot; controls&gt;
  &lt;source src=&quot;&#x2F;img&#x2F;warp_speed_edits.mp4&quot; type=&quot;video&#x2F;mp4&quot;&gt;
&lt;&#x2F;video&gt;
&lt;p&gt;Here’s what I did:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I searched for lines matching &lt;code&gt;set_&lt;&#x2F;code&gt; and &lt;code&gt;_config&lt;&#x2F;code&gt; in my project, and got over 90 matches.&lt;&#x2F;li&gt;
&lt;li&gt;I moved all the matches to their own buffer.&lt;&#x2F;li&gt;
&lt;li&gt;I used a regex replace on the buffer to transform patterns matching &lt;code&gt;&#x2F;set_([a-z]+)_config!&#x2F;&lt;&#x2F;code&gt; into &lt;code&gt;config_\1!&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;I saved those changes back into the files where the came from.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note that this replaced &lt;em&gt;two&lt;&#x2F;em&gt; symbols simultaneously: &lt;code&gt;set_logger_config!&lt;&#x2F;code&gt; and &lt;code&gt;set_injector_config!&lt;&#x2F;code&gt;. Moreover, this updated all the documentation as well, because I &lt;em&gt;wasn’t&lt;&#x2F;em&gt; relying on my language server to find instances of that symbol in the source code: I could look inside of doc strings and README files as well! (That can be a two-edged sword, so you’ll want to be careful with this.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Here is why this workflow rocks:&lt;&#x2F;strong&gt; Once you’ve dumped the search results into a buffer, you have the &lt;em&gt;full power&lt;&#x2F;em&gt; of Emacs at your disposal. I have recorded keyboard macros, used regex replace from &lt;code&gt;evil-mode&lt;&#x2F;code&gt;, and done other zany things to effect large-scale edits with elegance and speed. You’re not limited to dumb exact-match symbol replacement—you’ve got a lot of tools that you already know at your disposal.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;engage-the-editor&quot;&gt;Engage the editor&lt;&#x2F;h2&gt;
&lt;p&gt;You will need the following third-party packages to make this work, as well as &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BurntSushi&#x2F;ripgrep&quot;&gt;ripgrep&lt;&#x2F;a&gt; installed on your system:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;vertico&quot;&gt;Vertico&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:2-1&quot;&gt;&lt;a href=&quot;#fn-fn:2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;consult&quot;&gt;Consult&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;oantolin&#x2F;embark&quot;&gt;Embark&lt;&#x2F;a&gt; (also &lt;code&gt;embark-consult&lt;&#x2F;code&gt;, but that ships with Embark anyway)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mhayashi1120&#x2F;Emacs-wgrep&quot;&gt;wgrep&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All except wgrep are available from &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;elpa.gnu.org&#x2F;&quot;&gt;GNU ELPA&lt;&#x2F;a&gt;, and you can get wgrep &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;elpa.nongnu.org&#x2F;&quot;&gt;Non-GNU ELPA&lt;&#x2F;a&gt;, so you shouldn’t have trouble finding and installing these—especially if you’re running Emacs 28 or newer.&lt;&#x2F;p&gt;
&lt;p&gt;Why all the packages? That sure seems like a lot (4 whole packages!) for something that seems pretty complicated for a single feature. Well, Vertico, Consult, and Embark are &lt;em&gt;mostly&lt;&#x2F;em&gt; there for the slick UI. wgrep does all the heavy lifting. I’d recommend installing Vertico, Consult, and Embark&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:3-1&quot;&gt;&lt;a href=&quot;#fn-fn:3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; anyway for how much they improve discoverability and add really useful ways of interacting with Emacs.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s the short of what each package contributes:&lt;&#x2F;p&gt;
&lt;dl&gt;
&lt;dt&gt;Vertico&lt;&#x2F;dt&gt;
&lt;dd&gt;Turns the default minibuffer completion UI into an auto-updating list of candidates. This lets us interact with “candidates”—or more specifically in our case, lines matching a pattern across our entire project—in a fast and accessible way.&lt;&#x2F;dd&gt;
&lt;dt&gt;Consult&lt;&#x2F;dt&gt;
&lt;dd&gt;Adds a bunch of &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;emacs&#x2F;manual&#x2F;html_node&#x2F;elisp&#x2F;Minibuffer-Completion.html&quot;&gt;&lt;code&gt;completing-read&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;-based functions. This lets us use ripgrep with Vertico’s UI.&lt;&#x2F;dd&gt;
&lt;dt&gt;Embark&lt;&#x2F;dt&gt;
&lt;dd&gt;Kind of like a generalized keyboard-focused right-click on crazy steroids. This lets us export our list of matches out of Vertico’s UI and into a buffer that wgrep can use.&lt;&#x2F;dd&gt;
&lt;dt&gt;wgrep&lt;&#x2F;dt&gt;
&lt;dd&gt;Takes a buffer of search results, &lt;em&gt;lets us edit that buffer&lt;&#x2F;em&gt;, and then &lt;em&gt;reflect&lt;&#x2F;em&gt; those changes back into the files from the lines that they came from.&lt;&#x2F;dd&gt;
&lt;&#x2F;dl&gt;
&lt;h3 id=&quot;installing-and-configuring&quot;&gt;Installing and configuring&lt;&#x2F;h3&gt;
&lt;p&gt;Here are some sample configurations you can use.&lt;&#x2F;p&gt;
&lt;p&gt;If use &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jwiegley&#x2F;use-package&quot;&gt;use-package&lt;&#x2F;a&gt;,&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:4-1&quot;&gt;&lt;a href=&quot;#fn-fn:4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; here is how you can set it up to automatically install next time you evaluate your &lt;code&gt;init.el&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span&gt; vertico&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;ensure t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;vertico-mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span&gt; consult&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;ensure t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;bind&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  ((&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;C-c r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span&gt; consult-ripgrep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span&gt; embark&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;ensure t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;bind&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  ((&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;C-c a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span&gt; embark-act&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span&gt; embark-consult&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;  ;; comes bundled with Embark; no `:ensure t&amp;#39; necessary&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;after&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;embark consult&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span&gt; wgrep&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;ensure t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Alternatively, you can install the packages with &lt;code&gt;M-x package-install-package&lt;&#x2F;code&gt;, and your config should look like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; make sure all your packages are installed before using these&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;vertico-mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; global-map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;C-c a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;embark-act&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; global-map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;C-c r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;consult-ripgrep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you use fancy package managers like &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;progfolio&#x2F;elpaca&quot;&gt;Elpaca&lt;&#x2F;a&gt; (what I use) or &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;quelpa&#x2F;quelpa&quot;&gt;Quelpa&lt;&#x2F;a&gt;, I trust that you know how to modify the above to suit your needs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;make-it-so&quot;&gt;Make it so&lt;&#x2F;h2&gt;
&lt;p&gt;Once you have the packages installed, here are the steps you take to do this:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Invoke &lt;code&gt;consult-ripgrep&lt;&#x2F;code&gt;. (Bound to &lt;code&gt;C-c r&lt;&#x2F;code&gt; in the sample config.)&lt;&#x2F;li&gt;
&lt;li&gt;Type your search query. Note that space-separated patterns can match different parts of the line in different orders.&lt;&#x2F;li&gt;
&lt;li&gt;Invoke &lt;code&gt;embark-act&lt;&#x2F;code&gt;. (Bound to &lt;code&gt;C-c a&lt;&#x2F;code&gt; in the sample config.) This will open a buffer with a list of keys you can press next.&lt;&#x2F;li&gt;
&lt;li&gt;Hit &lt;code&gt;E&lt;&#x2F;code&gt; for &lt;code&gt;embark-export&lt;&#x2F;code&gt;. This opens up a new buffer with all the matches. Note that you should be able to further filter results with something like &lt;code&gt;consult-keep-lines&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Hit &lt;code&gt;C-c C-p&lt;&#x2F;code&gt; to run &lt;code&gt;wgrep-change-to-wgrep-mode&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Make your edits.&lt;&#x2F;li&gt;
&lt;li&gt;Hit &lt;code&gt;C-c C-c&lt;&#x2F;code&gt; to finish editing, then hit &lt;code&gt;q&lt;&#x2F;code&gt; to close the buffer.&lt;&#x2F;li&gt;
&lt;li&gt;Hit &lt;code&gt;C-x s&lt;&#x2F;code&gt; to run &lt;code&gt;save-some-buffers&lt;&#x2F;code&gt; to make sure writes are committed.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:5-1&quot;&gt;&lt;a href=&quot;#fn-fn:5&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;That’s it. Happy hacking!&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-fn:1&quot;&gt;
&lt;p&gt;Julia’s language server, for instance, comes with a nice “rename symbol” feature. I know lots of other IDEs and language servers offer this sort of thing. &lt;a href=&quot;#fr-fn:1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-fn:2&quot;&gt;
&lt;p&gt;This one isn’t &lt;em&gt;strictly&lt;&#x2F;em&gt; necessary with Emacs 28 and beyond thanks to enhancements made to the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.masteringemacs.org&#x2F;article&#x2F;understanding-minibuffer-completion&quot;&gt;default minibuffer interface&lt;&#x2F;a&gt;, but I can’t think of a good reason to &lt;em&gt;not&lt;&#x2F;em&gt; use Vertico: it is small, well-maintained, and it never ceases to impress me with how robust and flexible it is. &lt;a href=&quot;#fr-fn:2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-fn:3&quot;&gt;
&lt;p&gt;Let’s not forget also the excellent &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;marginalia&#x2F;&quot;&gt;Marginalia&lt;&#x2F;a&gt; and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;oantolin&#x2F;orderless&quot;&gt;Orderless&lt;&#x2F;a&gt; packages too! &lt;a href=&quot;#fr-fn:3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-fn:4&quot;&gt;
&lt;p&gt;Now built-in to Emacs 29! So many excellent features in Emacs 29! &lt;a href=&quot;#fr-fn:4-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-fn:5&quot;&gt;
&lt;p&gt;There is, of course, a way to do this automatically. Per the wgrep docs, put &lt;code&gt;(setq wgrep-auto-save-buffer t)&lt;&#x2F;code&gt; in your config. &lt;a href=&quot;#fr-fn:5-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hike up Desolation Trail</title>
        <published>2023-05-26T00:00:00+00:00</published>
        <updated>2023-05-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/personal/2023-05-26-hike/"/>
        <id>https://beta.lambdaland.org/posts/personal/2023-05-26-hike/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/personal/2023-05-26-hike/">&lt;p&gt;I hiked up Desolation Trail with &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;solitum.net&#x2F;&quot;&gt;Scott Wiersdorf&lt;&#x2F;a&gt;. It had rained a little bit the night before, so the trail was neither dusty nor muddy—perfect for hiking.&lt;&#x2F;p&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;hike_trip_overview.jpeg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;Hike overview&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Lots of pretty plants on the way.&lt;&#x2F;p&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;hike_arrow_leaf.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;This flower is called Arrow Leaf&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;hike_ground_cover.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;Some pretty ground cover&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;hike_tree.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;A neat old tree that got split&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;The way up was nice and scenic.&lt;&#x2F;p&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;hike_north_view.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;View from the trail looking at Church Fork or Grandeur Peak—I forget which&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Views at the top were spectacular.&lt;&#x2F;p&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;hike_south_view.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;Looking south at some snow in the draws&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;hike_overlook.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;View over the valley&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;hike_pano.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;Panorama from the Salt Lake Valley Overlook&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Writing Racket Macros: define-syntax and phases</title>
        <published>2023-05-19T00:00:00-06:00</published>
        <updated>2023-05-19T00:00:00-06:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-05-19_racket_macros/"/>
        <id>https://beta.lambdaland.org/posts/2023-05-19_racket_macros/</id>
        
        <summary type="html">&lt;p&gt;There are a bunch of different ways of writing a macro in Racket. There are also some tricky things around phases to keep in mind. This is to help me keep them all straight.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Meta: Update should fix RSS feeds</title>
        <published>2023-05-13T00:00:00+00:00</published>
        <updated>2023-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-05-13_rss_fixup/"/>
        <id>https://beta.lambdaland.org/posts/2023-05-13_rss_fixup/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-05-13_rss_fixup/">&lt;p&gt;I recently made an update to how I build my blog. I like writing my posts with Org-mode because it provides a richer markup language than Markdown. Plus, more Emacs = more good. &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gohugo.io&#x2F;&quot;&gt;Hugo&lt;&#x2F;a&gt; has support for Org files, but there was a problem with the RSS feed generation: all of my posts written in Org got truncated at some point. I don’t know if the fault lies with Hugo itself or with some problem in the theme I use—whatever it was, I don’t have the time right now to debug that and submit a good bug report or a fix. Instead, I’m using the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ox-hugo.scripter.co&#x2F;&quot;&gt;ox-hugo&lt;&#x2F;a&gt; org-mode exporter, so I still can write my posts with Org, but then let Emacs export them to Markdown for Hugo to process.&lt;&#x2F;p&gt;
&lt;p&gt;Yes, it’s a Rube Goldberg machine. But what would a programmer’s blog be if the build wasn’t convoluted like this? Anyway, RSS feeds are fixed now—I checked. If you happened to read anything only via RSS, and found the content cut off at a strange point, this might have fixed it for some posts. Let me know if you run into any other strange issues.&lt;&#x2F;p&gt;
&lt;p&gt;Cheers!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The kind of thinking computer science enables</title>
        <published>2023-05-11T00:00:00+00:00</published>
        <updated>2023-05-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-05-11_thinking_cs/"/>
        <id>https://beta.lambdaland.org/posts/2023-05-11_thinking_cs/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-05-11_thinking_cs/">&lt;p&gt;I believe computer science plays as integral of a part to a well-rounded liberal arts education as does mathematics and linguistics. Why? A liberal arts education is designed to help you think in new and better ways. Computer science teaches novel ways of thinking, reasoning, and approaching problems that are hard to get anywhere else.&lt;&#x2F;p&gt;
&lt;p&gt;I took a class on pedagogy when I encountered this puzzle. I answered the question easily, and I caught myself using reasoning patterns from work in programming coming to the forefront.&lt;&#x2F;p&gt;
&lt;p&gt;Consider the following problem: suppose you have four cards, each of which has a letter on one side, and a number on the other. The cards are arranged like so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-------+  +-------+  +-------+  +-------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |  |       |  |       |  |       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|   A   |  |   2   |  |   B   |  |   3   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |  |       |  |       |  |       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-------+  +-------+  +-------+  +-------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Suppose the cards follow the rule that, if a card has a vowel on one side, the other side &lt;em&gt;must&lt;&#x2F;em&gt; be an even number. What is the smallest number of cards you need to turn over to verify that the rule holds for these cards? Which cards?&lt;&#x2F;p&gt;
&lt;p&gt;Give yourself a second to think about it, and try and figure it out.&lt;&#x2F;p&gt;
&lt;details&gt;&lt;summary&gt;Answer&lt;&#x2F;summary&gt;
The answer is 2, and the cards are A and 3
&lt;&#x2F;details&gt;
&lt;p&gt;Did you get that? I translated the rule into the logical implication &lt;em&gt;if vowel → then even number&lt;&#x2F;em&gt;. It says nothing about the opposite side of a card if the number is even. Thus, we only need to check cards &lt;code&gt;A&lt;&#x2F;code&gt; and &lt;code&gt;3&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The point of the exercise that we were doing was to showcase how difficult reasoning with abstract symbols is. After showing this example with the cards, our instructor gave us another equivalent problem, but this time using familiar terms around conditions on the legal drinking age. The point was that familiar analogies reduce cognitive load, thereby freeing the students’ minds for grasping bigger and more important ideas.&lt;&#x2F;p&gt;
&lt;p&gt;Yet &lt;em&gt;I&lt;&#x2F;em&gt; found it easy to answer the first and more abstract problem. I’m not a genius or anything—I’ve just practiced this kind of reasoning with computer science. Anyone can do that.&lt;&#x2F;p&gt;
&lt;p&gt;Computer science teaches abstract reasoning in a way that nothing else can. I suppose once you get far enough into mathematics you get to experience a lot of the same sorts of ideas—but only math majors ever make it that far. Programming forces you to confront abstract reasoning about conditions and rules and how they combine from the outset.&lt;&#x2F;p&gt;
&lt;p&gt;Moreover, teaching programming can be fun! You don’t have to go all out into gamification to elicit delight in seeing a computer follow your instructions. The feedback loop between writing code and getting a response is so tight; I think students have an easier time in computer science pushing themselves to reason through problems because they can get fast immediate and real feedback from the computer.&lt;&#x2F;p&gt;
&lt;p&gt;I think more people should learn programming to learn how to think like a programmer. We also need to do a better job designing our CS courses in high school and university to focus on this kind of transferable skill, and we need to de-emphasize whatever &lt;code&gt;$hot_new_framework&lt;&#x2F;code&gt; is being pushed by industry in the classroom.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using a Real Mail Client with Outlook</title>
        <published>2023-05-03T00:00:00+00:00</published>
        <updated>2023-05-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-05-03_email_with_outlook/"/>
        <id>https://beta.lambdaland.org/posts/2023-05-03_email_with_outlook/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-05-03_email_with_outlook/">&lt;p&gt;I recently managed to get access to my Outlook email from Emacs. This took some doing as my university had disabled app passwords. I &lt;a href=&quot;&#x2F;posts&#x2F;2022-08-28_keep_email_federated&quot;&gt;consider Outlook to be harmful&lt;&#x2F;a&gt;, but inasmuch as companies and schools continue to enforce OAUTH-only authentication with email systems, it is good to find workarounds.&lt;&#x2F;p&gt;
&lt;p&gt;This is how I set up email sending&#x2F;receiving on my computer running macOS with &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;davmail.sourceforge.net&#x2F;index.html&quot;&gt;DavMail&lt;&#x2F;a&gt;. I also use &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;linux.die.net&#x2F;man&#x2F;1&#x2F;mbsync&quot;&gt;mbsync&lt;&#x2F;a&gt; (confusingly also known as isync) to actually fetch my email, and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.djcbsoftware.nl&#x2F;code&#x2F;mu&#x2F;&quot;&gt;mu&#x2F;mu4e&lt;&#x2F;a&gt; to index and read mail. &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;douglasrumbaugh.com&#x2F;post&#x2F;davmail-authentication&#x2F;&quot;&gt;Douglas Rumbaugh has an awesome blog post&lt;&#x2F;a&gt; that I followed to get this working. You should read that. This will mostly be my specific configuration settings as well as some tips and tricks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;davmail-configuration&quot;&gt;DavMail configuration&lt;&#x2F;h2&gt;
&lt;p&gt;I just installed DavMail using &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;brew.sh&#x2F;&quot;&gt;brew&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;brew&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; install davmail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I tried installing the cask version, but that never worked for me. Oh well. Command line is better anyway.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;config-file&quot;&gt;Config file&lt;&#x2F;h3&gt;
&lt;p&gt;Now comes the tricky part: we need to point DavMail the right direction to fetch a token. Start with the following in a config file: (I used &lt;code&gt;~&#x2F;.davmail.properties&lt;&#x2F;code&gt; as my config file)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Disallow access to the davmail server from remote hosts (i.e., other&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# computers on the network)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.allowRemote=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Don&amp;#39;t use SSL (between email client and davmail)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.nosecurecaldav=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.nosecureimap=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.nosecureldap=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.nosecuresmtp=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Ports to run the different services on. You&amp;#39;ll need these to connect&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# your clients. If you have several Exchange accounts, each one will need&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# to run on different ports&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.caldavPort=5000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.imapPort=5001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ldapPort=5002&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.smtpPort=5003&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Connection details for your exchange account. Odds are good that the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# url listed here will work for you. If not, see if your University&#x2F;employer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# has any details on the correct host URL to connect to their email services&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# with.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.url=https:&#x2F;&#x2F;outlook.office365.com&#x2F;EWS&#x2F;Exchange.asmx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Set the authentication mode to manual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.mode=O365Manual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Run davmail in server mode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.server=true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.enableKeepAlive=true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That’s snarfed verbatim from the Douglas Rumbaugh post. The &lt;code&gt;davmail.url&lt;&#x2F;code&gt; worked for me, and will probably work for you. My university uses a Duo-2FA powered authentication system, and that’s still the right URL. Go figure.&lt;&#x2F;p&gt;
&lt;p&gt;With that in place, fire up DavMail on the terminal like so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;davmail&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; ~&#x2F;.davmail.properties&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;        # put the path to your config file here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This sets up a mail server &lt;em&gt;proxy&lt;&#x2F;em&gt; running locally on your computer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;email-client-config&quot;&gt;Email client config&lt;&#x2F;h2&gt;
&lt;p&gt;Douglas Rumbaugh has some examples for mbsync, which is what I use too. I like using the built-in macOS &lt;code&gt;security&lt;&#x2F;code&gt; tool to store my passwords in my system keychain, so I don’t have to type a gpg decryption key every time I want to sync.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;security&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; add-generic-password -a umail -s mbsync -w&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;   # this will prompt for the secret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I put the login I use for my school account in there.&lt;&#x2F;p&gt;
&lt;p&gt;Now, inside my &lt;code&gt;.mbsyncrc&lt;&#x2F;code&gt; I can do this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;IMAPAccount uni&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Host 127.0.0.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Port 1143&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;User XXXXXXXX@XXXXX.edu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PassCmd &amp;quot;security find-generic-password -a umail -s mbsync -w&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SSLType None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;AuthMechs LOGIN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;IMAPStore uni-remote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Account uni&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MaildirStore uni-local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Path ~&#x2F;Mail&#x2F;Umail&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Inbox ~&#x2F;Mail&#x2F;Umail&#x2F;INBOX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SubFolders Verbatim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Channel uni&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Far :uni-remote:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Near :uni-local:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Patterns *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SyncState *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Create Both&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sync All&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Expunge Near&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;fetching-the-secret-token&quot;&gt;Fetching the secret token&lt;&#x2F;h2&gt;
&lt;p&gt;With DavMail running and an IMAP-speaking client ready to go, you are prepared to fetch a secret token.&lt;&#x2F;p&gt;
&lt;p&gt;Sync your mail through DavMail—in my case, by running &lt;code&gt;mbsync -a uni&lt;&#x2F;code&gt;. You should see a link pop up in the DavMail log output:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Please open the following link:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https:&#x2F;&#x2F;login.microsoftonline.com&#x2F;common&#x2F;oauth2&#x2F;authorize?&amp;lt;...&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; proceed through authentication steps and paste back the final url that contains authentication code (blank page)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Authentication code:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Follow the instructions on the page—I finished doing a DUO push. Once that was done, I got redirected to a blank screen. &lt;strong&gt;COPY THE URL&lt;&#x2F;strong&gt; of that page, and dump it into a text editor to pull out the key you will need from the query string.&lt;&#x2F;p&gt;
&lt;p&gt;The key will look something like &lt;code&gt;{AES}&amp;lt;really long base64 encoded string&amp;gt;&lt;&#x2F;code&gt;, and for me it was sandwiched between a few of the query parameters.&lt;&#x2F;p&gt;
&lt;p&gt;With that key in hand, you can either paste it into the terminal, or you might have to open the DavMail config file. Douglas’s instructions said pasting the whole URL worked for him, but it never did for me.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s what my config file looked like in the end:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.keystoreType=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.keystorePass=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.proxyPassword=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.oauth.tenantId=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.oauth.clientId=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.smtpPort=1025&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.enableKerberos=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.folderSizeLimit=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.forceActiveSyncUpdate=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.imapAutoExpunge=true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.useSystemProxies=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.proxyUser=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.caldavEditNotifications=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.nosecuresmtp=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.caldavPastDelay=0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.keyPass=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log4j.logger.httpclient.wire=WARN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.noProxyFor=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.server=true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.popMarkReadOnRetr=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.nosecureimap=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.disableTrayActivitySwitch=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.caldavAutoSchedule=true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.enableProxy=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.proxyPort=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.logFileSize=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.mode=O365Manual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.smtpSaveInSent=true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.bindAddress=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.nosecurepop=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.pkcs11Library=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log4j.rootLogger=WARN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.keystoreFile=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log4j.logger.davmail=DEBUG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.clientKeystoreType=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.clientSoTimeout=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.pkcs11Config=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.clientKeystorePass=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.imapPort=1143&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.url=https:&#x2F;&#x2F;outlook.office365.com&#x2F;EWS&#x2F;Exchange.asmx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log4j.logger.org.apache.http.conn.ssl=WARN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.sentKeepDelay=0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.nosecureldap=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.imapAlwaysApproxMsgSize=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.nosecurecaldav=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.popPort=1110&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.defaultDomain=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.showStartupBanner=true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log4j.logger.httpclient=WARN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.proxyHost=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ldapPort=1389&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.server.certificate.hash=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log4j.logger.org.apache.http.wire=WARN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.disableGuiNotifications=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.imapIdleDelay=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.allowRemote=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.disableUpdateCheck=false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log4j.logger.org.apache.http=WARN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# FIXME: make sure the username is correct here; for me it was &amp;quot;uXXXXXXX@umail.utah.edu&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.oauth.USERNAME.refreshToken={AES}THIS IS WHERE THE SECRET KEY GOES!!!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.caldavPort=1080&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.enableKeepAlive=true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.ssl.clientKeystoreFile=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.logFilePath=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.carddavReadPhoto=true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.keepDelay=30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.oauth.redirectUri=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;davmail.caldavAlarmSound=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Try re-running your email sync, and see if it works!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuring-emacs-for-sending-mail&quot;&gt;Configuring Emacs for sending mail&lt;&#x2F;h2&gt;
&lt;p&gt;I use mu4e, but I think the &lt;code&gt;smtpmail-*&lt;&#x2F;code&gt; variables are also used by &lt;code&gt;gnus&lt;&#x2F;code&gt; and &lt;code&gt;notmuch&lt;&#x2F;code&gt; for sending mail—I could be wrong though, so if I am, someone please correct me. :)&lt;&#x2F;p&gt;
&lt;p&gt;I use the following in my mu4e &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.djcbsoftware.nl&#x2F;code&#x2F;mu&#x2F;mu4e&#x2F;Contexts.html&quot;&gt;work context&lt;&#x2F;a&gt;; adjust as needed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;make-mu4e-context&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Work&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt;match-func&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;when&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;string-prefix-p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&#x2F;Umail&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; (&lt;&#x2F;span&gt;&lt;span&gt;mu4e-message-field msg &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;maildir&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt;vars&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;user-mail-address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;ashton.wiersdorf@utah.edu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;user-full-name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Ashton Wiersdorf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;mu4e-compose-signature &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;SIGNATURE GOES HERE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;   ;;                               ↓ this is a neat function ↓&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;   ;; (message-send-mail-function . message-send-mail-with-mailclient)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;mu4e-get-mail-command &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;mbsync uni&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;mu4e-bookmarks &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                   ((:&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Inbox&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;maildir:&#x2F;Umail&#x2F;INBOX&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 105&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                    (:&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Flagged&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;g:f AND NOT flag:trashed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 102&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                    (:&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Unread messages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;flag:unread AND NOT flag:trashed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 117&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                    (:&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Today&amp;#39;s messages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;date:today..now&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 116&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                    (:&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Last 7 days&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;date:7d..now&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 119&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                    (:&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Messages with images&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;mime:image&#x2F;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;hide-unread t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 112&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                    (:&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Drafts&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;query&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;maildir:&#x2F;Umail&#x2F;Drafts&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot; :&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;message-send-mail-function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span&gt; smtpmail-send-it&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;smtpmail-smtp-server &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;localhost&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;smtpmail-smtp-user &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;XXXXXXXX@XXXXXXXXX.edu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;   ; base username email, not my nice first.last@utah.edu alias&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;smtpmail-stream-type &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt; plain&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;smtpmail-smtp-service &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1025&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;mu4e-drafts-folder &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&#x2F;Umail&#x2F;Drafts&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;mu4e-sent-folder &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&#x2F;Umail&#x2F;Sent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;mu4e-trash-folder &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&#x2F;Umail&#x2F;Trash&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span&gt;mu4e-refile-folder &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&#x2F;Umail&#x2F;Archive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I also had to add the following to my &lt;code&gt;~&#x2F;.authinfo.gpg&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;machine localhost port 1025 login XXXXXXXX@XXXXXXX.edu password XXXXXXXXX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that the URL is &lt;code&gt;localhost&lt;&#x2F;code&gt; —this is because we are using DavMail as a &lt;em&gt;proxy&lt;&#x2F;em&gt; for Outlook.&lt;&#x2F;p&gt;
&lt;p&gt;If you have not set up your authsources, might be a good time to do that to manage secrets with Emacs. I have this in my config:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;setq&lt;&#x2F;span&gt;&lt;span&gt; auth-sources &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;~&#x2F;.authinfo.gpg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;David Wilson has an &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=nZ_T7Q49B8Y&quot;&gt;awesome video on how to set up gpg&lt;&#x2F;a&gt; to manage passwords with Emacs. I’d check out all his videos because he covers some seriously great stuff in the Emacs and the Guix space.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, email with Outlook sucks—we wouldn’t have to do any of this crap if app passwords were a thing. But if there is no other way, then DavMail can bring a little sanity back to your email workflow.&lt;&#x2F;p&gt;
&lt;p&gt;+++
Update 2023-09-24 = “I used to have my affiliate link for Fastmail here. I’ve genuinely enjoyed their services and have received no financial compensation for the little recommendation I gave them here. However, I’ve decided to remove the affiliate link because I don’t think it’s appropriate for my blog.”&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Delimited Continuations</title>
        <published>2023-04-11T00:00:00+00:00</published>
        <updated>2023-04-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-04-11_delimited_continuations/"/>
        <id>https://beta.lambdaland.org/posts/2023-04-11_delimited_continuations/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-04-11_delimited_continuations/">&lt;p&gt;I’ve talked at some length about &lt;a href=&quot;&#x2F;posts&#x2F;2022-11-17_continuations&quot;&gt;continuations&lt;&#x2F;a&gt; and what they can do. In short, continuations let us manipulate the control flow programmatically. Among other things, it lets us implement generic non-deterministic backtracking search constructs, exception handlers, and cooperative threading—all without changes to the runtime or standard library!&lt;&#x2F;p&gt;
&lt;p&gt;If you need a refresher, see my &lt;a href=&quot;&#x2F;posts&#x2F;2022-11-17_continuations&quot;&gt;previous post on continuations&lt;&#x2F;a&gt;. The continuations that I talked about there were &lt;em&gt;unbounded&lt;&#x2F;em&gt; continuations, meaning that they captured the &lt;em&gt;entire&lt;&#x2F;em&gt; call stack. There’s another kind of continuation called a &lt;em&gt;delimited&lt;&#x2F;em&gt; continuation, which can do a superset of the things that an unbounded continuation can do.&lt;&#x2F;p&gt;
&lt;p&gt;To talk about continuations—delimited and regular—let’s look at a model of how a programming language get implemented. For that, we’ll talk about an abstraction of a language runtime with a thing called a CEK machine. Then we’ll realize the model with a simple implementation in Racket, and then we’ll talk about continuations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-cek-machine&quot;&gt;The CEK machine&lt;&#x2F;h2&gt;
&lt;p&gt;To understand continuations, it will be helpful to talk about an idealized machine: one that isn’t tied to any CPU architecture or memory constraints. Our machine is the CEK machine described by Felleisen et al. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:1-1&quot;&gt;&lt;a href=&quot;#fn-fn:1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The letters “CEK” stand for the three parts of the machine:&lt;&#x2F;p&gt;
&lt;dl&gt;
&lt;dt&gt;C: Control&lt;&#x2F;dt&gt;
&lt;dd&gt;The &lt;em&gt;control&lt;&#x2F;em&gt; state of the machine. This translates to the expression currently being evaluated.&lt;&#x2F;dd&gt;
&lt;dt&gt;E: Environment&lt;&#x2F;dt&gt;
&lt;dd&gt;An &lt;em&gt;environment&lt;&#x2F;em&gt; is a mapping of &lt;em&gt;variables&lt;&#x2F;em&gt; to &lt;em&gt;values&lt;&#x2F;em&gt;.&lt;&#x2F;dd&gt;
&lt;dt&gt;K: Kontinuation&lt;&#x2F;dt&gt;
&lt;dd&gt;A thing that answers, “once I’m done with this bit, what do I do next?” We’ll talk about this some more. Yeah, yeah, I know that’s not how you spell continuation, but the &lt;code&gt;C&lt;&#x2F;code&gt; was taken by “control”, so they went with &lt;code&gt;K&lt;&#x2F;code&gt; instead.&lt;&#x2F;dd&gt;
&lt;&#x2F;dl&gt;
&lt;p&gt;Often times you’ll see interpreters defined in what’s called “big-step” semantics. All that means is that the interpreter takes an expression and produces a result, often calling itself recursively. It might look something like this:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementing-a-cek-machine-in-racket&quot;&gt;Implementing a CEK machine in Racket&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;capturing-continuations&quot;&gt;Capturing continuations&lt;&#x2F;h2&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-fn:1&quot;&gt;
&lt;p&gt;Felleisen, Matthias, Robert Bruce Findler, and Matthew Flatt. Semantics Engineering with PLT Redex. Cambridge, Mass: MIT Press, 2009. &lt;a href=&quot;#fr-fn:1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Case for Picking a Non-Mainstream Programming Language</title>
        <published>2023-04-10T00:00:00+00:00</published>
        <updated>2023-04-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-04-10_case_for_esoteric_langs/"/>
        <id>https://beta.lambdaland.org/posts/2023-04-10_case_for_esoteric_langs/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-04-10_case_for_esoteric_langs/">&lt;p&gt;How many JavaScript developers are there? A lot. What are your odds that a given candidate is a good programmer? Not great.&lt;&#x2F;p&gt;
&lt;p&gt;Identifying with a single language is rather myopic, in my view. Languages evolve, new ones arise, and old ones get discarded. It’s true that you can make a killing as a COBOL developer—I had a professor once who said that he took a COBOL job and made a good amount of money from it. Thing is, as soon as that job was over, he took COBOL off his résumé.&lt;&#x2F;p&gt;
&lt;p&gt;I used to identify as a developer in a particular language. But hey, I’m still under 30 and I’ve moved away from that, so that’s good.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Praise for the pragmatic third camp</title>
        <published>2023-03-16T00:00:00+00:00</published>
        <updated>2023-03-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-03-16_appreciation_for_business_programmers/"/>
        <id>https://beta.lambdaland.org/posts/2023-03-16_appreciation_for_business_programmers/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-03-16_appreciation_for_business_programmers/">&lt;p&gt;Some years ago I came across &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;josephg.com&#x2F;blog&#x2F;3-tribes&#x2F;&quot;&gt;a blog post&lt;&#x2F;a&gt; that described programmers as being in one of three camps. It’s a fun, short post, so I encourage you to go read that real quick, but the gist of it is that programmers generally fall into one of three categories according to what they primarily value:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Applied mathematicians, who appreciate elegant solutions to problems. Program execution on von Neumann machines is incidental. These programmers like high-level languages and mathematically correct reasoning about programs.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Bit hackers, who like making the machine run as efficiently as possible. Without a von Neumann machine, programs are pointless. These programmers like low-level languages that let them get into the guts of things.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Product makers, who care about the ideals of the first and second camps in as much as they help them accomplish the task of delivering more features. Most industry programmers probably fall into this category. They like high-level languages as long as performance doesn’t suffer too much and that it’s pragmatic. (E.g. JavaScript, Ruby, Python, Go, etc.)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The author of the post talks a little bit about the tension between the camps. I won’t reproduce it here, but it can be amusing, so you should give it a read.&lt;&#x2F;p&gt;
&lt;p&gt;I’ll go ahead and add one more camp to the list: the code monkey for whom coding is just a job. They care about the quality of their work in as much as it allows them to hit their deadlines and collect a paycheck. They don’t care too much about what language they use, as long as it’s the one they learned in school or their bootcamp. They’re generally not curious about learning new languages, understanding how things are implemented, or making a good UI.&lt;&#x2F;p&gt;
&lt;p&gt;Most people I’ve worked with have fallen into the first three camps, fortunately. I’ve encountered a few who fall into the fourth camp I just outlined, and they’re miserable to work with if you care about anything. When you work with someone from camps 1–3, there’s some passion there to channel to make a better program, for whatever your metric of “better” is—and you can usually come to some consensus so that a program is better on multiple axes. But with the fourth, there’s nothing there to push on.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve found it to be a helpful paradigm: whenever I have a disagreement about someone about what constitutes &lt;em&gt;good&lt;&#x2F;em&gt; or &lt;em&gt;valuable&lt;&#x2F;em&gt; programming, I consider what kinds of things they value. (In a way, it’s a little like Jonathan Haidt’s &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Moral_foundations_theory&quot;&gt;Moral Foundations Theory&lt;&#x2F;a&gt; for programmers.) Maybe you can think back to some disagreement you had and see the value mismatch manifesting.&lt;&#x2F;p&gt;
&lt;p&gt;The other day I experienced a burst of appreciation for camp 3—the pragmatic makers—more so than I had ever felt before. I was fighting with a crappy health insurance website. Instead of a &lt;code&gt;&amp;lt;select&amp;gt;&lt;&#x2F;code&gt; dropdown element, they had built a &lt;code&gt;&amp;lt;div&amp;gt;&lt;&#x2F;code&gt; with some &lt;code&gt;on-click&lt;&#x2F;code&gt; handler to make a faux dropdown. The website was janky, bloated, slow, and difficult to navigate. It must have been made by programmers in camp 4.&lt;&#x2F;p&gt;
&lt;p&gt;I realized that the only camp that stands a chance of fighting this kind of crappy experience online is those programmers in camp 3: the soldiers who care about their craft enough to make the user happy. I realized that &lt;em&gt;I&lt;&#x2F;em&gt; would never ever want to build a better insurance site because &lt;em&gt;that’s not an interesting problem to me&lt;&#x2F;em&gt;, but there are those who have different motivations than I do, and these people can channel those motivations into hammering out better experiences for all of us.&lt;&#x2F;p&gt;
&lt;p&gt;So, here’s to the pragmatists—the people who care about the end and not so much the means. I’m going to stay in my camp working on more elegant tools for you to use. It’s nice that there’s some symbiosis between the three groups. We should all recognize that we need each other.&lt;&#x2F;p&gt;
&lt;p&gt;Except for camp 4. You’re the reason why we have crappy insurance portals.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Metric Worship, or: How a bad manager wrecked a (small) company</title>
        <published>2023-02-21T00:00:00+00:00</published>
        <updated>2023-02-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-02-21_metric_worship/"/>
        <id>https://beta.lambdaland.org/posts/2023-02-21_metric_worship/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-02-21_metric_worship/">&lt;p&gt;I once worked as a part of a company with four employees, all of us programmers. We formed a sort of daughter company with a bigger—though still modest-sized—company that handled our payroll and whatnot. Our work directly helped the parent company, but we were organizationally independent development-wise. I really liked working with that small team: we had a one-hour meeting each week to plan out our work, and a short, casual stand-up each morning to get things rolling. Almost all my time was spent building features and squishing bugs. I got a lot of really good feedback on all my pull-requests, as everyone there really cared about making a good-quality product.&lt;&#x2F;p&gt;
&lt;p&gt;Then we got acquired by a big, old, ossified company.&lt;&#x2F;p&gt;
&lt;p&gt;We got a new manager. Corporate dictated that all teams follow a two-week sprint, orchestrated through JIRA, and that every minute of our work be tracked. We now had three or four “SCRUM ceremonies” a week, each of which lasted between one to three hours. Our new manager had a baroque system to track our velocity and carefully calculated how many story points our team could complete a week.&lt;&#x2F;p&gt;
&lt;p&gt;My team’s interactions with our manager could be summarized in this meme:&lt;&#x2F;p&gt;
&lt;div class=&quot;figure&quot;&gt;
  &lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;jira_scrum_crap.jpeg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;

  
  &lt;div class=&quot;figure-caption&quot;&gt;
    &lt;span class=&quot;figure-caption-text&quot;&gt;&lt;p&gt;Metric-worshiping SCRUM manager encounters a programmer who cares&lt;&#x2F;p&gt;
&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Maybe I was (or am) a bit naïve, but it was such a deep shock for me to be forced to work at the cadence of someone who cared more about metrics than about the quality of the actual product. There were some funny moments we had with our new manager and company:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Managers got worried about what the programmers would do in a three-hour window between the end of one sprint and the start of another. Clearly, work may only happen during a sprint!&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The new company bragged about having gotten their 4-week-long release cycle down to the blazing speed of only 2-weeks. Someone from my company asked, “but we do CI&#x2F;CD and deploy multiple times a day!” Management didn’t know how to work with such a tight release cycle. This was a SaaS product, mind you, so daily deployments was an easy way to squish bugs quickly.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I was working part-time, and over 50% of my work hours were now spent in meetings determining how the rest would go.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I had to clock every minute I spent on a ticket, and my manager got visibly frustrated when I forgot, because now his spreadsheet would be broken.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I once forgot to move a ticket into the “done” column, and my manager got visibly flustered. I guess I had wrecked his precious little metrics.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;My manager frequently bragged about having worked all weekend. What was this guy even doing? He’s a middle manager! Tweaking spread sheets and “grooming the backlog”, I guess.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Anyway, the profound amount of crap I and my team had to put up with (combined with other passive-aggressive hostility from HR and other parts of management) sent my &lt;em&gt;entire&lt;&#x2F;em&gt; team packing within a matter of weeks. I don’t know who they found to maintain that code base. I’m not sure if &lt;em&gt;anyone&lt;&#x2F;em&gt; is maintaining it now. I feel sorry for the customers who liked our product. Management didn’t care about the product. All they cared about were their stupid little metrics.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-did-this-happen&quot;&gt;How did this happen?&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Law_of_the_instrument&quot;&gt;Maslow’s Hammer&lt;&#x2F;a&gt; suggests one reason why this happens:&lt;&#x2F;p&gt;
&lt;div class=&quot;epigraph&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;If all you have is a hammer, everything looks like a nail.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Management at this company had a huge hammer in the form of an overly-complicated JIRA setup. Every problem could be broken apart into little atomic pieces of work, scheduled into sprints, and orchestrated from afar.&lt;&#x2F;p&gt;
&lt;p&gt;There’s also &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Goodhart%27s_law&quot;&gt;Goodhart’s Law&lt;&#x2F;a&gt;, which states:&lt;&#x2F;p&gt;
&lt;div class=&quot;epigraph&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;Any observed statistical regularity will tend to collapse once pressure is placed upon it for control purposes.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;When management fixates so much on metrics and ties rewards, praise, and incentives to hitting metrics rather than shipping good things, stuff will go downhill quickly. In our case, it drove out the people who cared. In other cases, mediocrity sets in.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;monetary-metrics-are-often-a-bad-proxy-for-quality&quot;&gt;Monetary metrics are often a bad proxy for quality&lt;&#x2F;h2&gt;
&lt;p&gt;It is an incredible privilege to work on something that you care about with people that also care about it. There’s a big difference between people who care about the &lt;em&gt;quality&lt;&#x2F;em&gt; of something and the people who only know what the monetary value of things are. This isn’t to say that business needs and financial questions are always bad to ask: at one job, many of my bright ideas (so I thought) got shelved because there simply wasn’t enough time and&#x2F;or programmers to get the thing done, and we were working really hard to give people what they wanted.&lt;&#x2F;p&gt;
&lt;p&gt;Now that I write that, the decision-makers in those instances were still completely different than that bad manager I had at the last company: the managers at the new company cared about the experiences that our users were having with our product and wanted to make that a high-quality experience. Their questions had a much better motivation than the bean-counting metric-chasing origins of the bad manager’s decisions.&lt;&#x2F;p&gt;
&lt;p&gt;Money can sometimes be an indicator for quality, but not always. Money just points you to what people are willing to pay for. Quality is multi-faceted and there can be many (sometimes competing) approaches to getting at quality. Maybe some of the complexity is why it’s tempting to move away from hard to quantify questions about quality and towards metrics that can be put on a linear scale and compared.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-two-companies&quot;&gt;The two companies&lt;&#x2F;h2&gt;
&lt;p&gt;I wrote a little bit about &lt;a href=&quot;&#x2F;posts&#x2F;2022-08-28_keep_email_federated&#x2F;#headline-2&quot;&gt;the differences between staff and line&lt;&#x2F;a&gt; workers. I’ve been a line worker my whole life, and so I get frustrated when staff gets in my way to (in my view) the detriment of the end of the institution. There’s probably some needs of the staff that I don’t fully appreciate—I bet a lot of people are just trying to perfect the institution as a thing in itself, which could be a good and needed thing.&lt;&#x2F;p&gt;
&lt;p&gt;As I write this, I realize that I, a tool-lover, sometimes focus on making tools better &lt;em&gt;an und für sich&lt;&#x2F;em&gt;. It’s probably good that I’m in academia where researching and making better tools (e.g. better programming languages) is my objective, rather than trying to make a product to sell. Not that I’m &lt;em&gt;bad&lt;&#x2F;em&gt; at the latter—I shipped some pretty sweet stuff—it’s just that my decision making might be a little skewed at times. I’ll try and work on that.&lt;&#x2F;p&gt;
&lt;p&gt;In any case, focusing in metrics rather than the real quality of your product is bound to frustrate people who care. If you believe that JIRA and better metrics will be the key to making a better product, don’t: metrics have their place, but they can quickly get in the way.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What is a type system, really?</title>
        <published>2023-01-23T00:00:00+00:00</published>
        <updated>2023-01-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2023-01-17_what_is_a_type_system_really/"/>
        <id>https://beta.lambdaland.org/posts/2023-01-17_what_is_a_type_system_really/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2023-01-17_what_is_a_type_system_really/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;&#x2F;h2&gt;
&lt;p&gt;This is a question I’ve been wrestling with for a little bit. My first experience with a type system was with Java, and I didn’t like it. It just felt like an annoying constraint on the kinds of programs I could write. I was coming from Perl, which sports weak dynamic typing, so Java’s rigidity came as a bit of a shock.&lt;&#x2F;p&gt;
&lt;p&gt;After Java I learned some C, which too has types. C’s types are different from Java’s in a big way: in C they’re really just directives to the compiler on how to interpret some bytes. “Everything is just &lt;code&gt;void *&lt;&#x2F;code&gt;” is kind of true. In C, bytes can be interpreted however you wish.&lt;&#x2F;p&gt;
&lt;p&gt;As I matured as a developer, I realized that sometimes I &lt;em&gt;wanted&lt;&#x2F;em&gt; constraints on what I could program. I wanted to have some way to narrow the scope of possibilities of things my program could do. While that may sound bad at first glance, consider if you could narrow the scope of ways your program would go &lt;em&gt;wrong&lt;&#x2F;em&gt;. That’s what types are designed to do.&lt;&#x2F;p&gt;
&lt;p&gt;Not all type systems are equally powerful: while Java’s type system prevents certain classes of errors, a &lt;code&gt;NullPointerException&lt;&#x2F;code&gt; crops up here and there to blow your (well-typed!) program out of the water. Languages like Rust or Kotlin sport type systems that prevent &lt;code&gt;NullPointerExceptions&lt;&#x2F;code&gt; or segfaults from ever cropping up. The trade-off is that these type systems often take a little more time to get used to, and might make it harder to write certain kinds of programs.&lt;&#x2F;p&gt;
&lt;p&gt;New advances in type systems are mitigating those trade-offs, however. Kotlin’s type system does away with &lt;code&gt;NullPointerExceptions&lt;&#x2F;code&gt; without being too much more complex than Java’s, and things like &lt;em&gt;gradual typing&lt;&#x2F;em&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:1-1&quot;&gt;&lt;a href=&quot;#fn-fn:1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; make the cost curve of adding static types to a dynamically typed codebase much smoother. The more I learn, the more I see that I can do with types.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-a-type-system&quot;&gt;What is a type system?&lt;&#x2F;h2&gt;
&lt;p&gt;In one sense types are just sets of values that an expression can take on. Suppose I have a variable of type &lt;code&gt;Int&lt;&#x2F;code&gt;: this implies the values it will be bound to belong to the set ℤ. This view of types is really good for thinking about how algebraic types work: when I take the &lt;em&gt;product&lt;&#x2F;em&gt; of two types (e.g. &lt;code&gt;Int × Bool&lt;&#x2F;code&gt;), I’m describing values that belong to the set of ordered pairs &lt;code&gt;{(n,b) | n ∈ ℤ, b ∈ 𝔹}&lt;&#x2F;code&gt; or the &lt;em&gt;cross-product&lt;&#x2F;em&gt; of the sets &lt;code&gt;ℤ × 𝔹&lt;&#x2F;code&gt;. Tuples and structs are usually how product types are realized in a programming language.&lt;&#x2F;p&gt;
&lt;p&gt;The same goes for sum types and set unions. A &lt;em&gt;sum type&lt;&#x2F;em&gt; is the union of two or more types; if I have a variable of type &lt;code&gt;Nat + Bool&lt;&#x2F;code&gt;, then it can be a number &lt;em&gt;or&lt;&#x2F;em&gt; a boolean. Tagged unions and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Enumerated_type&quot;&gt;enums&lt;&#x2F;a&gt; are typically how you see sum types in programming languages.&lt;&#x2F;p&gt;
&lt;p&gt;If you consider the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cardinality&quot;&gt;cardinality&lt;&#x2F;a&gt; of a type, the metaphor continues to work.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:2-1&quot;&gt;&lt;a href=&quot;#fn-fn:2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; For example, if I have a type called a &lt;code&gt;Byte&lt;&#x2F;code&gt; that holds an integer between 0 and 255, and I pair it with a boolean in a tuple to produce the type &lt;code&gt;Byte × Bool&lt;&#x2F;code&gt;, then there will be 256 × 2 = 512 different values that inhabit the type &lt;code&gt;Byte × Bool&lt;&#x2F;code&gt;. Likewise with a sum type, where a value can be either &lt;code&gt;Byte&lt;&#x2F;code&gt; or &lt;code&gt;Bool&lt;&#x2F;code&gt;, then there are 256 + 2 = 258 different inhabitants of the type.&lt;&#x2F;p&gt;
&lt;p&gt;Every type system that I know of has some set of &lt;em&gt;primitive types&lt;&#x2F;em&gt; along with ways of combining those types into bigger structures. Primitive types typically include numbers, booleans, and strings, while combining structures usually include records (or structs, i.e. product types) and enumerations (i.e. sum types).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;static-typing-dynamic-typing-and-type-inference&quot;&gt;Static typing, dynamic typing, and type inference&lt;&#x2F;h3&gt;
&lt;p&gt;Languages with a &lt;em&gt;static type system&lt;&#x2F;em&gt; are ones where the type of an expression—be it a variable, literal, compound expression, function call, etc.—is discernible without running the program. Haskell, Rust, Java, C, C++, Go, etc. are all statically typed languages.&lt;&#x2F;p&gt;
&lt;p&gt;In contrast, in a &lt;em&gt;dynamic type system&lt;&#x2F;em&gt;, the types of expressions are not knowable until runtime. The language implementation has to insert checks before e.g. performing an addition to make sure the types line up right. Perl, Python, Ruby, JavaScript, Scheme, Clojure, etc. are dynamically typed languages.&lt;&#x2F;p&gt;
&lt;p&gt;Some static languages like Java require you to write down the type of every variable, expression, and function. Others, like Rust and Haskell, do something called &lt;em&gt;type inference&lt;&#x2F;em&gt;: this is where the type checker is able to infer, based off of the types of literal data as well as the operators in use, what the types for a program should be. This is different than a dynamic type system: just because you didn’t write down what type a variable was, doesn’t mean it is now dynamically typed. In Rust, Haskell, etc., every expression still has a type—it’s just inferred rather than explicitly given by you, the programmer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nominal-vs-dot-structural&quot;&gt;Nominal vs. Structural&lt;&#x2F;h3&gt;
&lt;p&gt;Some types are &lt;em&gt;nominal&lt;&#x2F;em&gt; and others are &lt;em&gt;structural&lt;&#x2F;em&gt;. These notions describe how two types are considered equal. Nominal types are what you get all over in Java: for two objects to be of the same type, they must both be of the same class. It doesn’t matter if you have two classes like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span&gt; thing_1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  boolean&lt;&#x2F;span&gt;&lt;span&gt; thing_2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Bar&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span&gt; thing_1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  boolean&lt;&#x2F;span&gt;&lt;span&gt; thing_2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Even though the members of &lt;code&gt;Foo&lt;&#x2F;code&gt; and &lt;code&gt;Bar&lt;&#x2F;code&gt; have the same interface and even the same names, a value of type &lt;code&gt;Foo&lt;&#x2F;code&gt; will never be the same as type &lt;code&gt;Bar&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Structural types determine equivalence based off of their algebraic structure. Most types in Haskell, ML, Typed Racket, and others work this way. This is kind of like a generalization of interfaces: if two types “implement” the “same interface” of having the same structure, they can be considered equivalent and interchangeable. However, some types in Typed Racket, like those based off of structures, are nominal—you don’t have to be all structural or all nominal in your language.&lt;&#x2F;p&gt;
&lt;p&gt;Most of the time I find it easier to think in terms of structural types. There are times when nominal types make more sense, though. It’s nice when your language gives you the flexibility to choose.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-do-we-care-about-type-systems&quot;&gt;Why do we care about type systems?&lt;&#x2F;h2&gt;
&lt;p&gt;I think most computer scientists are familiar with &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Halting_problem&quot;&gt;the Halting Problem&lt;&#x2F;a&gt;, but &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rice%27s_theorem&quot;&gt;Rice’s Theorem&lt;&#x2F;a&gt; is &lt;em&gt;slightly&lt;&#x2F;em&gt; less well-known.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:3-1&quot;&gt;&lt;a href=&quot;#fn-fn:3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Rice’s theorem states:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;All non-trivial semantic properties of programs are undecidable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rice%27s_theorem&quot;&gt;Wikipedia&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;What is a semantic property? In contrast with a &lt;em&gt;syntactic property&lt;&#x2F;em&gt;, which is aspect apparent in the text of the program, a &lt;em&gt;semantic property&lt;&#x2F;em&gt; deals with what happens when the program runs. For example, “does this program halt?” is a semantic property, and the same semantic property covered by Turing’s Halting Problem. “Does this program contain any &lt;code&gt;if&lt;&#x2F;code&gt; statements?” is a syntactic property. “Does control reach this point in the program?” or “What values flow here?” are both semantic questions.&lt;&#x2F;p&gt;
&lt;p&gt;Type systems can turn certain semantic properties into syntactic ones: we can turn questions about the program’s runtime behavior (e.g. “Does a function taking integers get applied to a boolean causing a type error?”) into questions we can answer by examining the syntax of our program—if we have a statically typed language, we can tell—without running the program itself—whether or not no type errors ever occur.&lt;&#x2F;p&gt;
&lt;p&gt;There will still be programs when it’s impossible to decide whether or not the program has a type error:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;goldbach-conjecture-true?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;      &amp;quot;not a number&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;      42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;but in these cases we can restrict ourselves to programs that &lt;em&gt;definitely&lt;&#x2F;em&gt; do not have any type errors.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;beyond-sets-types-as-a-meta-language&quot;&gt;Beyond sets: types as a meta language&lt;&#x2F;h2&gt;
&lt;p&gt;Something I’ve learned recently is that “type system” is just what we call meta-languages for our programming languages. The language of types describes the behavior of a program written in another language.&lt;&#x2F;p&gt;
&lt;p&gt;Consider the following program in Typed Racket:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; add1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Number Number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add1&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The annotation &lt;code&gt;(: add1 (-&amp;gt; Number Number))&lt;&#x2F;code&gt; is a proposition that &lt;code&gt;add1&lt;&#x2F;code&gt; is a function that takes some value belonging to the set ℕ and gives back another thing in the set ℕ.&lt;&#x2F;p&gt;
&lt;p&gt;Now if we call that function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;seven : Number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add1&lt;&#x2F;span&gt;&lt;span&gt; seven&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;the &lt;code&gt;: Number&lt;&#x2F;code&gt; bit on the first line is a proposition that the variable &lt;code&gt;seven&lt;&#x2F;code&gt; will take on a value in the set ℕ.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:4-1&quot;&gt;&lt;a href=&quot;#fn-fn:4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now, in the meta-language of types, we can check that the type of the argument &lt;code&gt;seven&lt;&#x2F;code&gt; matches with the type of the parameter &lt;code&gt;n&lt;&#x2F;code&gt; in &lt;code&gt;add1&lt;&#x2F;code&gt;. In this case, the types match, so we proceed. If the declared or inferred type of the argument did &lt;em&gt;not&lt;&#x2F;em&gt; line up, our type checker would complain that we had violated the rules of the meta-language. These rules in the meta-language, of course, correspond to the actual runtime properties of Racket. More on that later in &lt;a href=&quot;https:&#x2F;&#x2F;beta.lambdaland.org&#x2F;posts&#x2F;2023-01-17_what_is_a_type_system_really&#x2F;#erasure&quot;&gt;§ Erasure&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;types-other-than-values&quot;&gt;Types other than values&lt;&#x2F;h3&gt;
&lt;p&gt;Many object-oriented (OO) languages have a notion of &lt;code&gt;public&lt;&#x2F;code&gt; and &lt;code&gt;private&lt;&#x2F;code&gt; variables. Visibility is another thing type systems enforce. Annotating a variable as being &lt;code&gt;private&lt;&#x2F;code&gt; is a proposition that it is only accessed in certain parts of the program, which is something the type checker can then ensure is enforced.&lt;&#x2F;p&gt;
&lt;p&gt;Tainting is another thing you might want from a type system: &lt;em&gt;tainting&lt;&#x2F;em&gt; refers to marking user-supplied data as “tainted”, and any attempt to e.g. modify this data or branch off of the value is prohibited, unless the data has been “sanitized” by e.g. explicitly parsing well-formed data with regular expressions or the like. This is supposed to help protect against injection attacks.&lt;&#x2F;p&gt;
&lt;p&gt;A type system could have a wrapper type &lt;code&gt;Tainted&amp;lt;A&amp;gt;&lt;&#x2F;code&gt; that takes some data of any type and protects it from dangerous operations. Then you’d have functions like &lt;code&gt;regex_sanitize :: Tainted&amp;lt;String&amp;gt;, Regex → String&lt;&#x2F;code&gt; for when you want to parse a tainted string to get some data out of it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;erasure&quot;&gt;Erasure&lt;&#x2F;h2&gt;
&lt;p&gt;There is usually some kind of check to make sure that the propositions in the meta-language correspond to the program we’re describing. Without this check, there wouldn’t be anything stopping me from writing:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;racket&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ([&lt;&#x2F;span&gt;&lt;span&gt;seven : Number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; &amp;quot;definitely not a number!&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add1&lt;&#x2F;span&gt;&lt;span&gt; seven&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and the program would still type check if it just blindly trusted the type annotations. Of course, as soon as the program &lt;em&gt;runs&lt;&#x2F;em&gt;, the runtime would explode at the &lt;code&gt;add1&lt;&#x2F;code&gt; exception. Removing the types after checking is called “type erasure”, as the types are erased after type checking and the program gets run as if they had never been there.&lt;&#x2F;p&gt;
&lt;p&gt;Some languages like Haskell and Java do this. This is safe to do because we’re only running programs that we’ve proven are well-typed. The upside to this is that we can save a lot of overhead by removing type checks. The downside is that certain kinds of runtime introspection might not be possible. Java, for example, doesn’t keep type parameters around on generics. &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Generics_in_Java#Problems_with_type_erasure&quot;&gt;Wikipedia has a good example&lt;&#x2F;a&gt; of where &lt;code&gt;ArrayList&amp;lt;Integer&amp;gt;&lt;&#x2F;code&gt; and &lt;code&gt;ArrayList&amp;lt;Float&amp;gt;&lt;&#x2F;code&gt; both report the same thing under &lt;code&gt;.getClass()&lt;&#x2F;code&gt; at runtime.&lt;&#x2F;p&gt;
&lt;p&gt;One place to be careful is when typed and untyped code mix. This is where &lt;em&gt;gradual typing&lt;&#x2F;em&gt; comes in. Most languages are either statically typed or dynamically typed, but a growing number of languages are either being adapted to support or are being developed out of the box with support for gradual types. In these languages, like Typed Racket, you have to insert runtime checks to make sure code coming from an untyped module into a typed module agrees with the type guarantees.&lt;&#x2F;p&gt;
&lt;p&gt;There’s a lot of hidden complexity around gradual typing. &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cs.brown.edu&#x2F;people&#x2F;bgreenma&#x2F;publications&#x2F;publications.html&quot;&gt;Ben Greenman&lt;&#x2F;a&gt; has many papers outlining some of the intricacies around the semantics of gradual typing.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wat-can-go-wrong&quot;&gt;Wat can go wrong&lt;&#x2F;h3&gt;
&lt;p&gt;TypeScript is a bit of an odd language. The main page proclaims “TypeScript becomes JavaScript via the delete key” and just erases all types after type checking. You can call TypeScript modules from JavaScript, and TypeScript doesn’t put in any runtime checks. For example, you can do:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; add2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; : number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; b number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; : number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;bar&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and get the result:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foobar&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;TypeScript’s type guarantees are only locally sound. As soon as your typed and untyped parts mix, your program will fall back on the very &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.destroyallsoftware.com&#x2F;talks&#x2F;wat&quot;&gt;wat-worthy&lt;&#x2F;a&gt; typing rules of JavaScript.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-layers-mix&quot;&gt;When layers mix&lt;&#x2F;h2&gt;
&lt;p&gt;How much can you program in this meta language of types? I’m still trying to understand this. &lt;em&gt;Dependent types&lt;&#x2F;em&gt; allow types to depend on values; i.e. you can have a type for “list with three integers”. Dependent typing, as I understand it, opens up complete programmability of the type system, at the cost of type checking becoming undecidable. These type systems allow you describe the behavior of your programs with incredible precision.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve done a little work with &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Coq&quot;&gt;Coq&lt;&#x2F;a&gt;, which supports dependent types. I haven’t done enough yet to really understand it well though!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;types-as-a-design-tool&quot;&gt;Types as a design tool&lt;&#x2F;h2&gt;
&lt;p&gt;Beyond the neat safety properties that type systems give me, I really like using types as a design tool. So often I’ll be working on transforming some data or pulling together information from multiple different sources to decide something, and it’s easy to get lost in the lines of code. What helps is for me to think of a function in terms of the shape of its inputs and the shape of the needed output. (This is part of the reason why I like &lt;a href=&quot;https:&#x2F;&#x2F;beta.lambdaland.org&#x2F;posts&#x2F;2023-01-17_what_is_a_type_system_really&#x2F;#nominal-vs-dot-structural&quot;&gt;structural type systems&lt;&#x2F;a&gt; so much.) With the types in hand, the program almost writes itself.&lt;&#x2F;p&gt;
&lt;p&gt;Indeed, there are times when the program &lt;em&gt;can&lt;&#x2F;em&gt; write itself! If you write down the type of a function, it’s not hard for an editor to suggest programs that satisfy that type. With more expressive types, the better the suggestions will be. To see an example of this in action, check out &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~ashton314&#x2F;microKanren&quot;&gt;the type checker I made with μKanren&lt;&#x2F;a&gt;, which can accept a type and generate expressions that satisfy it.&lt;&#x2F;p&gt;
&lt;p&gt;One thing that I like about this kind of program generation is the programs will definitely be &lt;em&gt;correct&lt;&#x2F;em&gt;, in the sense they’ll be well-typed. ML systems like GitHub Copilot are very impressive, but there’s always some chance that they’ll go completely wrong. Type-driven code suggestions can always be safe!&lt;&#x2F;p&gt;
&lt;p&gt;Despite how cool type-driven code generation is, and how valuable the safety guarantees that types provide are, I find types to be of greatest aid as a tool for thinking and reasoning about my programs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;again-what-are-type-systems&quot;&gt;Again, what are type systems?&lt;&#x2F;h2&gt;
&lt;p&gt;Type systems provide a way of writing down properties of our programs that we would like to be true, and then mechanically checking that those properties hold. Type systems come in all shapes and sizes; some are more expressive than others. Types are also a great tool to use when actually writing code.&lt;&#x2F;p&gt;
&lt;p&gt;Static type systems provide strong guarantees about program behavior at the expense of some friction in programming: dynamic languages make it easy to throw together a prototype, but can become unwieldy or difficult to maintain once the codebase grows. Gradual typing is an increasingly popular method to get the best of both worlds.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;p&gt;I’d recommend checking out the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lambda_cube&quot;&gt;Lambda Cube&lt;&#x2F;a&gt;. Other books that I’ve read or am reading that have helped me understand types a bit better include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Practical Foundations for Programming Languages&lt;&#x2F;em&gt;, by Robert Harper&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Types and Programming Languages&lt;&#x2F;em&gt;, by Benjamin Pierce&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Semantics Engineering with PLT Redex&lt;&#x2F;em&gt;, by Matthias Felleisen, Robert Findler, and Matthew Flatt&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Programming Languages: Application and Interpretation&lt;&#x2F;em&gt;, by Shriram Krishnamurthi&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-fn:5-1&quot;&gt;&lt;a href=&quot;#fn-fn:5&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I’ve also written a post about &lt;a href=&quot;&#x2F;posts&#x2F;2022-07-27_how_to_write_a_type_checker&#x2F;&quot;&gt;how to write a type checker&lt;&#x2F;a&gt; that hopefully should be pretty easy to follow.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acknowledgments&quot;&gt;Acknowledgments&lt;&#x2F;h2&gt;
&lt;p&gt;Thanks to my advisor &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cs.brown.edu&#x2F;people&#x2F;bgreenma&#x2F;&quot;&gt;Ben Greenman&lt;&#x2F;a&gt; for reading a draft and correcting some inaccuracies in the erasure and gradual typing portions. Thanks also to &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;solitum.net&#x2F;&quot;&gt;Scott Wiersdorf&lt;&#x2F;a&gt; and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;alex0112&quot;&gt;Alex Larsen&lt;&#x2F;a&gt; for providing feedback and some much-needed polishing.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-fn:1&quot;&gt;
&lt;p&gt;Gradual typing was first proposed by Jeremy Siek. The &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gradual_typing&quot;&gt;Wikipedia page on Gradual Typing&lt;&#x2F;a&gt; has a decent introduction. &lt;a href=&quot;#fr-fn:1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-fn:2&quot;&gt;
&lt;p&gt;This should suggest the relationship between sums and products in types and algebra is a deep one! &lt;a href=&quot;#fr-fn:2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-fn:3&quot;&gt;
&lt;p&gt;Next time someone asks you to write a program that does some static analysis of a semantic property, you can say to them (in your best Vizzini voice of course), “you fell for one of the classic blunders! The first is never get involved in a Turing-machine halting problem. The second which is &lt;em&gt;slightly&lt;&#x2F;em&gt; less well-known, never attempt to use static analysis when semantics are on the line!”&lt;&#x2F;p&gt;
&lt;p&gt;At this point it’s generally appropriate to laugh manically before falling over dead from iocane poisoning. &lt;a href=&quot;#fr-fn:3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-fn:4&quot;&gt;
&lt;p&gt;Typed Racket would actually derive the type &lt;code&gt;Positive-Byte&lt;&#x2F;code&gt; for &lt;code&gt;seven&lt;&#x2F;code&gt; which is a subtype of Number. Typed Racket’s &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.racket-lang.org&#x2F;ts-reference&#x2F;type-ref.html#%28part._.Numeric_.Types%29&quot;&gt;numeric type hierarchy&lt;&#x2F;a&gt; is quite impressive! &lt;a href=&quot;#fr-fn:4-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-fn:5&quot;&gt;
&lt;p&gt;The book is available online here: &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.plai.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.plai.org&#x2F;&lt;&#x2F;a&gt; The sections on types and type checking are quite excellent. &lt;a href=&quot;#fr-fn:5-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Make an Emacs Buffer Open the Way You Want</title>
        <published>2022-12-27T00:00:00+00:00</published>
        <updated>2022-12-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-12-27_repl_buffer_on_the_right/"/>
        <id>https://beta.lambdaland.org/posts/2022-12-27_repl_buffer_on_the_right/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2022-12-27_repl_buffer_on_the_right/">&lt;p&gt;Are you tired of having a particular buffer pop open in the wrong direction? Do you wish, for example, that the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.racket-mode.com&#x2F;#Edit-buffers-and-REPL-buffers&quot;&gt;Racket REPL&lt;&#x2F;a&gt; buffer showed up on the right in a vertical split, rather than below in a horizontal one? Look no further. I give you, &lt;code&gt;display-buffer-alist&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add-to-list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;display-buffer-alist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             &amp;#39;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;\\*Racket REPL &amp;lt;&#x2F;&amp;gt;\\*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span&gt;display-buffer-in-direction&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span&gt;direction &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That little snippet will make sure when you hit &lt;code&gt;C-c C-k&lt;&#x2F;code&gt; inside of a &lt;code&gt;racket-mode&lt;&#x2F;code&gt; buffer, a REPL will pop up on the right-side instead of on the bottom. I find that much more comfortable to use.&lt;&#x2F;p&gt;
&lt;p&gt;The variable &lt;code&gt;display-buffer-alist&lt;&#x2F;code&gt; is a &lt;span class=&quot;underline&quot;&gt;fantastically&lt;&#x2F;span&gt; useful variable. There’s so much to it that I can’t write it up in a blog post. Fortunately, the indomitable Mickey Petersen has written up a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.masteringemacs.org&#x2F;article&#x2F;demystifying-emacs-window-manager&quot;&gt;fantastic article about how Emacs manages windows&lt;&#x2F;a&gt; which you should definitely check out. Here are just some of the settings that I use:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuration-for-dedicated-eshell-buffers&quot;&gt;Configuration for dedicated Eshell buffers&lt;&#x2F;h2&gt;
&lt;p&gt;If you don’t use &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.masteringemacs.org&#x2F;article&#x2F;complete-guide-mastering-eshell&quot;&gt;Eshell&lt;&#x2F;a&gt; already, it’s definitely worth a look. You might justly wonder, “why should I use something that’s inferior to &lt;code&gt;$TERMINAL_EMULATOR_OF_CHOICE&lt;&#x2F;code&gt;?” Good question. I still make heavy use of my terminal, but I &lt;em&gt;really&lt;&#x2F;em&gt; like how I can use completion frameworks like &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;vertico&quot;&gt;Vertico&lt;&#x2F;a&gt; or &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minad&#x2F;corfu&quot;&gt;Corfu&lt;&#x2F;a&gt; with &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;oantolin&#x2F;orderless&quot;&gt;Orderless&lt;&#x2F;a&gt; to search through history. If you’ve put a bunch of effort into configuring Emacs in those ways, it’s really nice to port that across.&lt;&#x2F;p&gt;
&lt;p&gt;I also used Eshell to great effect when I was debugging my implementation of Raft for a class. I had a ton of log messages getting dumped out to the screen, and on my terminal, the lines always wrap. Maybe there’s a setting to enable horizontal scrolling, but I couldn’t find it. With Eshell, that just comes right out of the box.&lt;&#x2F;p&gt;
&lt;p&gt;On top of getting long lines to play nice, I can also use the powerful search and filtering operations that I’m used to using to navigate my code to navigate through my terminal history.&lt;&#x2F;p&gt;
&lt;p&gt;There’s a lot more, but those features have intrigued me enough that I wanted to make it easy to pop open to Eshell whenever I could. Here’s what I use:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Don&amp;#39;t forget to bind these functions to convenient keys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defun&lt;&#x2F;span&gt;&lt;span&gt; startup-eshell&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Fire up an eshell buffer or open the previous one&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;interactive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;get-buffer-window&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*eshell*&amp;lt;42&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;delete-window&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;get-buffer-window&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*eshell*&amp;lt;42&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;eshell&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defun&lt;&#x2F;span&gt;&lt;span&gt; tab-to-eshell&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Open a tab with eshell. If that tab doesn&amp;#39;t exist, create it. If already in that tab, switch to previous tab.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;interactive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;tab-bar-tab-name-current&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*eshell*&amp;lt;43&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span&gt;tab-bar-switch-to-prev-tab&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;eshell&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add-to-list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;display-buffer-alist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             &amp;#39;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;\\*eshell\\*&amp;lt;43&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span&gt;display-buffer-in-tab&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span&gt;tab-name &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*eshell*&amp;lt;43&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add-to-list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;display-buffer-alist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             &amp;#39;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;\\*eshell\\*&amp;lt;42&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;display-buffer-in-side-window&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span&gt;side &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;window-width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0.5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;window-height&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span&gt; fit-window-to-buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I wanted to be able to open an Eshell buffer on the left side of the window whenever, and I also wanted to be able to make a dedicated tab that I could toggle between easily. With &lt;code&gt;startup-eshell&lt;&#x2F;code&gt; and &lt;code&gt;tab-to-eshell&lt;&#x2F;code&gt; respectively, I can do just that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;org-roam&quot;&gt;Org-Roam&lt;&#x2F;h2&gt;
&lt;p&gt;I like using &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.orgroam.com&quot;&gt;Org-roam&lt;&#x2F;a&gt; for note taking. I wanted to make the backlinks buffer always appear in a narrow-ish window on the right. Here’s all the config needed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;; Dedicated side window for backlinks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add-to-list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;display-buffer-alist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;             &amp;#39;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;\\*org-roam\\*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;display-buffer-in-side-window&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span&gt;side &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;window-width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 0.4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;window-height&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span&gt; fit-window-to-buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;things-to-note&quot;&gt;Things to note&lt;&#x2F;h2&gt;
&lt;p&gt;There’s a difference between &lt;code&gt;display-buffer-in-side-window&lt;&#x2F;code&gt; and &lt;code&gt;display-buffer-in-direction&lt;&#x2F;code&gt;: the first, if I’m not mistaken, makes a &lt;em&gt;dedicated window&lt;&#x2F;em&gt;, which you can read about on &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.masteringemacs.org&#x2F;article&#x2F;demystifying-emacs-window-manager&quot;&gt;Mickey Petersen’s site&lt;&#x2F;a&gt;. The short of it is, that buffer will stay in that space and will not move, even if you’re used to your windows automatically re-laying out with e.g. &lt;code&gt;evil-mode&lt;&#x2F;code&gt; enabled.&lt;&#x2F;p&gt;
&lt;p&gt;The second is a little gentler, at least in my mind. It asks Emacs to open the buffer in one direction rather than another, and it’s just as if you had done &lt;code&gt;C-x 2&lt;&#x2F;code&gt; or &lt;code&gt;C-x 3&lt;&#x2F;code&gt; for up&#x2F;down or left&#x2F;right respectively.&lt;&#x2F;p&gt;
&lt;p&gt;Yet again, this is another testament to the fantastic power and flexibility of Emacs. This isn’t a &lt;em&gt;life-changing&lt;&#x2F;em&gt; configuration &lt;em&gt;per se&lt;&#x2F;em&gt;, but it definitely makes Emacs more comfortable to use for me.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Christmas</title>
        <published>2022-12-25T00:00:00+00:00</published>
        <updated>2022-12-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/personal/2022-12-25-christmas/"/>
        <id>https://beta.lambdaland.org/posts/personal/2022-12-25-christmas/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/personal/2022-12-25-christmas/">&lt;p&gt;This year I discovered the profound joy of giving toys to a little girl. Our daughter is beginning to babble and walk, and nothing has brought me more happiness than playing with her and watching her grow in her capabilities. She’s still young enough that she has no clue as to what is going on, but she did like getting some new toys wrapped in paper and bows! Christmas is so much better giving presents to your kids than it is getting presents as a kid.&lt;&#x2F;p&gt;
&lt;p&gt;I am grateful for good health. My family got COVID earlier this year, and what a miserable time that was. Our little girl has been sick off and on, as happens with little kids. But by and large we’ve been unimpeded from doing things that bring us joy.&lt;&#x2F;p&gt;
&lt;p&gt;I started my PhD! It was difficult for me to leave Spiff: I enjoyed working there, the work was interesting, and I have never worked on a team that cared so much about programming as a craft. It was the perfect job for me. Starting a PhD has been challenging—I discovered a deep mismatch between my interests and the interests of my advisor and I decided that I needed to switch advisors or try and get back into industry. Fortunately I’ll be working with someone whose interests are much better aligned—but more on that later.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org646cf37&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;books&quot;&gt;Books&lt;&#x2F;h1&gt;
&lt;p&gt;I’ve started a small host of books. I think the only books that I finished were &lt;em&gt;How to Write a Lot&lt;&#x2F;em&gt; by Silvia and &lt;em&gt;The Lost Metal&lt;&#x2F;em&gt; by Sanderson. Some other books that I’m in the process of reading are: (in no particular order)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Bernoulli’s Fallacy&lt;&#x2F;em&gt;, Clayton&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The Closing of the American Mind&lt;&#x2F;em&gt;, Bloom&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The Constitution of Knowledge&lt;&#x2F;em&gt;, Rauch&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Range&lt;&#x2F;em&gt;, Epstein&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And technical books:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Semantics Engineering with PLT Redex&lt;&#x2F;em&gt;, Felleisen, Findler, and Flatt&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Compiling with Continuations&lt;&#x2F;em&gt;, Abel&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Essentials of Programming Languages&lt;&#x2F;em&gt;, Friedman and Wand&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Practical Foundations for Programming Languages&lt;&#x2F;em&gt;, Harper&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are some others, but that’s what I’ve got running around in my head right now.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org3488dcb&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;peace&quot;&gt;Peace&lt;&#x2F;h1&gt;
&lt;p&gt;I have never been so grateful for peace in my country. Watching the war in Ukraine unfold has reminded me of how much I have to be thankful for. I’ve tried to give a little extra in charity this year to help. I’d encourage you to do the same. It doesn’t feel to me that this comes up very often: there’s one clear bad and one clear good in this fight. Sure, individuals and groups will be doing bad things on both sides, but there’s nothing defensible about an invasion that regularly launches missiles against hospitals and children’s schools.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;But whoso shall offend one of these little ones… it were better for him that a millstone were hanged about his neck, and that he were drowned in the depth of the sea.&lt;&#x2F;p&gt;
&lt;p&gt;Matt. 18:6&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I am grateful my little girl is far away from war.&lt;&#x2F;p&gt;
&lt;p&gt;I pray, and I hope, that I can do a little bit to temper hate and anger. I worry about a lot of things that seem small but, I feel, lead to the kind of collapse of dignified civilization that we see in increasingly authoritarian regimes. Technology is not going to save society—we need more people who are conscientious, moderate, kind, and forgiving.&lt;&#x2F;p&gt;
&lt;p&gt;I am grateful for peace in my family. There are differences between myself and members of my family and my in-laws—some pretty deep ones too—but everyone put those differences aside for Christmas and we celebrated in a way that just felt happy and &lt;em&gt;good&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There’s a lot I have to be thankful for. Peace in various parts of my life is something I’m cherishing more than normal this year. May we all be generous peacemakers. I’m still working on it, but it’s worthwhile to keep trying. Be the slack and the flex in the system: absorb jostles and bumps, unjust as they are. We need worry more about what we can give in our relationships and less about what we might think we are owed. There’s a balance there: we shouldn’t allow ourselves to be abused—but trying to be a little kinder never hurts.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What I Like in a Font for Code</title>
        <published>2022-12-05T00:00:00+00:00</published>
        <updated>2022-12-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-12-05_what_I_like_in_a_coding_font/"/>
        <id>https://beta.lambdaland.org/posts/2022-12-05_what_I_like_in_a_coding_font/</id>
        
        <summary type="html">&lt;p&gt;I’m well aware that I may have a bit of an &lt;a href=&quot;&#x2F;posts&#x2F;2022-08-01_a_new_font&#x2F;&quot;&gt;obsession with fonts&lt;&#x2F;a&gt;. I don’t think that’s too unusual for someone who works in tech, however. Sites like &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.programmingfonts.org&#x2F;&quot;&gt;Programming Fonts&lt;&#x2F;a&gt; exist to let people test drive and compare a bunch of different fonts. Just for fun, I thought I’d write up some of the features I look for in a programming font that I’ve come to deliberately pick out.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Never surrender your password</title>
        <published>2022-11-22T00:00:00+00:00</published>
        <updated>2022-11-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-11-22_never_surrender/"/>
        <id>https://beta.lambdaland.org/posts/2022-11-22_never_surrender/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2022-11-22_never_surrender/">&lt;p&gt;In &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2211.05824.pdf&quot;&gt;a study&lt;&#x2F;a&gt; that &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arstechnica.com&#x2F;information-technology&#x2F;2022&#x2F;11&#x2F;half-of-computer-repairs-result-in-snooping-of-sensitive-data-study-finds&#x2F;&quot;&gt;Ars Technica reported on&lt;&#x2F;a&gt;, researchers found that an alarming number of computer repair technicians snooped through clients’ devices—and female clients were &lt;em&gt;way&lt;&#x2F;em&gt; more likely to have their data accessed. Yikes!&lt;&#x2F;p&gt;
&lt;p&gt;I once had to take my laptop to get some repairs done. The &lt;code&gt;TAB&lt;&#x2F;code&gt; key on my 2016 MacBook Pro had started glitching, and that wasn’t going to fly when I was working on code and needed my tab completions and app switching to be seamless. I took my laptop to the Apple-authorized repair service at my school. The surly technician confirmed my warranty and asked me to fill out an intake form for my computer.&lt;&#x2F;p&gt;
&lt;p&gt;One of the fields on that form was for the root password to my computer. I noted that this form wasn’t going to be encrypted, and so I declined to give the password to decrypt my hard drive. (To be honest, even if I could have somehow verified that the form &lt;em&gt;were&lt;&#x2F;em&gt; going to be stored securely, I wouldn’t have given up the password.) The technician got a little huffy and said that they needed to be able to run diagnostics to make sure everything was done correctly, etc. This was hard to believe, since it was a hardware problem that could be handled without any software intervention. I refused again; I told them (and wrote in the notes field of the form for any other support technicians) that I worked nearby and could come enter my password if needed within two minutes of getting a call.&lt;&#x2F;p&gt;
&lt;p&gt;The technician didn’t like that, but I was insistent. Eventually they relented. I didn’t have to give up my password and the repairs were completed without any problems. I was  never called to input my password. I doubt something nefarious would have happened at &lt;em&gt;that&lt;&#x2F;em&gt; campus repair shop, but you never know.&lt;&#x2F;p&gt;
&lt;p&gt;There’s too much on your hard drive that cannot leak: information about your bank, access to your email, saved passwords, photos, journal entries, etc. Never surrender your password. There may be times when there &lt;em&gt;is&lt;&#x2F;em&gt; a legitimate need for the master password to run some diagnostics, but you should if at all possible be present to put that password in yourself and monitor closely what is done with your hardware. Go out of your way to find reputable repair shops. It will be worth the privacy.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Continuations—what are they?</title>
        <published>2022-11-17T00:00:00+00:00</published>
        <updated>2022-11-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-11-17_continutations/"/>
        <id>https://beta.lambdaland.org/posts/2022-11-17_continutations/</id>
        
        <summary type="html">&lt;p&gt;I had a friend ask me what &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Continuation&quot;&gt;continuations&lt;&#x2F;a&gt; are, and why they’re useful.
There’s a ton of literature about continuations; this is just a simple example meant to showcase something small and hopefully grokkable.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Unix As a Tool Forge</title>
        <published>2022-11-07T00:00:00+00:00</published>
        <updated>2022-11-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-11-07_unix_philosophy/"/>
        <id>https://beta.lambdaland.org/posts/2022-11-07_unix_philosophy/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2022-11-07_unix_philosophy/">&lt;p&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Unix_philosophy&quot;&gt;Wikipedia&lt;&#x2F;a&gt; cites a few different sources on what “Unix Philosophy” is. Peter Salus summarizes it as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Write programs that do one thing and do it well.&lt;&#x2F;li&gt;
&lt;li&gt;Write programs to work together.&lt;&#x2F;li&gt;
&lt;li&gt;Write programs to handle text streams, because that is a universal interface.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That second bullet point is my favorite: making &lt;em&gt;composable&lt;&#x2F;em&gt; programs rather than monolithic systems. In this way, Unix is designed to be a forge for easily building new tools. The first rule—writing programs that do one thing well—is largely a means to the second. When you have building blocks that take simple shapes, you can compose them easily like Lego pieces.&lt;&#x2F;p&gt;
&lt;p&gt;I think that second goal is what makes Unix win: instead of providing you with every tool under the sun, you get a set of composable tools that allow you to construct better tools perfectly tailored to your problem. No one hacking on a PDP-11 thought to make an easy way to publish a blog like this one, but they put the framework in place to let &lt;em&gt;me&lt;&#x2F;em&gt; put together the tools I need to deploy this very post with a single command.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-emacs-fits-inside-of-unix-philosophy&quot;&gt;How Emacs fits inside of Unix philosophy&lt;&#x2F;h2&gt;
&lt;p&gt;One might argue that Emacs goes against Unix philosophy, for it can quite literally do pretty much everything. But that only violates the first rule—if you consider Emacs to be a tool forge, then Emacs is quite in line with the Unix philosophy. Emacs provides functions that all work on the buffer or bits of text, and these can all be composed to craft a work environment to fit your needs. &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~ashton314&#x2F;.dotfiles&quot;&gt;I use&lt;&#x2F;a&gt; over 100 different packages, and they all play nice together!&lt;&#x2F;p&gt;
&lt;div class=&quot;marginnote&quot;&gt;
&lt;p&gt;Emacs once ran Germany’s flight control software (&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;emacs&#x2F;comments&#x2F;lly7po&#x2F;comment&#x2F;gnvzisy&quot;&gt;source&lt;&#x2F;a&gt;). Please don’t try this at home.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;I have come to view Emacs as my primary forge. It’s my layer on top of Unix, if you will. If I have Emacs customized how I like it, it doesn’t matter too much what operating system lives underneath: I can get a lot of work done. I used to view Emacs just as a tool, and I used it exclusively as a text editor. As time went on, though, I began to value the extreme keyboard-centric control Emacs gave me over my system. That’s why I &lt;a href=&quot;&#x2F;posts&#x2F;2020-07-22-gui-emacs&#x2F;&quot;&gt;moved from the terminal to the GUI&lt;&#x2F;a&gt; version of Emacs: I wanted to have more modifiers available to bind functions to.&lt;&#x2F;p&gt;
&lt;p&gt;Many people use Emacs exclusively as a text editor, and that’s fine. Usually these people have gotten comfortable with the command line, which is just another kind of tool forge. The great thing is both places make building new tools easy. Whatever your toolkit (though I do recommend you add Emacs to it if it’s not already there!) make sure you can build new tools with ease.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=33522735&quot;&gt;Discussion on Hacker News&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A kind chap sent me a link to &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tilde.town&#x2F;~ramin_hal9001&#x2F;articles&#x2F;emacs-fulfills-the-unix-philosophy.html&quot;&gt;this blog post&lt;&#x2F;a&gt; as well as &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;amodernist.com&#x2F;texts&#x2F;emacs-unix.html&quot;&gt;their own thoughts&lt;&#x2F;a&gt;, which seemed like good things to link to.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Yet another blog revamp</title>
        <published>2022-10-26T00:00:00+00:00</published>
        <updated>2022-10-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-10-26_yet_another_blog_theme/"/>
        <id>https://beta.lambdaland.org/posts/2022-10-26_yet_another_blog_theme/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2022-10-26_yet_another_blog_theme/">&lt;p&gt;Yes, it’s time to redo my blog again.&lt;&#x2F;p&gt;
&lt;p&gt;This time I found an ultra light-weight blog theme. This page here is under 100KB!&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to make something that acts more like a homepage for my research, rather than a blog. I still have all my blog posts, but now the focus will be on a more professional presentation of my work.&lt;&#x2F;p&gt;
&lt;p&gt;This theme is really what I’ve wanted all along: a home page with a max-width for the text, table of contents, and built-in local search!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Email, Getting Work Done, and Corporations, Or: Outlook Considered Harmful</title>
        <published>2022-08-28T00:00:00+00:00</published>
        <updated>2022-08-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-08-28_keep_email_federated/"/>
        <id>https://beta.lambdaland.org/posts/2022-08-28_keep_email_federated/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2022-08-28_keep_email_federated/">&lt;p&gt;It’s hard to overstate how important email is in our modern world. Even as hip new platforms like Slack &amp;amp;co. gain traction in the workplace, so much communication takes place in a crusty old medium that’s outlived every purported “email killer”. Where does it get its staying power from?&lt;&#x2F;p&gt;
&lt;p&gt;Email &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;History_of_email&quot;&gt;predates&lt;&#x2F;a&gt; much of the Internet as we know it today. Its current incarnation first emerged in the early 80s, though it has roots in earlier forms of digital messaging from as far back as the 60s. “Email” is roughly three related protocols: &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Simple_Mail_Transfer_Protocol&quot;&gt;SMTP&lt;&#x2F;a&gt;, “Simple Mail Transfer Protocol”, which deals with the &lt;em&gt;sending&lt;&#x2F;em&gt; of mail; &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Internet_Message_Access_Protocol&quot;&gt;IMAP&lt;&#x2F;a&gt;, or “Internet Message Access Protocol”, which allows mail clients to fetch mail; and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Post_Office_Protocol&quot;&gt;POP3&lt;&#x2F;a&gt;, or “Post Office Protocol”, an older mail fetching protocol largely superseded by IMAP.&lt;&#x2F;p&gt;
&lt;p&gt;One neat thing about email is that you don’t have to use a particular &lt;em&gt;email client&lt;&#x2F;em&gt; to send and receive messages: it doesn’t matter if you use Gmail’s web interface, their mobile app, or Thunderbird, or Apple’s built-in email program, or even text-based mail clients like &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mutt_(email_client)&quot;&gt;mutt&lt;&#x2F;a&gt;—everyone can still talk to each other.&lt;&#x2F;p&gt;
&lt;p&gt;Moreover, different email clients have different strengths: Gmail, for instance, is so simple that your grandma can (and probably does) use it to send you pictures or reminders about the family reunion next weekend. Academics, who typically have to deal with &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;parentheticallyspeaking.org&#x2F;articles&#x2F;bandit-inbox&#x2F;&quot;&gt;overwhelming heaps of emails&lt;&#x2F;a&gt;, can use keyboard-driven mail clients to digest all these messages. (See &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rougier&#x2F;mu4e-dashboard&quot;&gt;Nicolas P. Rougier’s mu4e-dashboard package&lt;&#x2F;a&gt; for an example of what some academics do.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The point&lt;&#x2F;strong&gt;: email derives its staying power from how the &lt;em&gt;common platform&lt;&#x2F;em&gt; (SMTP, IMAP) is decoupled from &lt;em&gt;how one interacts with it&lt;&#x2F;em&gt;. (mail clients) It is malleable and ubiquitous, and everyone can adapt it for their needs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;outlook-is-faux-email&quot;&gt;Outlook is faux email&lt;&#x2F;h2&gt;
&lt;p&gt;I’m starting a new position as a research assistant at the University of Utah, and I’m elated to be here. However, the university is pushing everyone to use their MS Outlook email system, and they’ve disabled SMTP and IMAP access. The mail client that I use (&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.djcbsoftware.nl&#x2F;code&#x2F;mu&#x2F;mu4e&#x2F;Why-another-e_002dmail-client.html&quot;&gt;mu4e&lt;&#x2F;a&gt; for those wondering) is built to work with these &lt;em&gt;common&lt;&#x2F;em&gt;, &lt;em&gt;decades-old&lt;&#x2F;em&gt; standards of IMAP and SMTP. I can’t use the built-in OS’s mail client or (heaven forbid) the web client nearly as effectively.&lt;&#x2F;p&gt;
&lt;p&gt;I’ll be trying some work-arounds, but I’m not optimistic that anything will be resolved in the near future. So for now I’m stuck using the mail client provided by my operating system for work-related email. It’s really a shame because some brilliant Emacs users have made managing email pleasant and effective.&lt;&#x2F;p&gt;
&lt;p&gt;Why would the university block the tools that I need to do my job effectively? I have a theory on that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-theory-of-two-companies&quot;&gt;The theory of two companies&lt;&#x2F;h2&gt;
&lt;p&gt;This also goes by the name “&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Staff_and_line&quot;&gt;staff and line&lt;&#x2F;a&gt;”.&lt;&#x2F;p&gt;
&lt;p&gt;Inside every organization there are two smaller companies: company 1 and company 2.&lt;&#x2F;p&gt;
&lt;p&gt;Company 1 is concerned with the &lt;em&gt;product&lt;&#x2F;em&gt; of the organization. In a tech firm for instance, company 1 is usually made up of engineering, product, sales, and marketing. (Broadly speaking.) In a university, company 1 is the faculty who are there to teach and do research.&lt;&#x2F;p&gt;
&lt;p&gt;Company 2 is concerned with running the organization. In a tech firm, this includes IT, HR, middle management, etc. In a university, company 2 is comprised of the staff and administration.&lt;&#x2F;p&gt;
&lt;p&gt;The primary job of company 2 is to support company 1’s operations. However, as is the nature with any large system, company 2 often begins to put some of its priorities over those of company 1’s. I saw this happen in a tech company I left a few years ago when management mandated that developers track the time they spent on each ticket in our &lt;del&gt;scrum&lt;&#x2F;del&gt; waterfall system &lt;em&gt;down to the minute&lt;&#x2F;em&gt;. This wasn’t a move that helped the developers in any way—this was just for management to feel like they had some better control of the situation.&lt;&#x2F;p&gt;
&lt;p&gt;Likewise with university email: no one I know would elect to use Outlook as their email platform. It seems the university administration has deemed it better to force everyone into a closed system to avoid the potential of lawsuits. It helps the university as an organization, but it gets in the way of the faculty’s work.&lt;&#x2F;p&gt;
&lt;p&gt;I get nervous when company 2 starts putting its priorities over company 1’s. To some extent it’s necessary, but it can be a slippery slope into bureaucratic paralyzation.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Today I learned: Vertical monitors and subpixel anti-aliasing</title>
        <published>2022-08-11T00:00:00+00:00</published>
        <updated>2022-08-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-08-11_til_vertical_monitors/"/>
        <id>https://beta.lambdaland.org/posts/2022-08-11_til_vertical_monitors/</id>
        
        <summary type="html">&lt;p&gt;Something I learned today from a coworker: if you turn your monitor sideways, &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Subpixel_rendering&quot;&gt;subpixel anti-aliasing&lt;&#x2F;a&gt; gets completely broken. This isn’t as much of an issue on today’s high-dpi displays, but for anything lower than a 4k screen, the effect can be noticeable.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>A New Font</title>
        <published>2022-08-01T00:00:00+00:00</published>
        <updated>2022-08-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-08-01_a_new_font/"/>
        <id>https://beta.lambdaland.org/posts/2022-08-01_a_new_font/</id>
        
        <summary type="html">&lt;p&gt;This week I created a custom build of the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;be5invis&#x2F;Iosevka&quot;&gt;Iosevka&lt;&#x2F;a&gt; font. I’ve used &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;input.djr.com&#x2F;&quot;&gt;Input Mono&lt;&#x2F;a&gt; for a long time now, and was very happy with it. However, it was missing a few glyphs that I wanted to use. Moreover, I didn’t have a license for the Input font to use on e.g. my blog. Iosevka is &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;be5invis&#x2F;Iosevka&#x2F;blob&#x2F;master&#x2F;doc&#x2F;custom-build.md&quot;&gt;stupendously customizable&lt;&#x2F;a&gt;, so I thought I’d see if I could get something close to Input’s styles.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>How to write a type checker&#x2F;type inferrer with good error messages</title>
        <published>2022-07-27T00:00:00+00:00</published>
        <updated>2022-07-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-07-27_how_to_write_a_type_checker/"/>
        <id>https://beta.lambdaland.org/posts/2022-07-27_how_to_write_a_type_checker/</id>
        
        <summary type="html">&lt;p&gt;This is an experimental type checker&#x2F;inferer for a simple lambda calculus. All the source for this may be found on my &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;type-error-research&quot;&gt;Codeberg repository&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Adding a Clock to the Tab-Bar in Emacs 28</title>
        <published>2022-07-20T00:00:00+00:00</published>
        <updated>2022-07-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-07-20_adding_a_clock_to_emacs/"/>
        <id>https://beta.lambdaland.org/posts/2022-07-20_adding_a_clock_to_emacs/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2022-07-20_adding_a_clock_to_emacs/">&lt;p&gt;+++&lt;&#x2F;p&gt;
&lt;p&gt;Today I figured out how to add a tab-bar to Emacs. I didn’t like having it in the mode-line: it gets duplicated for every window and my mode-line space is precious. In contrast, the right side of the tab-bar was always blank. I’ve just been using my OS’s clock, but I started using non-native fullscreen with Emacs, so I wanted a view of the clock again.&lt;&#x2F;p&gt;
&lt;p&gt;Add this to your &lt;code&gt;early-init.el&lt;&#x2F;code&gt; or the like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add-to-list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;tab-bar-format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;tab-bar-format-align-right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;append&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;add-to-list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;tab-bar-format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;tab-bar-format-global&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;append&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;setq&lt;&#x2F;span&gt;&lt;span&gt; display-time-format &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;%a %F %T&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;setq&lt;&#x2F;span&gt;&lt;span&gt; display-time-interval &lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;display-time-mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Adding that &lt;code&gt;tab-bar-format-global&lt;&#x2F;code&gt; to the &lt;code&gt;tab-bar-format&lt;&#x2F;code&gt; list means that whatever would to on the “global” section of the format line will now appear in the tab bar. The &lt;code&gt;tab-bar-format-align-right&lt;&#x2F;code&gt; puts the clock at the top-right hand corner, instead of right next to the tab. Here’s what it looks like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;emacs_tab_clock.jpg&quot; alt=&quot;Screenshot of my Emacs buffer while I was composing this post; a custom clock is visible on the right side of the tab-bar&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that this only works in Emacs 28.&lt;&#x2F;p&gt;
&lt;p&gt;I wrote an ugly hack that uses a posframe to display the time in the right place. I &lt;em&gt;do not&lt;&#x2F;em&gt; recommend this, but if you’re still on Emacs 27 or earlier for whatever reason, this might work for you:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #616E88;&quot;&gt;;;; Hack to display a clock in the tab-bar&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defun&lt;&#x2F;span&gt;&lt;span&gt; posframe-poshandler-real-top-right&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;info&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;cons&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;plist-get&lt;&#x2F;span&gt;&lt;span&gt; info &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;parent-frame-width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;plist-get&lt;&#x2F;span&gt;&lt;span&gt; info &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;posframe-width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;plist-get&lt;&#x2F;span&gt;&lt;span&gt; info &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;font-width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;        0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defun&lt;&#x2F;span&gt;&lt;span&gt; update-posframe-clock&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;Update the clock displayed with posframe&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span&gt;the-time &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;format-time-string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;%H:%M:%S&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;tab-bar-tabs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;posframe-show &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*clock*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                       :&lt;&#x2F;span&gt;&lt;span&gt;string the-time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                       :&lt;&#x2F;span&gt;&lt;span&gt;width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                       :&lt;&#x2F;span&gt;&lt;span&gt;poshandler&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;posframe-poshandler-real-top-right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;                       :&lt;&#x2F;span&gt;&lt;span&gt;background-color&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;plist-get&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;custom-face-attributes-get&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;tab-bar&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;) :&lt;&#x2F;span&gt;&lt;span&gt;background&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span&gt;posframe-delete &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;*clock*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;when&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;display-graphic-p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;run-with-timer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt;   1 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;   #&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;update-posframe-clock&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Again, I recommend you find something better than the above. It will almost certainly break. &lt;em&gt;Caveat emptor&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rules for Social Media</title>
        <published>2022-07-17T00:00:00+00:00</published>
        <updated>2022-07-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-07-17_social_media_rules/"/>
        <id>https://beta.lambdaland.org/posts/2022-07-17_social_media_rules/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2022-07-17_social_media_rules/">&lt;p&gt;I’m not on many social media platforms these days. I like it like that. I mostly follow some academics and people who post interesting stuff. I post only occasionally, usually to show off my recent hiking exploits. I’ve come up with some rules for myself (all subject to change) about what I post.&lt;&#x2F;p&gt;
&lt;p&gt;A post must meet all the following criteria:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It must be positive and uplifting.&lt;&#x2F;p&gt;
&lt;p&gt;There’s enough that’s negative on the internet. Don’t add to it.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;It must be interesting&lt;&#x2F;p&gt;
&lt;p&gt;I’m a bad judge of this sometimes; I don’t want to be that schmuck who’s posting drivel for the sake of posting. Sorry if that happens.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;No politics.&lt;&#x2F;p&gt;
&lt;p&gt;I’ll make a few exceptions here and there, but as a general rule I don’t like posting about politics. I do follow some people that I find interesting for political reasons; that expressly does &lt;em&gt;not&lt;&#x2F;em&gt; mean that I agree with all or any of their views. I will post mostly about technology, academics, jokes, and hiking.&lt;&#x2F;p&gt;
&lt;p&gt;Why no politics? I try to keep my views nuanced. It is fantastically difficult to convey any degree of nuance in a tweet or two. If I do have something I feel strongly about, I’ll post about it in my &lt;a href=&quot;&#x2F;personal&quot;&gt;personal&lt;&#x2F;a&gt; section of my blog so I can write something in long-form, but that’s it.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I won’t post often, but when I do, I’ll try to make sure it meets a high bar of quality. I’m not out to get more followers or anything—I have just had some really good interactions online, and I want to filter for that. Fighting trolls can be fun, but is ultimately unproductive and uninteresting.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>microKanren Reading</title>
        <published>2022-07-04T00:00:00+00:00</published>
        <updated>2022-07-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-07-04_kanren/"/>
        <id>https://beta.lambdaland.org/posts/2022-07-04_kanren/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2022-07-04_kanren/">&lt;p&gt;+++&lt;&#x2F;p&gt;
&lt;p&gt;μKanren (“micro-Kanren”) is a tiny, embeddable logic programming language. It’s easy to understand and implement in almost any language. It’s a great case study of an embedded language: unlike other common “embedded” languages like SQL or regex, which normally are represented as just plain-old strings, μKanren takes more advantage of the host language’s features.&lt;&#x2F;p&gt;
&lt;p&gt;I recommend reading &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;webyrd.net&#x2F;scheme-2013&#x2F;papers&#x2F;HemannMuKanren2013.pdf&quot;&gt;the original paper&lt;&#x2F;a&gt;: it’s short, well-written, and easy to understand.&lt;&#x2F;p&gt;
&lt;p&gt;I did a write-up which you can read &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;ashton314&#x2F;microKanren&quot;&gt;on Codeberg&lt;&#x2F;a&gt;. The README is my set of notes that I made while walking through the implementation of the paper, and the repository contains an implementation in &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;racket-lang.org&quot;&gt;Racket&lt;&#x2F;a&gt;. I’ve included some fun use cases like a type checker&#x2F;inference engine that takes up only 37 lines of code!&lt;&#x2F;p&gt;
&lt;p&gt;It’s a fun little language, and I might be able to use it at work soon actually. It’s definitely specialized for solving a particular class of problem, but you might be surprised how many things fall into that category. Have you used μKanren? &lt;a href=&quot;&#x2F;about&#x2F;#contact&quot;&gt;Drop me a line&lt;&#x2F;a&gt;—I’d love to hear about it!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Blog update</title>
        <published>2022-07-02T00:00:00+00:00</published>
        <updated>2022-07-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-07-02_update/"/>
        <id>https://beta.lambdaland.org/posts/2022-07-02_update/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2022-07-02_update/">&lt;p&gt;Brief update on the blog: I had been running a custom fork of the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lxndrblz&#x2F;anatole&quot;&gt;Anatole&lt;&#x2F;a&gt; theme; it diverged pretty heavily, and I found a nice way to customize the CSS. Behold! The new-and-improved blog.&lt;&#x2F;p&gt;
&lt;p&gt;Some of the new extensions to Anatole include the ability to set a static page as your profile; I’ll do this and include links to lists of publications and whatnot. This should make my blog a better place for my professional&#x2F;academic life.&lt;&#x2F;p&gt;
&lt;p&gt;I have lost my comments and metrics plugins; I’m debating about whether or not I will want to re-include them. I wasn’t getting too much benefit from them (though it was exciting to see when a post I wrote made it to the front page of HN!) and they’re a little bit of a hassle to maintain.&lt;&#x2F;p&gt;
&lt;p&gt;In other news, I’m trying out &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sr.ht&#x2F;~ashton314&quot;&gt;SourceHut&lt;&#x2F;a&gt; to host some of my projects; stay tuned for a post about μKanren, a tiny logic language that can be embedded into pretty much any language you want. You can read the material that will form the source of my post &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~ashton314&#x2F;microKanren&quot;&gt;here on SourceHut&lt;&#x2F;a&gt; if you are impatient.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Complete and Liveness, Safe and Sound</title>
        <published>2022-03-02T00:00:00+00:00</published>
        <updated>2022-03-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2022-03-02_sound_complete_and_duals/"/>
        <id>https://beta.lambdaland.org/posts/2022-03-02_sound_complete_and_duals/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2022-03-02_sound_complete_and_duals/">&lt;p&gt;I have a hard time keeping these terms straight:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;liveness vs. safety&lt;&#x2F;li&gt;
&lt;li&gt;soundness vs. completeness&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is intended as a short guide for myself; maybe someone else will find it useful too! Note that this is all to the best of my knowledge and understanding at the present time; if there be faults, they be the faults of myself. I welcome correction and clarification if I am wrong.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;liveness-vs-safety&quot;&gt;Liveness vs. Safety&lt;&#x2F;h2&gt;
&lt;p&gt;Liveness and safety deal with &lt;em&gt;properties&lt;&#x2F;em&gt; of a system. Contrast that with soundness and completion, which are adjectives about analyses.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;liveness&quot;&gt;Liveness&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;em&gt;liveness&lt;&#x2F;em&gt; property of a system is of the form “something good will eventually happen.” One example is eventual consistency in a concurrent system: we want to know that, after some finite number of steps, our system comes to a consistent state of the world.&lt;&#x2F;p&gt;
&lt;p&gt;Another example might be with a bank: I want it to be the case that when I move money between accounts, the correct amount of money makes it to the destination account. That is something we want to eventually happen, and that’s what makes it a liveness property.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;safety&quot;&gt;Safety&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;em&gt;Safety&lt;&#x2F;em&gt; is the dual of &lt;em&gt;liveness&lt;&#x2F;em&gt;: in contrast to liveness, a safety property states that “something bad does not occur”. One example of a safety property is in an operating system, nothing prevents the kernel from preempting a task. We never want to get stuck in a state where the kernel cannot regain control of the processor. If our operating system is safe in this regard, we know that we’ll never have the case where a program supersedes the kernel.&lt;&#x2F;p&gt;
&lt;p&gt;Extending the bank analogy, a safety property might be that we never want money lost in a transaction. The program might occasionally fail to deliver money, but no value is accidentally destroyed during a transfer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;soundness-vs-completeness&quot;&gt;Soundness vs. Completeness&lt;&#x2F;h2&gt;
&lt;p&gt;Soundness and completeness refer to whole systems that make some kind of decision, e.g. a type system or some kind of a static analysis.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;soundness&quot;&gt;Soundness&lt;&#x2F;h3&gt;
&lt;p&gt;From &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Soundness&quot;&gt;Wikipedia&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;[A]n argument is sound if it is both valid in form and its premises are true. Soundness also has a related meaning in mathematical logic, wherein logical systems are sound if and only if every formula that can be proved in the system is logically valid with respect to the semantics of the system.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;em&gt;Soundness&lt;&#x2F;em&gt; means the system is trustworthy. A sound type system, for example, will never tell you that a program is devoid of type errors when there are in fact type errors. Most type systems typically are sound. This means, however, that there are programs which may not contain a type error but that the type checker cannot prove to be devoid of errors.&lt;&#x2F;p&gt;
&lt;p&gt;Another term that may be used for soundness is &lt;em&gt;correct&lt;&#x2F;em&gt;. (Though, I believe, this may be highly context-dependent.)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;completeness&quot;&gt;Completeness&lt;&#x2F;h3&gt;
&lt;p&gt;The dual of &lt;em&gt;soundness&lt;&#x2F;em&gt;: if a system is complete, it means the system can give an answer for every input. It might make some mistakes in reasoning. E.g. with a complete type system, there is no program which it cannot assign a type to (even if it’s a divergent type) but an assertion that a program is type-safe is not necessarily true.&lt;&#x2F;p&gt;
&lt;p&gt;Why can’t we have both soundness and completeness at the same time? Gödel is to blame for that.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Christmas 2021</title>
        <published>2021-12-25T00:00:00+00:00</published>
        <updated>2021-12-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-12-25_christmas/"/>
        <id>https://beta.lambdaland.org/posts/2021-12-25_christmas/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2021-12-25_christmas/">&lt;p&gt;It’s my first Christmas being a dad. The end of the school semester was unusually stressful; I didn’t have much time or energy to anticipate Christmas. But I’ve felt a marked lack of eagerness for &lt;em&gt;getting&lt;&#x2F;em&gt; presents. That feeling wanes each year—something I’m grateful for—but this year I only felt an eagerness for a time of peace and celebration with my family. Peaceful it has been.&lt;&#x2F;p&gt;
&lt;p&gt;My family isn’t perfect. (My baby daughter is about as perfect as they come, though!) The time I’ve gotten to spend so far and the time that I will spend with them is precious to me. My wife and I have focused so much on celebrating the birth of Jesus Christ that this commercialized junk we put up with has been all but absent from our home. We have a few books about Santa Claus that we read to our daughter, but we’ve listened to strictly Christ-centered music. (&lt;em&gt;A Charlie Brown Christmas&lt;&#x2F;em&gt; counts, though!) There’s been a spirit in our home that has brought me comfort and peace in this tumultuous year—more than any before it.&lt;&#x2F;p&gt;
&lt;p&gt;Merry Christmas—may the peace of God be with you.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Class Management Reviews: Fall 2021</title>
        <published>2021-12-18T00:00:00+00:00</published>
        <updated>2021-12-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-12-18_classroom_management_reviews/"/>
        <id>https://beta.lambdaland.org/posts/2021-12-18_classroom_management_reviews/</id>
        
        <summary type="html">&lt;p&gt;A collection of what worked well and what didn’t in classes that I took this semester. This is partially for me to record what things reduced friction for me as a student so that one day, should I become a professor, I’ll be able to run the lowest-friction class ever!&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Foundations of High-Modernist Ideology in Metropolis</title>
        <published>2021-12-07T00:00:00+00:00</published>
        <updated>2021-12-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-12-07_metropolis_essay/"/>
        <id>https://beta.lambdaland.org/posts/2021-12-07_metropolis_essay/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2021-12-07_metropolis_essay/">&lt;p&gt;&lt;em&gt;The following is from a essay from a class on German literature and film.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Fritz Lang’s movie &lt;em&gt;Metropolis&lt;&#x2F;em&gt; is primarily about the struggle between the oppressed working class and the ruling elite. What drives this tension, however, is a particular view of technology and technological progress that exacerbates the problems the film focuses on. This mentality is called &lt;em&gt;high modernist ideology&lt;&#x2F;em&gt; by Scott in his book &lt;em&gt;Seeing Like a State&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;What is high modernism, then? It is best conceived as a strong (one might even say muscle-bound) version of the beliefs in scientific and technical progress that were associated with industrialization in Western Europe and in North America from roughly 1830 until World War I. At its center was a supreme self-confidence about continued linear progress, the development of scientific and technical knowledge, the expansion of production, the rational design of social order, the growing satisfaction of human needs, and, not least, an increasing control over nature (including human nature) commensurate with scientific understanding of natural laws.&lt;&#x2F;p&gt;
&lt;p&gt;(Scott, 89)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Note that this is different from the literary definition of high modernism. For the purposes of this paper, &lt;em&gt;high modernist ideology&lt;&#x2F;em&gt; is understood as a belief that rational, scientific systems will solve all of mankind’s ailments. &lt;em&gt;Metropolis&lt;&#x2F;em&gt; is situated right at the tail end of the reign of high modernist ideology, and illustrates some of the failings of that mentality.&lt;&#x2F;p&gt;
&lt;p&gt;In this paper we will examine how &lt;em&gt;Metropolis&lt;&#x2F;em&gt; illustrates the dangers of high modernist thinking in how it portrays man’s subservient relationship to machinery and the fragility of the city of Metropolis resulting from top-down, rational planning. Ironically, even though these themes of centralized failure have been common place in film for more than a century now,&lt;sup&gt;&lt;a id=&quot;fnr.1&quot; class=&quot;footref&quot; href=&quot;#fn.1&quot; role=&quot;doc-backlink&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; the dream of a perfectly organized Utopia persists in our culture today. &lt;em&gt;Metropolis&lt;&#x2F;em&gt; therefore remains an important case study of the dangers and failings of high modernism.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;man-serves-the-machine&quot;&gt;Man Serves the Machine&lt;&#x2F;h2&gt;
&lt;p&gt;The opening of &lt;em&gt;Metropolis&lt;&#x2F;em&gt; shows a stark example of men working as slaves to the machine. Freder goes down to the lower levels to see how the workers live. He passes workers mechanically going from pose to pose to keep the machines running. Their jerky, repetitive motions cast the human workers merely as organic components of each machine that they tend.&lt;&#x2F;p&gt;
&lt;p&gt;When Freder arrives at the M-Machine, he witnesses an explosion that kills or seriously maims several workers, all because one worker was unable to reach a particular valve in time. The machine was obviously not designed to be ergonomic and was lacking critical safety features that would have prevented such a devastating accident. The machine’s complexity and human-hostile design make  accidents like this essentially inevitable. The massive requirements that the machines impose on the humans shows the high modernist idea that humans should submit themselves to rational ideas, and that human nature can be overcome by rational, technical means.&lt;&#x2F;p&gt;
&lt;p&gt;Yet this submission to rational, mechanical systems is in itself an irrational one. Freder’s vision of Moloch gobbling up workers who dutifully march into the gaping jaws of the machine speaks to the almost fanatic devotion certain planners of large systems had to rationality. The vision closes and Freder sees some workers wordlessly&lt;sup&gt;&lt;a id=&quot;fnr.2&quot; class=&quot;footref&quot; href=&quot;#fn.2&quot; role=&quot;doc-backlink&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; collecting the bodies of the injured and dead, whilst others take up their posts to keep the machine working. There’s some redundancy in how the human workers are allocated to account for mechanical failures or accidents, but there’s no redundancy &lt;em&gt;in the machines&lt;&#x2F;em&gt; to account for human failures.&lt;&#x2F;p&gt;
&lt;p&gt;We get other hints throughout the film of the submission of men to the machine. Metropolis looks to be absolutely unlivable. In the upper levels, we do see crowds gathered for entertainment and sport, but the city streets are either entirely devoted to automobiles, or are so foreboding and unwelcoming that no pedestrian-centric economy could ever flourish there. The streets are sterile and perfectly regular; the buildings are all blocks and perfectly featureless. This prefigures some of the architecture and city planning that was present during the DDR: massive apartment complexes built out of prefabricated concrete slabs were often placed far away from the city center, so as to make the Plattenbau districts feel stifling. The straight lines might look good on paper, but maps and city plans are of necessity a simplification over what real life looks like. Life flourishes in the hand-crafted and in the unique. Top-down imposed grids crush what makes life interesting and livable in the city.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-fragility-of-monoculture-and-centralized-planning&quot;&gt;The Fragility of Monoculture and Centralized Planning&lt;&#x2F;h2&gt;
&lt;p&gt;After the accident at the M-Machine, Freder rushes to tell his father, the architect and ruler of Metropolis, about what he saw. In his office at the top of the New Tower of Babel, Jon Frederson controls the city from a central vantage point: aides digest and bring him information, while others record his decisions and carry out his orders. He is the very model of a high modernist: his rationality has brought order and prosperity to the citizens of the upper levels, and everyone above is free to spend their time as they please. It seems that the city is working perfectly well. However, Metropolis turns out to be very fragile.&lt;&#x2F;p&gt;
&lt;p&gt;Frederson’s control begins unraveling when his aids fail to bring him the information that he wants, and continues when Rotwang plots against him. Eventually the city collapses when the striking workers’ protest goes further than he had foreseen. The destruction of the Heart Machine causes the lower levels of the city to flood and the upper levels to loose power. Cars halt in the streets, and elevators plummet down their shafts. The apparently well-ordered city with bumper-to-bumper cars moving smoothly down the streets suffers cardiac arrest: broken elevators and stopped cars hinder the protagonists as they try to reach safety.&lt;&#x2F;p&gt;
&lt;p&gt;This fragility has a good analogue from the mistakes of high modernist ideology. &lt;em&gt;Scientific forestry&lt;&#x2F;em&gt; came about in the 1700s in Germany as a way to improve lumber yield. A plot of forest would be cleared of all “junk” trees and underbrush, and new trees of a single species were planted in straight lines. The ground was cleared to make way for the saplings, and each year there was a neat rotation between different parcels of land from which mature wood could easily and quickly be harvested. Initially, this was a great success: the wood was strong, straight, and plentiful. There was no junk wood that interfered, and lumber outputs could be reliably predicted.&lt;&#x2F;p&gt;
&lt;p&gt;It was not, however, without its drawbacks. In a book published in 1986, Richard Plochmann describes how yields dropped after the first few batches (Lang and Pye). The reasons for the drop are complex, but the cause was simple: the “clean” forest that produced such predictable quantities of lumber was a monoculture: there was no variety to protect against a pest that targeted a single species of tree. The soil fauna that are critical to a flourishing forest died off, and the trees withered when they didn’t get the nutrients that they needed.&lt;&#x2F;p&gt;
&lt;p&gt;One of the hallmarks of high modernist ideology is that problems can be solved by large, complex systems, be they mechanical, political, or bureaucratic. Such aspirations usually fail to take account of the difficulties in getting complex systems to run for long periods of time without encountering significant failures. &lt;em&gt;Metropolis&lt;&#x2F;em&gt; vividly illustrates the fall of Jon Frederson’s pride as the fragility in the massive system he created causes everything to fail around him.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mediation&quot;&gt;Mediation&lt;&#x2F;h2&gt;
&lt;p&gt;Amidst the warnings of the dangers of high modernist ideology, the message of &lt;em&gt;Metropolis&lt;&#x2F;em&gt; is tentatively hopeful: “the mediator between the hands and the head must be the heart!” By the end of the movie, we see the robot masquerading as a human unmasked and destroyed, and the beginnings of greater understanding between the architect of the city, and those that are actually required to live in the city and maintain it. This ultimately is also the cure for high modernist ideology: the designers of complex systems must take into account the needs and the experiences of those who would suffer the brunt of its effects. &lt;em&gt;Metropolis&lt;&#x2F;em&gt; casts this lesson in the discourse of class struggle, but it can also apply to those who design cities, automobiles, software, and other systems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;works-cited&quot;&gt;Works Cited&lt;&#x2F;h2&gt;
&lt;p&gt;Scott, James C. Seeing like a State: How Certain Schemes to Improve the Human Condition Have Failed. Nachdr., Yale Univ. Press, 2008.&lt;&#x2F;p&gt;
&lt;p&gt;Lang, Chris, and Oliver Pye. “Blinded by Science: The Invention of Scientific Forestry and Its Influence in the Mekong Region.” Chrislang.Org, 1 Nov. 2000, &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chrislang.org&#x2F;2000&#x2F;11&#x2F;01&#x2F;blinded-by-science-the-invention-of-scientific-forestry-and-its-influence-in-the-mekong-region&#x2F;&quot;&gt;https:&#x2F;&#x2F;chrislang.org&#x2F;2000&#x2F;11&#x2F;01&#x2F;blinded-by-science-the-invention-of-scientific-forestry-and-its-influence-in-the-mekong-region&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;footnotes&quot;&gt;Footnotes&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;sup&gt;&lt;a id=&quot;fn.1&quot; href=&quot;#fnr.1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Other films with central-point-of-failure plots include Star Wars, (the thermal exhaust port on the Death Star) The Lord of the Rings, (cast it into the fire!) Batman Begins, (the train with the microwave generator) etc.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;sup&gt;&lt;a id=&quot;fn.2&quot; href=&quot;#fnr.2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; The failure of Texas’s power grid is an extremely interesting case study about the dangers of fragile systems.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Programs and Intent</title>
        <published>2021-11-09T00:00:00+00:00</published>
        <updated>2021-11-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-11-09_programs_and_intent/"/>
        <id>https://beta.lambdaland.org/posts/2021-11-09_programs_and_intent/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2021-11-09_programs_and_intent/">&lt;p&gt;What does this program do? At the most reduced level, one could say that a program’s behavior is defined by the effect it has on the hardware running it. That’s not very useful however; when we’re programming, we often have to deal with legacy code and tease out the original intent of the code.&lt;&#x2F;p&gt;
&lt;p&gt;Saying that the meaning of a program is entirely encapsulated by the code is saying that the intent and the implementation are the same. They so rarely are!&lt;&#x2F;p&gt;
&lt;p&gt;Today I found some Elixir code that looked like the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;font-weight: bold;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;spec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; all_have_key?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lst &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;{}],&lt;&#x2F;span&gt;&lt;span&gt; needed_key &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; boolean&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; all_have_key?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; needed_key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  lst&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;keys&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;any?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; k &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; k &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; needed_key &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;all?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(Note, I just threw that together—possible syntax errors in there.)&lt;&#x2F;p&gt;
&lt;p&gt;What is this code trying to do? It’s trying to check that each map in a list has a given key and return true or false on that condition. I don’t think the code even had a &lt;code&gt;@spec&lt;&#x2F;code&gt; to help explain that: all I had was the function name (which was not as clear as &lt;code&gt;all_have_key&lt;&#x2F;code&gt;) and the source.&lt;&#x2F;p&gt;
&lt;p&gt;After a few moments of reflection, I rewrote it to this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;font-weight: bold;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;spec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; all_have_key?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lst &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;{}],&lt;&#x2F;span&gt;&lt;span&gt; needed_key &lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; boolean&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt; all_have_key?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; needed_key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  lst&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt;Map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;has_key?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; needed_key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;  |&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8FBCBB;&quot;&gt; Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;all?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That big long complicated bit has a built-in function. The built-in function is more efficient because it doesn’t traverse the entire list of keys searching for a match: with a map, you get O(1) lookup time.&lt;&#x2F;p&gt;
&lt;p&gt;So what does a program mean? I’m pretty confident that I preserved the intended meaning of this program. But what’s a better way to express that intent?&lt;&#x2F;p&gt;
&lt;p&gt;Tests are useful, but they don’t capture everything. While I think this function was tested, no test can ever ensure 100% preservation of intent. &lt;em&gt;Tests can only find witnesses of meaning mismatches.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Type systems are helpful too. But types come in varying degrees of precision: some languages give you an &lt;code&gt;Int&lt;&#x2F;code&gt;, while others give you &lt;code&gt;Int&lt;&#x2F;code&gt; or &lt;code&gt;Nat&lt;&#x2F;code&gt; or &lt;code&gt;∈ {1, 2, 3}&lt;&#x2F;code&gt;. More powerful type systems let you express more of your intent in a way that can be mechanically checked, but they tend to also be more burdensome.&lt;&#x2F;p&gt;
&lt;p&gt;This is an open question that I know there’s a lot of ongoing research around. I’m excited to see what I find!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Models of Programming</title>
        <published>2021-10-24T00:00:00+00:00</published>
        <updated>2021-10-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-09-25_models_of_programming_draft2/"/>
        <id>https://beta.lambdaland.org/posts/2021-09-25_models_of_programming_draft2/</id>
        
        <summary type="html">&lt;p&gt;+++&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Last week I was studying outside of a lecture hall where someone was teaching an introductory course on computer programming. There was a lot that I overheard that I disagreed with; this essay is an attempt to help me crystallize what exactly I disagreed with.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Reluctance to Bear a Symbol</title>
        <published>2021-09-19T00:00:00+00:00</published>
        <updated>2021-09-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-09-19_symbols/"/>
        <id>https://beta.lambdaland.org/posts/2021-09-19_symbols/</id>
        
        <summary type="html">&lt;p&gt;I feel uncomfortable with many symbols. I might have opinions about a subject, but there’s rarely a camp that has some symbol, flag, slogan, etc. that I’m comfortable with adopting because that camp does not accurately reflect my opinion. All too often, a slogan takes on more than its surface meaning, and that can make using that slogan tricky.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>A programmable programming language? I&#x27;ll drink to that!</title>
        <published>2021-08-21T00:00:00+00:00</published>
        <updated>2021-08-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-08-21_racket_mug/"/>
        <id>https://beta.lambdaland.org/posts/2021-08-21_racket_mug/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2021-08-21_racket_mug/">&lt;p&gt;My wife and I got a chance to go to a place that lets you paint pottery and then have it fired. The pottery is all pre-made; you just get to paint it.&lt;&#x2F;p&gt;
&lt;p&gt;It’s been a very long time since I’ve worked with a physical art medium, so the mug looks kinda dumpy. I did alright with the Racket logo on the bottom-inside of the mug though!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;racket_mug0.jpeg&quot; alt=&quot;A poorly-painted blue mug&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;img&#x2F;racket_mug1.jpeg&quot; alt=&quot;A passable freehanded Racket logo&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I’m working on some fun projects with Racket. It’s been a really enjoyable language to work with. If you haven’t given it a whirl, I recommend checking it out. The docs on the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;racket-lang.org&quot;&gt;official Racket site&lt;&#x2F;a&gt; are very good, and there are some absolutely &lt;em&gt;stellar&lt;&#x2F;em&gt; gentle introductions to the language like &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;htdp.org&quot;&gt;How to Design Programs&lt;&#x2F;a&gt; that I would recommend.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Health and Taking Care of Yourself</title>
        <published>2021-08-14T00:00:00+00:00</published>
        <updated>2021-08-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-08-14_health/"/>
        <id>https://beta.lambdaland.org/posts/2021-08-14_health/</id>
        
        <summary type="html">&lt;p&gt;It’s going to be another long night. My baby has reached the point where she’s too tired to sleep. She alternates between screaming at 90+ decibels and sleeping fitfully. She only transfers from the crying state to the sleep state after prolonged, labored rocking and soothing. She transfers back to the base crying state on her own after a few seconds.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Ode to Used Book Stores</title>
        <published>2021-08-03T00:00:00+00:00</published>
        <updated>2021-08-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-08-03_used_books/"/>
        <id>https://beta.lambdaland.org/posts/2021-08-03_used_books/</id>
        
        <summary type="html">&lt;blockquote&gt;
&lt;p&gt;When I get a little money I buy books; and if any is left I buy food and clothes.&lt;br &#x2F;&gt;
— Erasmus of Rotterdam&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Used bookstores are my arch nemesis.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Control-Flow Analysis</title>
        <published>2021-07-27T00:00:00+00:00</published>
        <updated>2021-07-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-05-20_cfa/"/>
        <id>https://beta.lambdaland.org/posts/2021-05-20_cfa/</id>
        
        <summary type="html">&lt;p&gt;Control-Flow Analysis is a popular technique for performing static analysis of many different kinds of programming languages.
It’s most often needed in cases where you have some kind of dynamic dispatch: either where you have first-class functions or when you have objects and you call one of their methods.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>This Too Shall Pass</title>
        <published>2021-06-13T00:00:00+00:00</published>
        <updated>2021-06-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-06-13_this_shall_pass/"/>
        <id>https://beta.lambdaland.org/posts/2021-06-13_this_shall_pass/</id>
        
        <summary type="html">&lt;p&gt;It’s cliché at this point to say that 2020 was a rough year. I’m grateful in that I and my wife were relatively unscathed by the pandemic. I had some personal health issues however that by themselves made 2020 a bit of a struggle. I learned some important lessons.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Easter 2021</title>
        <published>2021-03-21T00:00:00+00:00</published>
        <updated>2021-03-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-03-21_easter_2021/"/>
        <id>https://beta.lambdaland.org/posts/2021-03-21_easter_2021/</id>
        
        <summary type="html">&lt;p&gt;I love Easter. In my mind it is just as important as Christmas. Indeed, if Christ had not died for our sins and been resurrected, then there would be no reason to celebrate His birth.&lt;&#x2F;p&gt;
&lt;p&gt;I recorded a short, simple vocal arrangement of “O Savior, Thou Who Wearest a Crown” by J. S. Bach with my wife.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Using a Raspberry Pi for Proctorio</title>
        <published>2021-01-30T00:00:00+00:00</published>
        <updated>2021-01-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2021-01-30_proctorio/"/>
        <id>https://beta.lambdaland.org/posts/2021-01-30_proctorio/</id>
        
        <summary type="html">&lt;p&gt;For one of my classes I am required to take a short weekly exam via Proctorio. There’s &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.theverge.com&#x2F;2020&#x2F;10&#x2F;22&#x2F;21526792&#x2F;proctorio-online-test-proctoring-lawsuit-universities-students-coronavirus&quot;&gt;been some controversy&lt;&#x2F;a&gt; surrounding this software. Although it claims it’s trustworthy, it’s not open-source, so no one can verify their claims. So naturally, I was reluctant to install it on my primary machine. Enter: the spare raspberry pi I have sitting around.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>FreeBSD on a Raspberry Pi 4 with 4GB of RAM</title>
        <published>2020-12-28T00:00:00+00:00</published>
        <updated>2020-12-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-12-23_freebsd_rpi4/"/>
        <id>https://beta.lambdaland.org/posts/2020-12-23_freebsd_rpi4/</id>
        
        <summary type="html">&lt;p&gt;+++&lt;&#x2F;p&gt;
&lt;p&gt;This is the story of how I managed to get FreeBSD running on a Raspberry Pi 4 with 4GB of RAM, though I think the setup story is pretty similar for those with 2GB and 8GB.&lt;&#x2F;p&gt;
&lt;p&gt;I also managed to get Rust built from source, (kind of) which is nice because the default Rust installer doesn’t seem to work for FreeBSD running on a Raspberry Pi.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Dr. Loopback, Or: How I Learned to Stop DOSing Myself and Love the Pi-Hole</title>
        <published>2020-12-11T00:00:00+00:00</published>
        <updated>2020-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-12-11-raspberry-pi-dos/"/>
        <id>https://beta.lambdaland.org/posts/2020-12-11-raspberry-pi-dos/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2020-12-11-raspberry-pi-dos/">&lt;p&gt;I noticed that my Internet was acting strangely: whenever I visited a web page, my browser would hang for a good second or two before it started loading anything. Zoom calls worked without a problem for school, so this tipped me off that something was wrong with the DNS lookup or the handshake.&lt;&#x2F;p&gt;
&lt;p&gt;Sure enough, I popped open my &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pi-hole.net&#x2F;&quot;&gt;Pi-Hole&lt;&#x2F;a&gt; admin console, and was greeted with this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;pi_hole_before.png&quot; alt=&quot;Pi-Hole Admin Console&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The green number in the &lt;code&gt;Total Queries&lt;&#x2F;code&gt; box would jump by 10, 20, or sometimes even 100 every second.&lt;&#x2F;p&gt;
&lt;p&gt;I tried turning off, disconnecting, and rebooting my various computers and devices to see if it was just some rogue process messing everything up. No change. I rebooted my router. No change. I updated and restarted the Pi-Hole. Still no change.&lt;&#x2F;p&gt;
&lt;p&gt;I noticed that a &lt;em&gt;lot&lt;&#x2F;em&gt; of requests to the domain &lt;code&gt;lb._dns-sd._udp.0.0.0.10.in-addr.arpa&lt;&#x2F;code&gt;. I did a web search and found &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;discourse.pi-hole.net&#x2F;t&#x2F;many-requests-to-lb-dns-sd-udp-0-1-168-192-in-addr-arpa&#x2F;18241&quot;&gt;a single post on a forum&lt;&#x2F;a&gt; that suggested turning off conditional forwarding on the Pi-Hole.&lt;&#x2F;p&gt;
&lt;p&gt;I went into admin settings, turned off conditional forwarding, and was rewarded with this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;pi_hole_after.png&quot; alt=&quot;Pi-Hole Admin Console&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now my pi isn’t overloaded with DNS requests, and my Internet is as snappy as it used to be.&lt;&#x2F;p&gt;
&lt;p&gt;What happened, I think, was that a device on my network would try and lookup some name. The router would forward this request to the pi, which would then forward it back to the router, which would then send it back to the pi, etc. Boom. Infinite loop, and all my DNS requests got bogged down.&lt;&#x2F;p&gt;
&lt;p&gt;I’m not very good with networking; that’s probably my biggest weakness. I learned a thing today, though!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>RMS Does Not See the Future of Emacs</title>
        <published>2020-11-27T00:00:00+00:00</published>
        <updated>2020-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-11-future-of-emacs/"/>
        <id>https://beta.lambdaland.org/posts/2020-11-future-of-emacs/</id>
        
        <summary type="html">&lt;p&gt;I am an avid &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;emacs.org&quot;&gt;Emacs&lt;&#x2F;a&gt; user. I’m using it right now to compose this post. I use it every single day for everything from work to school to personal notes. Most of my activity on GitHub comes from me tweaking little things in my configuration files. I now have an editor that perfectly fits my hands. Emacs is a big part of my life.&lt;&#x2F;p&gt;
&lt;p&gt;I’m afraid it’s dying.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>The Social Dilemma</title>
        <published>2020-10-27T00:00:00+00:00</published>
        <updated>2020-10-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-10-27-social-dilemma/"/>
        <id>https://beta.lambdaland.org/posts/2020-10-27-social-dilemma/</id>
        
        <summary type="html">&lt;p&gt;I just finished watching &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.thesocialdilemma.com&#x2F;&quot;&gt;The Social Dilemma&lt;&#x2F;a&gt;, and here’s my hot take: &lt;em&gt;The Social Dilemma&lt;&#x2F;em&gt; is an emotive, accessible introduction to problems that, without exaggeration, pose an existential threat to life as we know it. If you can, watch it.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>The 11th</title>
        <published>2020-09-11T00:00:00+00:00</published>
        <updated>2020-09-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-09-11-september-11th/"/>
        <id>https://beta.lambdaland.org/posts/2020-09-11-september-11th/</id>
        
        <summary type="html">&lt;p&gt;Today is September 11th. I remember waking up 19 years ago, coming into the living room, and my dad getting down on one knee so he was closer to my level. He told me that earlier that morning two airplanes had crashed into some tall buildings in New York City. I didn’t know what that meant at the time, but I soon found out.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Quarantine in the 1600s</title>
        <published>2020-09-05T00:00:00+00:00</published>
        <updated>2020-09-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-09-05-quarantine-in-1600s/"/>
        <id>https://beta.lambdaland.org/posts/2020-09-05-quarantine-in-1600s/</id>
        
        <summary type="html">&lt;p&gt;It’s been a long six months that we’ve been under quarantine and other disease-limiting measures. It hasn’t been easy, but thanks to something I saw at &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;K%C3%B6nigstein_Fortress&quot;&gt;Königsstein Fortress&lt;&#x2F;a&gt; I’m not complaining. Here’s why:&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Book Review: Technopoly</title>
        <published>2020-08-26T00:00:00+00:00</published>
        <updated>2020-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-08-16-book-review-technopoly-v2/"/>
        <id>https://beta.lambdaland.org/posts/2020-08-16-book-review-technopoly-v2/</id>
        
        <summary type="html">&lt;!-- Introduction --&gt;
&lt;p&gt;In &lt;em&gt;Technopoly: The Surrender of Culture to Technology&lt;&#x2F;em&gt;, Neil Postman argues that our infatuation with technology has insidiously eroded our culture. We gain much through technology, but it comes at a price; all too often we are blind to that price. This book seeks to call attention to the costs of a technology-focused society. I felt this poignantly because I, as a technology worker, know what that infatuation feels like.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Thoughts on Goals in Programming Language Design</title>
        <published>2020-08-04T00:00:00+00:00</published>
        <updated>2020-08-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-08-04-thoughts-on-pl-design-goals/"/>
        <id>https://beta.lambdaland.org/posts/2020-08-04-thoughts-on-pl-design-goals/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2020-08-04-thoughts-on-pl-design-goals/">&lt;p&gt;+++&lt;&#x2F;p&gt;
&lt;p&gt;I’ve been thinking about programming languages a lot recently. A question I asked myself was: why do we work on, refine, and create new programming languages?&lt;&#x2F;p&gt;
&lt;p&gt;I thought of several reasons, but they seemed to boil down into two broader reasons:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Better abstractions and more automation:&lt;&#x2F;strong&gt; Some languages automate and ease some tedious tasks like memory management, concurrency, or type annotations. Almost all languages give you some ways of creating abstractions that let you reason with concepts in your problem domain, but different languages do this in different ways.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;More precisely describe what you want:&lt;&#x2F;strong&gt; Languages like Haskell let you describe the behavior of your program very precisely with an expressive type system. This lets you write &lt;em&gt;correct&lt;&#x2F;em&gt; programs with a high degree of confidence.&lt;&#x2F;p&gt;
&lt;p&gt;Other languages give you a different level of control: C lets you manipulate bits at arbitrary memory locations and evaluate them as you please. You can get very good performance from a well-tuned C program.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There’s some overlap between these domains for sure, but these goals often seem to conflict one another: the first objective seems optimal for &lt;em&gt;drafting&lt;&#x2F;em&gt; programs. The second group is more tuned for long-running projects or programs with specific constraints. Permissive languages like Perl, Ruby, and most Lisps seem designed with the first objective in mind and are very easy to use when exploring an idea. They can be expressive and concise. More demanding languages, like Rust or Haskell, seem optimized for a long-lived project or a program with intensive system resource constraints or performance requirements. Maybe some people can draft in Rust, but I find it more difficult to whip up something in Rust than Perl or Elixir.&lt;&#x2F;p&gt;
&lt;p&gt;Can we reconcile these two goals? Maybe. I think the further away you get away from the machine—trading some fine-grained control for abstraction—the closer the goals can converge. You can have a language well-suited for discovering an idea, which can then let you evolve your program into a more correct, reliable version.&lt;&#x2F;p&gt;
&lt;p&gt;In the end, I don’t think there is a perfect language. But some languages are more perfect than others! Hopefully I’ll strike on something interesting in my fumbling about with PL.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Transitioning to GUI&#x27;d Emacs on macOS</title>
        <published>2020-07-22T00:00:00+00:00</published>
        <updated>2020-07-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-07-22-gui-emacs/"/>
        <id>https://beta.lambdaland.org/posts/2020-07-22-gui-emacs/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2020-07-22-gui-emacs/">&lt;p&gt;I went on an adventure today. I left behind the stable comforts of the terminal and compiled bleeding-edge Emacs that uses a native window system.&lt;&#x2F;p&gt;
&lt;p&gt;This is a big deal for me. As long as I can remember, I’ve used Emacs from within a terminal. I’ve decided to give the GUI’d Emacs a whirl.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;my-journey&quot;&gt;My Journey&lt;&#x2F;h2&gt;
&lt;p&gt;I’m running macOS Catalina (10.15.5). Originally I tried using the pre-built packages via brew (&lt;code&gt;brew cask install emacs&lt;&#x2F;code&gt;) and those available at &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;emacsformacosx.com&quot;&gt;Emacs for Mac OS X&lt;&#x2F;a&gt;. However, all these pre-built binaries crashed on Catalina. I guess it’s a problem with Catalina. 🙄&lt;&#x2F;p&gt;
&lt;p&gt;So, I decided to try building from source. I cloned the Emacs source code directly from &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.savannah.gnu.org&#x2F;git&#x2F;emacs.git&quot;&gt;Savannah&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ git clone https:&#x2F;&#x2F;git.savannah.gnu.org&#x2F;git&#x2F;emacs.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I cd’d into that directory:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ cd emacs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point you’ve got the bleeding-edge development Emacs. You might want to check out and pull a different branch or tag. I decided to check out the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;emacs&#x2F;comments&#x2F;g9vdd0&#x2F;bringing_gnu_emacs_to_native_code_at_the_european&#x2F;&quot;&gt;native-compilation&lt;&#x2F;a&gt; branch:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ git checkout feature&#x2F;native-comp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ git pull origin feature&#x2F;native-comp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(I’m pretty sure those are the right commands; stuff got a little funky while I was building.)&lt;&#x2F;p&gt;
&lt;p&gt;I exported a magic&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; environment variable that I got from a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;emacs.stackexchange.com&#x2F;a&#x2F;54433&#x2F;19088&quot;&gt;helpful Emacs StackExchange post&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ export LIBXML2_CFLAGS=&amp;quot;-I&#x2F;Library&#x2F;Developer&#x2F;CommandLineTools&#x2F;SDKs&#x2F;MacOSX.sdk&#x2F;usr&#x2F;include&#x2F;libxml2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After exporting that variable, I ran &lt;code&gt;configure&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ .&#x2F;configure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then I ran &lt;code&gt;make&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That will create a binary at &lt;code&gt;src&#x2F;emacs&lt;&#x2F;code&gt; that you can run to test to make sure that all is working as it should. If you’re satisfied with that emacs configuration, you can bundle it up into a stand-alone application:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ make install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will create &lt;code&gt;Emacs.app&lt;&#x2F;code&gt; inside of the &lt;code&gt;nextstep&#x2F;&lt;&#x2F;code&gt; directory. You are free to move that around:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ mv nextstep&#x2F;Emacs.app &#x2F;Applications&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I also went into &lt;code&gt;System Preferences &amp;gt; Security&lt;&#x2F;code&gt; and gave Emacs Full Disk Access. I heard of some people having difficulty accessing iCloud files from Emacs and this cleared it up. I haven’t had any difficulty—I just wanted Emacs to have full access anyway.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;niceties&quot;&gt;Niceties&lt;&#x2F;h2&gt;
&lt;p&gt;I still use the terminal a &lt;em&gt;lot&lt;&#x2F;em&gt; (though I might use it less directly if I can get comfortable with &lt;code&gt;ansi-term&lt;&#x2F;code&gt; mode) so I made a few shortcuts for myself:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I symlinked &lt;code&gt;&#x2F;usr&#x2F;local&#x2F;bin&#x2F;emacs&lt;&#x2F;code&gt; to &lt;code&gt;&#x2F;Applications&#x2F;Emacs.app&#x2F;Contents&#x2F;MacOS&#x2F;Emacs&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; $ cd &#x2F;usr&#x2F;local&#x2F;bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; $ ln -s &#x2F;Applications&#x2F;Emacs.app&#x2F;Contents&#x2F;MacOS&#x2F;Emacs emacs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;&#x2F;usr&#x2F;local&#x2F;bin&lt;&#x2F;code&gt; is already in my &lt;code&gt;PATH&lt;&#x2F;code&gt;, so now I can just type &lt;code&gt;emacs&lt;&#x2F;code&gt; on the command line and it will fire it up just as it used to&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I created an alias like this in my &lt;code&gt;.zshrc&lt;&#x2F;code&gt; file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; alias &amp;#39;e&amp;#39;=&amp;#39;emacs -nw&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That way, when I’m in a terminal and type &lt;code&gt;e &amp;lt;filename&amp;gt;&lt;&#x2F;code&gt; it will open up the file in Emacs &lt;em&gt;in the terminal&lt;&#x2F;em&gt;. I might change that behavior at some point in the future, but that will help me transition for the time being.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I installed the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;purcell&#x2F;exec-path-from-shell&quot;&gt;exec-path-from-shell package&lt;&#x2F;a&gt; so that Emacs could fire off processes like &lt;code&gt;elixir&lt;&#x2F;code&gt; when using &lt;code&gt;lsp-mode&lt;&#x2F;code&gt;. Otherwise, you get errors like this inside the &lt;code&gt;*lsp::stderr*&lt;&#x2F;code&gt; buffer:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; line 66: exec: elixir: not found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Why did I do this? Because I was a little bored. I also wanted to experiment with some of the more extensive key binding opportunities that a full-bodied Emacs offers.&lt;&#x2F;p&gt;
&lt;p&gt;I’ll write updates to my blog as time goes on. I might decide to switch back to regular-old Emacs in the terminal. Right now, however, I’m enjoying the GUI’d version.&lt;&#x2F;p&gt;
&lt;p&gt;You can see my Emacs config on &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ashton314&#x2F;.dotfiles&quot;&gt;my GitHub&lt;&#x2F;a&gt;. Feel free to drop me a line if you have any questions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;update-2020-07-23&quot;&gt;UPDATE 2020-07-23&lt;&#x2F;h2&gt;
&lt;p&gt;After using Emacs 28.0.5 for a day, here’s what I came away with:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;No crashes. Things did start getting a little strange when I tried selecting text with the mouse in ansi-term without switching from character-mode to line-mode; I ended up killing that ansi-term session and creating a new one.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I really missed having frames all in the same place and switching between them with &lt;code&gt;C-x 5 o&lt;&#x2F;code&gt;. I found a &lt;em&gt;very&lt;&#x2F;em&gt; acceptable replacement; as of Emacs 27, you can enable the built-in &lt;code&gt;tab-bar-mode&lt;&#x2F;code&gt; and switch between “tabs” with &lt;code&gt;C-x t o&lt;&#x2F;code&gt;, create new ones with &lt;code&gt;C-x t 2&lt;&#x2F;code&gt;, etc. It looks just like switching between frames does in the terminal, minus the display of which tab you’re on. I haven’t figured out how to turn that on yet.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Using the tab-bar stuff, I created a tab and fired up ansi-term. I was able to switch back and forth between my editor tab and the console tab as I would between iTerm tabs or if I were using &lt;code&gt;C-z&lt;&#x2F;code&gt; to suspend.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Inputting special characters via the keyboard has changed. No longer can I hit &lt;code&gt;alt-shift--&lt;&#x2F;code&gt; to insert an em-dash. Instead, I turn on TeX mode input (&lt;code&gt;C-\ TeX RET&lt;&#x2F;code&gt;) and I can type the TeX character sequence (in the case of an em-dash, you just type a normal dash three times) and it will be inserted into the buffer.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In short, I’m finding this switch a decently comfortable one. I’m not giving up very much, and I’m gaining a decent amount. I’ve had some difficulty getting all the colors in the theme how I like them—I might just give up for a bit and see if I get used to them.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;I’m not entirely sure what it does. I know that it didn’t work before using this environment variable, and now it works after I tried using it. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Programming Languages and Typography</title>
        <published>2020-06-15T00:00:00+00:00</published>
        <updated>2020-06-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-06-15-languages-and-fonts/"/>
        <id>https://beta.lambdaland.org/posts/2020-06-15-languages-and-fonts/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2020-06-15-languages-and-fonts/">&lt;p&gt;An analogy occurred to me this evening as I was thinking about programming language design:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Choosing good keywords and function names is like picking a good font; the ideas conveyed may be the same, but a change can drastically impact legibility and enjoyment of use.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;PHP does a spectacular job of providing a &lt;em&gt;bad&lt;&#x2F;em&gt; example. It’s like the Comic Sans of programming languages. Now there are &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eev.ee&#x2F;blog&#x2F;2012&#x2F;04&#x2F;09&#x2F;php-a-fractal-of-bad-design&#x2F;&quot;&gt;many reasons why PHP is not a good language&lt;&#x2F;a&gt;—I’d like to investigate this particular aspect of its design here briefly.&lt;&#x2F;p&gt;
&lt;p&gt;There are ~55 &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.php.net&#x2F;manual&#x2F;en&#x2F;ref.array.php&quot;&gt;functions in PHP that start with &lt;code&gt;array_&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. Why? Why would you need to call the &lt;code&gt;map&lt;&#x2F;code&gt; operator &lt;code&gt;array_map&lt;&#x2F;code&gt;? Or &lt;code&gt;array_filter&lt;&#x2F;code&gt;, etc. Most other languages just call it &lt;code&gt;map&lt;&#x2F;code&gt; and leave it at that.&lt;&#x2F;p&gt;
&lt;p&gt;You might argue that that is a superficial difference: you are still doing the same thing so the expressive power of PHP is the same as whatever other languages you are comparing it to. I disagree. That extra clutter of the &lt;code&gt;array_&lt;&#x2F;code&gt; prefix &lt;em&gt;should not&lt;&#x2F;em&gt; be there and it’s purely clutter.&lt;&#x2F;p&gt;
&lt;p&gt;A bad font changes the tone and the perception of a body of text. Likewise, shoddy selection of keywords and names in a language changes it’s tone and feel.&lt;&#x2F;p&gt;
&lt;p&gt;Other examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Java&lt;&#x2F;li&gt;
&lt;li&gt;PHP’s &lt;code&gt;function&lt;&#x2F;code&gt; keyword and other similar atrocities&lt;&#x2F;li&gt;
&lt;li&gt;Common Lisp (the length of its function names are a shortcoming)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I’ll continue fleshing this iut more, but these are my thoughts at the present&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Book Review: Amusing Ourselves to Death</title>
        <published>2020-06-07T00:00:00+00:00</published>
        <updated>2020-06-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-06-07-amusing-ourselves-to-death/"/>
        <id>https://beta.lambdaland.org/posts/2020-06-07-amusing-ourselves-to-death/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2020-06-07-amusing-ourselves-to-death/">&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h1&gt;
&lt;p&gt;The primary thrust of this book is that television has degraded our mode
of public discourse. Our news, politics, education, and even religion
are delivered to us primarily through television, where they were once
delivered via the written word. This transformation of medium is not
irrelevant: just as poetry doesn’t survive fully intact when translated
from one language to another, likewise ideas do not survive translation
of medium.&lt;&#x2F;p&gt;
&lt;p&gt;This book was written in 1986. What foresight. If Postman was worried
about the effects that &lt;em&gt;television&lt;&#x2F;em&gt; was having on public discourse, he
would have been scared silly to see how much of our dialog is held
online on Facebook and Twitter, where all ideas are compressed into 140
to 280 characters and algorithms designed to optimize for consumer
engagement determine what rises to prominence and what does not. Thus
rational thought is drowned out—stamped out—by a deluge of content
that is shallow, simplistic, and sensational.&lt;&#x2F;p&gt;
&lt;p&gt;What follows are my notes that I wrote as I read the book, organized by
chapter. Do note that these notes are not meant to stand on their own;
if you have not read the book, they will likely seem disjoint.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;reading-notes&quot;&gt;Reading Notes&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;typographic-america-p-30&quot;&gt;Typographic America (p. 30)&lt;&#x2F;h2&gt;
&lt;p&gt;The typographical America read a lot.&lt;&#x2F;p&gt;
&lt;p&gt;The telegraph &lt;em&gt;commoditized&lt;&#x2F;em&gt; information: news was suddenly taken out of
context and held as valuable &lt;em&gt;per se&lt;&#x2F;em&gt;. &lt;em&gt;The question&lt;&#x2F;em&gt;: if something is
not relevant to my actions, can it still be valuable?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-peek-a-boo-world-p-64&quot;&gt;The Peek-a-Boo World (p.64)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;p. 69&lt;&#x2F;strong&gt;: Is the problem then in &lt;em&gt;unidirectional&lt;&#x2F;em&gt; means of
communication? We can’t reply and can’t really engage. We become passive
and the signal gets lost in the noise.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;now-this-p-99&quot;&gt;Now… This (p. 99)&lt;&#x2F;h2&gt;
&lt;p&gt;The idea here seems to be this: television has become the paradigm of
information transmittal. Because it strips things of context and things
are to be understood by themselves, contradictions fade. Magazines
follow suit: entertainment is news, and news must be entertaining.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shuffle-off-to-bethlehem-p-114&quot;&gt;Shuffle Off to Bethlehem (p. 114)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;p. 117&lt;&#x2F;strong&gt;: Prose survives translation between languages, whereas poetry
does not survive. Likewise, ideas do not survive changes in medium
unchanged. Television (and now mediums like Twitter, Instagram, etc.) do
great violence to ideas.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;p. 121&lt;&#x2F;strong&gt;: TV demands that what what be presented be &lt;em&gt;easy&lt;&#x2F;em&gt;. Elder
Maxwell’s talks are nice to watch, but move far too quickly and are way
more intricate than can be comfortably comprehended. There is some place
for easy: beginners to faith will have difficulty appreciating
everything about Elder Maxwell.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reach-out-and-elect-someone-p-125&quot;&gt;Reach Out and Elect Someone (p. 125)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;p. 128&lt;&#x2F;strong&gt;: Commercials are less about the character of the product and
mare more about the &lt;em&gt;character of the consumer&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reach-out-and-elect-someone-p-126&quot;&gt;Reach out and Elect Someone (p. 126)&lt;&#x2F;h2&gt;
&lt;p&gt;Capitalism works when the buyer and producer can both know what is good
and what is valuable. In sports, there are rules and standards that
cannot be muffled over; a basketball player who misses all his free
throws cannot weasel his way into being considered a “good player”.&lt;&#x2F;p&gt;
&lt;p&gt;Yet the virtues exposed by television are how &lt;strong&gt;entertaining&lt;&#x2F;strong&gt; something
is. It becomes “How good can a president look?” rather than “is this a
good man?” We see that quite strongly today.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;p. 135&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;As Xenophanes remarked twenty-five centuries ago, men always make
their gods in their own image. But to this, television politics has
added a new wrinkle: Those who would be gods refashion themselves into
images the viewers would have them be.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Is this what gets Trump supporters so fanatic—to the point where they
cannot see his contradictions? What image does he portray that they wish
they had?&lt;&#x2F;p&gt;
&lt;p&gt;One thing he projects is a disregard for the status quo. He’s also
fiercely tribal—people want an enemy they can scapegoat, and he leads
the charge against everyone and everything. People then feel like if
they’re on his team, they’re winning. What they think they’re
winning, I have no idea. But they seem to think that they are winning
&lt;em&gt;something&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;That’s kind of like a game show: a meaningless contest of luck,
strength, trivia recall, etc. which is filmed in a futuristic studio.
Everything is automatic and accompanied by jazzy music and flashing
lights. Game shows are strange things.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;p. 141&lt;&#x2F;strong&gt;: Television’s Censorship: television doesn’t &lt;em&gt;ban&lt;&#x2F;em&gt;
books—it displaces them, which is just as bad. I’ve wished for a
super power—not to be invisible, but that no one would be able to
focus their attention on me and pay attention to what I am doing. It
would be far easier to get away with stuff if no one noticed you than it
would be if you were merely invisible: floating objects catch people’s
attention rather quickly!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;p. 141&lt;&#x2F;strong&gt;: Collateral learning: what do you learn outside of the
content of the lesson? Helping students develop the right attitudes
towards learning is important and tricky.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;teaching-as-an-amusing-activity-p-142&quot;&gt;Teaching as an Amusing Activity (p. 142)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;p. 145&lt;&#x2F;strong&gt;: Television makes new conceptions of knowledge and how it is
acquired. The Internet has compounded this a thousand fold: google it,
tweet it, stream it on-demand, etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Masks</title>
        <published>2020-05-23T00:00:00+00:00</published>
        <updated>2020-05-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-05-23-masks/"/>
        <id>https://beta.lambdaland.org/posts/2020-05-23-masks/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2020-05-23-masks/">&lt;p&gt;Masks have become a hot issue. Here’s my 2¢.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;I think everyone &lt;em&gt;should&lt;&#x2F;em&gt; wear a mask, unless they have a compelling medical reason &lt;em&gt;not&lt;&#x2F;em&gt; to.&lt;&#x2F;p&gt;
&lt;p&gt;Look at it this way: a mask will either help you and those around you, or it will do no harm—beyond a little social awkwardness. If we look at the trade-offs in a game-theory-style matrix, we get:&lt;&#x2F;p&gt;
&lt;div align=&quot;center&quot; style=&quot;overflow-x:auto;&quot;&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: right&quot;&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Masks Help&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Masks don’t help&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;Wear a mask&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;+100&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;Don’t wear a mask&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;-100&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;There is &lt;em&gt;nothing&lt;&#x2F;em&gt; to loose by wearing a mask, while there is the possibility of loosing a whole lot if we &lt;em&gt;don’t&lt;&#x2F;em&gt;. There’s some &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fightcovid19.hku.hk&#x2F;hku-hamster-research-shows-masks-effective-in-preventing-covid-19-transmission&#x2F;&quot;&gt;preliminary research&lt;&#x2F;a&gt; showing that masks in fact help prevent transmission of COVID-19.&lt;&#x2F;p&gt;
&lt;p&gt;One way to think about wearing a mask is it’s like wearing a seat belt: seat belts save lives. Wearing seat belts is mandatory—rightly so!&lt;&#x2F;p&gt;
&lt;p&gt;But masks, unlike seat belts, not only help the wearer, but also protect others. True, cloth masks (home-made; surgical masks and N95 masks do much better of course) don’t seem to provide much protection for the &lt;em&gt;wearers&lt;&#x2F;em&gt;, but they do catch some non-negligible portion of the virus coming out of infected people. That one glob of saliva, if it lands right, could be the difference between life-and-death for someone else.&lt;&#x2F;p&gt;
&lt;p&gt;Wearing a mask shows respect and care for those around you. It shows solidarity: hundreds of thousands of people have died across the world—with over 100,000 in the US alone. We need to look out for each other.&lt;&#x2F;p&gt;
&lt;p&gt;Refusing to wear a mask is disrespectful. It’s more than just driving without a seat belt. It’s like driving drunk: &lt;em&gt;you&lt;&#x2F;em&gt; might be fine, but there are so many other people that you are endangering.&lt;&#x2F;p&gt;
&lt;p&gt;If you continue to not wear a mask just because you feel it restricts your freedom, then I think society is well within its rights to deny you access or services out of self-preservation: the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nbcnews.com&#x2F;news&#x2F;us-news&#x2F;woman-seen-licking-ice-cream-viral-video-faces-20-years-n1026556&quot;&gt;ice cream licker&lt;&#x2F;a&gt; faces prison time, and drunk drivers can have their licenses suspended.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, think about the &lt;em&gt;disrespect&lt;&#x2F;em&gt; and &lt;em&gt;selfishness&lt;&#x2F;em&gt; you show by not wearing a mask. In essence you are saying, “I cannot be bothered to put up with mild discomfort in order to potentially save people’s lives.”&lt;&#x2F;p&gt;
&lt;p&gt;If you think I’m wrong about something or that there’s something I ought to understand better, please reach out to me via my &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keybase.io&#x2F;ashton314&quot;&gt;Keybase&lt;&#x2F;a&gt;. (My email is also in my résumé if Keybase isn’t working for you.) I prefer rational, one-to-one discussion; unfortunately the medium of the Internet makes that difficult.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Computers and Abstractions</title>
        <published>2020-05-20T00:00:00+00:00</published>
        <updated>2020-05-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-05-20-computers-and-abstractions/"/>
        <id>https://beta.lambdaland.org/posts/2020-05-20-computers-and-abstractions/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2020-05-20-computers-and-abstractions/">&lt;p&gt;Computers are funny things. At the lowest level they’re just a pile of ones and zeros that we assign meaning to. It’s something you can easily take for granted, but there’s a disconnect with how we talk about how things operate at the hardware level and then again at the software level.&lt;&#x2F;p&gt;
&lt;p&gt;Since writing a compiler, I’ve been able to bridge that gap in part. The fundamental idea is that we represent some meaning in a concrete, though still high-level form. Example: we might represent an entry in a contact book with a struct.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defstruct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; age&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;font-weight: bold;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The critical step is this: we find a way to &lt;em&gt;consistently represent that entity in the physical realm&lt;&#x2F;em&gt;. We pack up a bunch of ones and zeros next to each other that are spaced apart at the right distances. Operations on bits in that neighborhood have to obey the rules we put in place. (E.g. treat the bits representing the age as a single thing, the bits representing the name can be broken up along character boundaries, etc.) Once our operations are complete, assuming our rules—our invariants—were never violated, then we can ascribe new meaning to the resulting mass of ones and zeros.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps this isn’t that profound. Or maybe it’s more profound than my attempt to talk about it shoes. I’m sure I’ll gain more insight about this phenomenon as time goes on.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Starting Fresh</title>
        <published>2020-05-09T00:00:00+00:00</published>
        <updated>2020-05-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-05-09-starting-fresh/"/>
        <id>https://beta.lambdaland.org/posts/2020-05-09-starting-fresh/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2020-05-09-starting-fresh/">&lt;p&gt;I’ve been building a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ashton314&#x2F;lambda-x86&quot;&gt;compiler&lt;&#x2F;a&gt; for a small lambda calculus that compiles to x86. It’s pretty broken, and I decided to start from scratch. I checked out a new branch in Git, and then &lt;strong&gt;deleted&lt;&#x2F;strong&gt; the entirety of my compiler before I had a chance to do anything else.&lt;&#x2F;p&gt;
&lt;p&gt;It hurt. But it was a good kind of hurt.&lt;&#x2F;p&gt;
&lt;p&gt;I don’t usually just blow everything away like that. Even this time, I’m keeping many of my auxiliary functions. I’m not rewriting the parser or some of my x86-helper routines. Those can stay.&lt;&#x2F;p&gt;
&lt;p&gt;I just wanted a blank slate. It’s nice having Git because I know I can always go back, but I’m not sure I will. I might glance back at my old branch occasionally, but by and large I’m starting fresh.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Fresh starts are important. I think one silver lining found among the clouds of this COVID-19 madness is that this is a chance to start fresh for so many people. Yes, it’s hard, and yes, there is lots of sadness, uncertainty, and grief. Take advantage of your life being paused and let this be a fresh start for &lt;em&gt;something&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;My wife is working on a writing habit. I’m working on developing research-oriented habits. I’m trying to read a paper every day—it’s not going &lt;em&gt;super&lt;&#x2F;em&gt; well, but I am improving!&lt;&#x2F;p&gt;
&lt;p&gt;It’s dark enough outside. Look for the silver lining and start fresh.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>FreeBSD on a Raspberry Pi</title>
        <published>2020-02-12T00:00:00+00:00</published>
        <updated>2020-02-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2020-02-12-freebsd-on-a-raspberry-pi/"/>
        <id>https://beta.lambdaland.org/posts/2020-02-12-freebsd-on-a-raspberry-pi/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2020-02-12-freebsd-on-a-raspberry-pi/">&lt;p&gt;+++&lt;&#x2F;p&gt;
&lt;p&gt;I’m a FreeBSD guy. My first computer was a FreeBSD machine that my dad had running in a closet. I learned how to use Emacs as well as the command line on that black-screen white-text no-mouse interface. That’s how real programmers spend their childhood! 😎 😜&lt;&#x2F;p&gt;
&lt;p&gt;I’ve only heard good things about FreeBSD. While not known as particularly desktop-friendly (various Linux distros win here) I’ve heard tales of its rock-solid stability. I wanted to try running on FreeBSD again, just to see what all the fuss was about.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installing&quot;&gt;Installing&lt;&#x2F;h1&gt;
&lt;p&gt;Installing was relatively straight forward. I followed the instructions
&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.freebsd.org&#x2F;action&#x2F;show&#x2F;arm&#x2F;Raspberry%20Pi?action=show&amp;amp;redirect=FreeBSD%2Farm%2FRaspberry+Pi&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Once I got the card flashed (took about an hour) and booted, I reset the
passwords for users &lt;code&gt;root&lt;&#x2F;code&gt; and &lt;code&gt;freebsd&lt;&#x2F;code&gt;. Note that at time of writing
WiFi wasn’t supported; I had to hard-link an Ethernet cable. It found
the connection without any trouble, so that was nice.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;initial-setup&quot;&gt;Initial Setup&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;setting-up-the-clock&quot;&gt;Setting up the clock&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freebsd.org&#x2F;doc&#x2F;handbook&#x2F;network-ntp.html&quot;&gt;https:&#x2F;&#x2F;www.freebsd.org&#x2F;doc&#x2F;handbook&#x2F;network-ntp.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The clock is necessary to start working with the ports. Set the config
variables in &lt;code&gt;&#x2F;etc&#x2F;rc.conf&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ntpd_enable=YES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ntpd_sync_on_start=YES  # This one might not be necessary&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You should be able to just run this without rebooting. (I ended up
rebooting, but I think I did things out of order.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;service&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; ntpd start&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;installing-the-port-tree&quot;&gt;Installing the port tree&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freebsd.org&#x2F;doc&#x2F;handbook&#x2F;ports-using.html&quot;&gt;https:&#x2F;&#x2F;www.freebsd.org&#x2F;doc&#x2F;handbook&#x2F;ports-using.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Run the following: (I think you can do this in any directory)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;portsnap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; fetch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;portsnap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; extract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;installing-the-critical-tools-emacs-and-git&quot;&gt;Installing the critical tools: Emacs and Git&lt;&#x2F;h1&gt;
&lt;p&gt;I tried going into &lt;code&gt;&#x2F;usr&#x2F;ports&#x2F;editors&#x2F;emacs&#x2F;&lt;&#x2F;code&gt; and running
&lt;code&gt;make install&lt;&#x2F;code&gt;, but I must have had an option wrong because it tried
installing… I think the entire X Windowing System. Yikes.&lt;&#x2F;p&gt;
&lt;p&gt;I gave up after about a day and instead ran &lt;code&gt;pkg install emacs-nox&lt;&#x2F;code&gt; and
&lt;code&gt;pkg install git&lt;&#x2F;code&gt;; those ran pretty quickly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Switching from Helm to Ivy</title>
        <published>2019-12-13T00:00:00+00:00</published>
        <updated>2019-12-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2019-12-13-switching-to-ivy-from-helm/"/>
        <id>https://beta.lambdaland.org/posts/2019-12-13-switching-to-ivy-from-helm/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2019-12-13-switching-to-ivy-from-helm/">&lt;p&gt;+++&lt;&#x2F;p&gt;
&lt;p&gt;Yet again, I’ve tweaked my &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ashton314&#x2F;.dotfiles&quot;&gt;emacs configuration&lt;&#x2F;a&gt;. The big change this time is switching to &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abo-abo&#x2F;swiper&quot;&gt;Ivy&lt;&#x2F;a&gt; from &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;emacs-helm.github.io&#x2F;helm&#x2F;&quot;&gt;Helm&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I’d like to say right off the bat that Helm is a great tool. I used it for several months and enjoyed it. Once thing that I love about helm is how discoverable it makes commands and functions. helm also got me into using bookmarks. I don’t keep many bookmarks; I tend to collect a few when working on a multi-file project long-term. The bookmark that I use most consistently is to my &lt;code&gt;.emacs&lt;&#x2F;code&gt; file; these days I’m fiddling constantly with my settings.&lt;&#x2F;p&gt;
&lt;p&gt;I switched to Ivy because I found its completion options to be &lt;em&gt;killer&lt;&#x2F;em&gt; when using &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;magit.vc&#x2F;&quot;&gt;Magit&lt;&#x2F;a&gt;: being able to fuzzy match branch names was sooo nice. I’ve also liked how Ivy handled completing file names. I &lt;em&gt;feel&lt;&#x2F;em&gt; faster. I’m not sure if I’m that much faster navigating around my file tree with it, but it does feel nice. There’s so much that Ivy makes better: any function using &lt;code&gt;completing-read&lt;&#x2F;code&gt; benefits from Ivy’s fuzzy matching.&lt;&#x2F;p&gt;
&lt;p&gt;It’s been a gradual process; there’s a lot that Helm does out-of-the-box that Ivy took some tweaking to get right. For example, sorting candidates for &lt;code&gt;M-x&lt;&#x2F;code&gt; by most recently used was one of my favorite features of Helm. I had to install &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;melpa.org&#x2F;#&#x2F;ivy-prescient&quot;&gt;Ivy Prescient&lt;&#x2F;a&gt; to get the behavior I wanted. On top of that, I needed &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abo-abo&#x2F;swiper#counsel&quot;&gt;Counsel&lt;&#x2F;a&gt; to show the key bindings next to their functions in &lt;code&gt;M-x&lt;&#x2F;code&gt;. Finally, I like to be able to fuzzy match anywhere within the command name, so I took out the leading &lt;code&gt;^&lt;&#x2F;code&gt; in counsel with this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span&gt; counsel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;ivy-configure &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;counsel-M-x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt;initial-input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Both Helm and Ivy are fantastic packages. They’ve changed the way I use Emacs and I feel like they’ve made me substantially more productive and happy. If you haven’t used either, you might want to start off with Helm for a nice out-of-the-box experience with loads of features and sensible defaults. However, if you just would like to be able to fuzzy-match things, Ivy is your library. It’s fast, clean, and configurable. The only problem is that it sometimes requires configuration before it’s exactly how you like it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Macros with Elixir</title>
        <published>2019-02-27T00:00:00+00:00</published>
        <updated>2019-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2019-02-27-macros-with-elixir/"/>
        <id>https://beta.lambdaland.org/posts/2019-02-27-macros-with-elixir/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2019-02-27-macros-with-elixir/">&lt;p&gt;I gave a presentation at the Utah Elixir Meetup this February. Here’s the recording of my presentation:&lt;&#x2F;p&gt;
&lt;figure class=&quot;kg-card kg-embed-card&quot;&gt;&lt;iframe width=&quot;480&quot; height=&quot;270&quot; src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;8gZP3oixr4A?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;&lt;figcaption&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=8gZP3oixr4A&quot;&gt;Watch on YouTube&lt;&#x2F;a&gt;&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;I’ve posted the slides as an HTML file, along with some materials to follow along with, on my &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ashton314&#x2F;elixir-macro-demo&quot;&gt;GitHub account&lt;&#x2F;a&gt;. Check it out!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Citations with Pandoc</title>
        <published>2019-02-06T00:00:00+00:00</published>
        <updated>2019-02-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2019-02-06-citations-with-pandoc/"/>
        <id>https://beta.lambdaland.org/posts/2019-02-06-citations-with-pandoc/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2019-02-06-citations-with-pandoc/">&lt;p&gt;+++&lt;&#x2F;p&gt;
&lt;p&gt;Today I figured out how to get &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pandoc.org&quot;&gt;Pandoc&lt;&#x2F;a&gt; to automatically generate MLA citations for me!&lt;&#x2F;p&gt;
&lt;p&gt;I used Pandoc and the Biblatex bibliography format. What’s nice about this is that you can enter in all the information you know about the source, keep it nice and organized in a file, and then change the citation style on the fly. Imagine if you thought you had to use MLA, but then realized you needed to switch to APA citation styles. You can do that instantly with Pandoc and Biblatex.&lt;&#x2F;p&gt;
&lt;p&gt;First, you’ll need &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pandoc.org&quot;&gt;pandoc&lt;&#x2F;a&gt; and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;hackage.haskell.org&#x2F;package&#x2F;pandoc-citeproc&quot;&gt;pandoc-citeproc&lt;&#x2F;a&gt;. (Instructions to install are on the Pandoc website. If you’re running macOS, you can use &lt;a href=&quot;https:&#x2F;&#x2F;beta.lambdaland.org&#x2F;posts&#x2F;2019-02-06-citations-with-pandoc&#x2F;brew.sh&quot;&gt;Homebrew&lt;&#x2F;a&gt; to install with &lt;code&gt;brew install pandoc&lt;&#x2F;code&gt; and &lt;code&gt;brew install pandoc-citeproc&lt;&#x2F;code&gt;.)&lt;&#x2F;p&gt;
&lt;p&gt;Next, create a bibliography file. Pandoc can work with many different formats, outlined &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pandoc.org&#x2F;MANUAL.html#citations&quot;&gt;in their documentation&lt;&#x2F;a&gt;, but I’ll show an example with Biblatex, the bibliography database format used with LaTeX.&lt;&#x2F;p&gt;
&lt;p&gt;Example markdown file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;title: Irresponsible Encryption&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;author: Ashton Wiersdorf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;date: \today&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bibliography: research&#x2F;refs.bib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;link-citations: true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cls: Modern Language Association 8th edition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Imagine a world where every phone call was tapped, where every purchase online could compromise your credit card, and where every one of your online accounts could be hacked. Imagine if every email you sent were scanned, analyzed, and the findings sold to the highest bidder. Imagine if your health, financial, and shopping records were public. That would be the end of our modern life as we know it. That is a real possiblity we are facing. (Especially if you use Gmail—Google has scanned the contents of emails in the past to serve targeted ads. [See @scroogled_blog]) Governments across the world—from the United States to Australia—are pushing or have passed legislation that mandates &amp;quot;exceptional access mechanisms&amp;quot;—means by which they can break encryption if they have a warrant to do so. They point to cases where criminals—from drug dealers to terrorists—have used encryption to conceal evidence against themselves. However, what they are asking for would have its consequences.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\pagebreak&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# References&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note how I have &lt;code&gt;bibliography: research&#x2F;refs.bib&lt;&#x2F;code&gt; at the top of the file. That lets Pandoc know where to go to find the biblography file. Then you can have a database file like this stored in &lt;code&gt;research&#x2F;refs.bib&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@online{scroogled_blog,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Annotation = {Ars Technica reports on this---the scary part is that Google was scanning emails in the first place.},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Author = {Diane Greene},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Crossref = {ars_scroogled},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Date = {2017-06-23},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Title = {As G Suite gains traction in the enterprise, G Suite&amp;#39;s Gmail and consumer Gmail to more closely align},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Url = {https:&#x2F;&#x2F;blog.google&#x2F;products&#x2F;gmail&#x2F;g-suite-gains-traction-in-the-enterprise-g-suites-gmail-and-consumer-gmail-to-more-closely-align&#x2F;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Urldate = {2019-02-05},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Bdsk-Url-1 = {https:&#x2F;&#x2F;blog.google&#x2F;products&#x2F;gmail&#x2F;g-suite-gains-traction-in-the-enterprise-g-suites-gmail-and-consumer-gmail-to-more-closely-align&#x2F;}}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@online{ars_scroogled,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Author = {Ron Amadeo},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Date = {2017-06-23},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Title = {Scroogled no more: Gmail won&amp;#39;t scan e-mails for ads personalization},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Url = {https:&#x2F;&#x2F;arstechnica.com&#x2F;gadgets&#x2F;2017&#x2F;06&#x2F;gmail-will-no-longer-scan-e-mails-for-ad-personalization&#x2F;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Urldate = {2019-02-05},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Bdsk-Url-1 = {https:&#x2F;&#x2F;arstechnica.com&#x2F;gadgets&#x2F;2017&#x2F;06&#x2F;gmail-will-no-longer-scan-e-mails-for-ad-personalization&#x2F;}}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each entry has a &lt;em&gt;cite key&lt;&#x2F;em&gt;: something that lets you refer to the citation from within your document. Note how in the markdown file I wrote &lt;code&gt;[See @scroogled_blog]&lt;&#x2F;code&gt;. That gets replaced with the following in the final product:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;…Google has scanned the contents of emails in the past to serve targeted ads. (See Greene 2017)…&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;And at the end of the paper, I get a nice-looking citation like this:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Greene, Diane. 2017. “As G Suite Gains Traction in the Enterprise, G Suite’s Gmail and Consumer Gmail to More Closely Align.” June 23, 2017. https:&#x2F;&#x2F;blog.google&#x2F;products&#x2F;gmail&#x2F;g-suite-gains-traction-in-the-enterprise-g-suites-gmail-and-consumer-gmail-to-more-closely-align&#x2F;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;To generate the finished product, I simply run &lt;code&gt;pandoc --filter pandoc-citeproc paper.md -o paper.pdf&lt;&#x2F;code&gt;. Poof! Nicely formatted and automatic citations!&lt;&#x2F;p&gt;
&lt;p&gt;To change the citation style, simply alter what is on the line starting with &lt;code&gt;cls:&lt;&#x2F;code&gt; in the header. You can find a list of valid styles &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.zotero.org&#x2F;styles&quot;&gt;here&lt;&#x2F;a&gt;, with more information &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;citationstyles.org&#x2F;authors&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;. Good luck with your papers!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Marked Man</title>
        <published>2019-01-24T00:00:00+00:00</published>
        <updated>2019-01-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2019-01-24-marked-man/"/>
        <id>https://beta.lambdaland.org/posts/2019-01-24-marked-man/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2019-01-24-marked-man/">&lt;p&gt;Marked Man (mm) is a little program I wrote to view Markdown files like UNIX man pages. (Because who wants to leave their terminal just to open a file?)&lt;&#x2F;p&gt;
&lt;p&gt;It uses &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pandoc.org&quot;&gt;Pandoc&lt;&#x2F;a&gt; to convert between Markdown and the &lt;code&gt;groff&lt;&#x2F;code&gt; format. As a happy side-effect, this program can read basically &lt;em&gt;anything&lt;&#x2F;em&gt; as a man page: HTML, LaTeX, Word files (seriously), ePub, etc. Anything that Pandoc can read, Marked Man can handle.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing&quot;&gt;Installing&lt;&#x2F;h2&gt;
&lt;p&gt;I’m working on getting this set up with &lt;a href=&quot;https:&#x2F;&#x2F;beta.lambdaland.org&#x2F;posts&#x2F;2019-01-24-marked-man&#x2F;brew.sh&quot;&gt;Homebrew&lt;&#x2F;a&gt;. For now, check out my GitHub repository &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ashton314&#x2F;homebrew-mm&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>DuckDuckGo</title>
        <published>2019-01-15T00:00:00+00:00</published>
        <updated>2019-01-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2019-01-15-duckduckgo/"/>
        <id>https://beta.lambdaland.org/posts/2019-01-15-duckduckgo/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2019-01-15-duckduckgo/">&lt;p&gt;DuckDuckGo is a search engine. Like Google Search, you just throw some keywords into a box and get a list of results. Lots of people use Google, but I don’t. DuckDuckGo works better for me, and this is why.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;consistent-results&quot;&gt;Consistent Results&lt;&#x2F;h1&gt;
&lt;p&gt;Did you know that Google will give you different search results, based on who you are and what you have searched for in the past? This is called a &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Filter_bubble&quot;&gt;filter bubble&lt;&#x2F;a&gt;, and it’s &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;spreadprivacy.com&#x2F;google-filter-bubble-study&#x2F;&quot;&gt;annoying and dangerous&lt;&#x2F;a&gt;. DuckDuckGo doesn’t put you in a filter bubble.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;goodies-and-tools&quot;&gt;Goodies and Tools&lt;&#x2F;h1&gt;
&lt;p&gt;Oh, man do I love the tools DuckDuckGo gives software developers. Here are just a few.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;software-development&quot;&gt;Software Development&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Need to find a color? Search “color picker”. A built-in color picker pops up.&lt;&#x2F;li&gt;
&lt;li&gt;Want to know the HTML character entity for, say, the interrobang? (‽) Type “HTML entity ‽”&lt;&#x2F;li&gt;
&lt;li&gt;Got some JSON that you need to prettify? Search “json validator” for a validator and beautifier.&lt;&#x2F;li&gt;
&lt;li&gt;Searching Stack Overflow, Mozilla Developer Network, etc. with Bangs! (more later)&lt;&#x2F;li&gt;
&lt;li&gt;Keybinding references for Emacs, Vim, Bash, etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;entertainment&quot;&gt;Entertainment&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Need to play 2048? Yes, just search “2048” and an in-browser game pops up.&lt;&#x2F;li&gt;
&lt;li&gt;Today’s XKCD (search “xkcd”)&lt;&#x2F;li&gt;
&lt;li&gt;Cheat sheets for Kerbal Space Program, Minecraft, League of Legends, etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;bangs&quot;&gt;Bangs&lt;&#x2F;h3&gt;
&lt;p&gt;Perform special operations by putting the appropriate !-sequence at the beginning of your search.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;!yt&lt;&#x2F;code&gt; Search YouTube (“!yt glitter bomb package”)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;!a&lt;&#x2F;code&gt; Search Amazon&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;!w&lt;&#x2F;code&gt; Search Wikipedia&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;!mdn&lt;&#x2F;code&gt; Search Mozilla Developer Network&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;!unsplash&lt;&#x2F;code&gt; Search Unsplash photos&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;!img&lt;&#x2F;code&gt; Search Google images—proxied for you so you can keep your privacy&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;!ldss&lt;&#x2F;code&gt; Search LDS Scriptures (just found this one 🤯&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are thousands. Literally.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;misc&quot;&gt;Misc.&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Generate Lorem Ipsum filler text by searching “lorem ipsum”&lt;&#x2F;li&gt;
&lt;li&gt;Check the weather with “weather &lt;code&gt;&amp;lt;zipcode&amp;gt;&#x2F;&amp;lt;city name&amp;gt;&lt;&#x2F;code&gt;”&lt;&#x2F;li&gt;
&lt;li&gt;Calculator with “calculator”&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For a full list of instant answers, see &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;duck.co&#x2F;ia&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For a full list of Bang-directives, see &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;duckduckgo.com&#x2F;bang&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It’s incredible. It’s simple. Perhaps best of all, ad-free! Well, they do display ads based on your search term for &lt;em&gt;just that search&lt;&#x2F;em&gt;. They don’t track you. The ads are not customized to &lt;em&gt;you&lt;&#x2F;em&gt;, rather they are customized to your &lt;em&gt;search&lt;&#x2F;em&gt;. They’re not intrusive either. I forgot they were there until I was typing this. 😄&lt;&#x2F;p&gt;
&lt;p&gt;But seriously. DuckDuckGo is amazing. Give it a try.&lt;&#x2F;p&gt;
&lt;p&gt;You can even enable it as your default search engine on iOS. Go to Settings &amp;gt; Safari &amp;gt; Search Engine and select DuckDuckGo. You can set it as well in Safari on desktop, as well as Firefox. (I don’t use Chrome or Edge, though I imagine they’d let you do the same. Comment below if you find anything out.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Organization Theory</title>
        <published>2019-01-05T00:00:00+00:00</published>
        <updated>2019-01-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2019-01-05-organization-theory/"/>
        <id>https://beta.lambdaland.org/posts/2019-01-05-organization-theory/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2019-01-05-organization-theory/">&lt;p&gt;Life is messy. We devote a lot of time and effort into managing that chaos. I thought of a little “theory”, if you will, that helps me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-home-theory&quot;&gt;The Home Theory&lt;&#x2F;h2&gt;
&lt;p&gt;Everything needs a home. The class of things that need homes is broad. It includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;School assignments&lt;&#x2F;li&gt;
&lt;li&gt;Legal documents&lt;&#x2F;li&gt;
&lt;li&gt;Pictures&lt;&#x2F;li&gt;
&lt;li&gt;Recipes&lt;&#x2F;li&gt;
&lt;li&gt;Ideas&lt;&#x2F;li&gt;
&lt;li&gt;Projects&lt;&#x2F;li&gt;
&lt;li&gt;Books&lt;&#x2F;li&gt;
&lt;li&gt;Charging cables&lt;&#x2F;li&gt;
&lt;li&gt;Tools&lt;&#x2F;li&gt;
&lt;li&gt;etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The home needs to suit the thing that goes there. I have found that getting this right is really tricky. But once you have a home for a thing, you never loose it. You will want to put things back into their homes when you are done using it, because it will &lt;em&gt;feel&lt;&#x2F;em&gt; right. If the home doesn’t fit the item, you run into a bit of friction—that slows you down and makes you more likely to put the thing where it’s easy.&lt;&#x2F;p&gt;
&lt;p&gt;One thing that stood out to me from &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zen_and_the_Art_of_Motorcycle_Maintenance&quot;&gt;Zen and the Art of Motorcycle Maintenance&lt;&#x2F;a&gt; was the author’s discussion about tools. Regarding tool organization:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;One of the first warning signs of impatience is frustration at not being able to lay your hand on the tool you need right away. If you just stop and put tools away neatly you will both find the tool and also scale down your impatience without wasting time or endangering the work. (pp. 286)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I mentioned this a bit when I talked about &lt;a href=&quot;&#x2F;posts&#x2F;2018-12-06-editor-apology.html&quot;&gt;text editors&lt;&#x2F;a&gt;, but this holds true for more things than physical or software tools. Consider a home for finances: if you have a budgeting program you &lt;em&gt;always&lt;&#x2F;em&gt; use, then it’s much easier to keep track of your finances because records of transactions have a home to go to.&lt;&#x2F;p&gt;
&lt;p&gt;The investment of time is worth it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;symptoms-of-no-home&quot;&gt;Symptoms of No Home&lt;&#x2F;h2&gt;
&lt;p&gt;I once didn’t have a home for a while. I mean, I lived in a house and was provided with more than adequate food, shelter, clothing, etc. However, I didn’t have a room. We were renovating our basement to make more space, and until that was complete, I slept on an air mattress.&lt;&#x2F;p&gt;
&lt;p&gt;The air mattress was no problem. I was young enough that it didn’t hurt my back. (I can’t believe that I’m suddenly “old” and reposing on a mattress hurts my back!) The biggest struggle for me is that I didn’t have a home for my stuff, and I didn’t have a place where I could go to be quiet.&lt;&#x2F;p&gt;
&lt;p&gt;I’m quite introverted. That means after spending time with people, I need quiet time to relax and recharge. I didn’t get that. The barrage of noise I experience in that time made it difficult for me at times.&lt;&#x2F;p&gt;
&lt;p&gt;I’m grateful that I have a home now. It’s important. It’s important for things and people to have a home.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Semester Finished</title>
        <published>2018-12-14T00:00:00+00:00</published>
        <updated>2018-12-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2018-12-14-semester-finished/"/>
        <id>https://beta.lambdaland.org/posts/2018-12-14-semester-finished/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2018-12-14-semester-finished/">&lt;p&gt;I finished the semester! This is how I feel:&lt;&#x2F;p&gt;
&lt;figure class=&quot;kg-card kg-embed-card&quot;&gt;&lt;iframe width=&quot;480&quot; height=&quot;270&quot; src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;QUAItQmq-LU?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Don’t you?&lt;&#x2F;p&gt;
&lt;p&gt;Well, I still have finals. But those are easy compared to the projects I’ve had to push out. I’ll probably write about my escapades later. :)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Editors, or The Tools of my Trade</title>
        <published>2018-12-06T00:00:00+00:00</published>
        <updated>2018-12-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2018-12-06-editor-apology/"/>
        <id>https://beta.lambdaland.org/posts/2018-12-06-editor-apology/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2018-12-06-editor-apology/">&lt;p&gt;I spend a fair portion of every day writing programs. As with all professions, using the right tools makes a huge difference in my productivity and general happiness. Having good tools helps me keep my gumption up.&lt;&#x2F;p&gt;
&lt;p&gt;One of my favorite books is &lt;em&gt;Zen and the Art of Motorcycle Maintenance&lt;&#x2F;em&gt;. Contrary to what the title suggests, this book is actually not about motorcycles. It’s about a lot of things; one topic is about tools and caring about your trade.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;… By far the most frustrating gumption trap is inadequate tools. Nothing’s quite so demoralizing as a tool hang-up. Buy good tools as you can afford them and you’ll never regret it.‌‌ (ibid. p.g. 291)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;For me, my most important tool is my text editor: manipulating source code is what I spend ALL DAY doing. I’ve selected &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.m.wikipedia.org&#x2F;wiki&#x2F;Emacs&quot;&gt;Emacs&lt;&#x2F;a&gt; as my primary text editor.&lt;&#x2F;p&gt;
&lt;p&gt;Lots of programmers use what’s called an &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.m.wikipedia.org&#x2F;wiki&#x2F;Integrated_development_environment&quot;&gt;IDE&lt;&#x2F;a&gt; If programming were cooking, then an IDE would be a knife that has a sink, a strainer, and a toaster-oven built into it.&lt;&#x2F;p&gt;
&lt;p&gt;I find IDE’s visually distracting. Everything is done with buttons that you click. Emacs has so much more screen devoted to content.&lt;&#x2F;p&gt;
&lt;p&gt;Emacs and Vim &lt;em&gt;do&lt;&#x2F;em&gt; have steeper learning curves. This is in part because the absence buttons make the features only discoverable via manuals. When working with an IDE, the presense of buttons hints at the existence of certain features.&lt;&#x2F;p&gt;
&lt;p&gt;I find it a shame when people don’t read, prefering a video tutorial or the like. Emacs’s features are very discoverable, but not in the way most people are used to. The &lt;code&gt;apropos-function&lt;&#x2F;code&gt; command is terribly useful—if you think a certain command &lt;em&gt;should&lt;&#x2F;em&gt; exist, searching all available function names for a particular string has helped me find both what I’ve gone looking for, and what I didn’t know I wanted!&lt;&#x2F;p&gt;
&lt;p&gt;The advantage to using keyboard only navigation is that hundreds of commands are immediately available all the time, without having to dig through menus or such. It takes me the same amount of time to access complicated commands as it does moving around a file.&lt;&#x2F;p&gt;
&lt;p&gt;Again, from &lt;em&gt;Zen and the Art of Motorcycle&lt;&#x2F;em&gt; &lt;em&gt;Maintenance:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;…One of the first warning signs of impatience is frustration at not being able to lay your hand on the tool you need right away.‌‌ (ibid. p.g. 286)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Moving a mouse takes me out of my flow, which slows me down and leads to gumption traps. If something takes longer, I’m more reluctant to do it. That means my productivity drops.&lt;&#x2F;p&gt;
&lt;div class=&quot;asterism&quot;&gt;
⁂
&lt;&#x2F;div&gt;
&lt;p&gt;Now, you might have used a word processor for text editing all your life. Or perhaps you’re comfortable with your IDE. I encourage you to stretch beyond what you’re comfortable with, and learn Emacs. An investment in a powerful text editor will change how you consider how you program. Editing will become more fluid, and the barrier of buttons and menus will fade away.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;learning-emacs&quot;&gt;Learning Emacs&lt;&#x2F;h2&gt;
&lt;p&gt;There is an index of learning resources &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.emacswiki.org&#x2F;emacs&#x2F;LearningEmacs&quot;&gt;here&lt;&#x2F;a&gt;. If you’re just looking for a cheat sheet, check &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.emacswiki.org&#x2F;emacs&#x2F;EmacsCrashCourse&quot;&gt;this link&lt;&#x2F;a&gt; out. Also, see &lt;a href=&quot;&#x2F;posts&#x2F;2017-09-23-emacs-tips-and-tricks&#x2F;&quot;&gt;my cheat sheet&lt;&#x2F;a&gt;. (I update this one occasionally.)&lt;&#x2F;p&gt;
&lt;p&gt;If you’re coming from an IDE and miss feature X, you might be able to find the corresponding Emacs feature &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.emacswiki.org&#x2F;emacs&#x2F;EmacsForDevStudioUsers&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;picture-credit&quot;&gt;Picture Credit&lt;&#x2F;h2&gt;
&lt;p&gt;I found this via a Google Image search; the origional file came from &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;batsov.com&#x2F;articles&#x2F;2011&#x2F;11&#x2F;11&#x2F;blogging-like-a-hacker-evolution&#x2F;&quot;&gt;this blog post&lt;&#x2F;a&gt;, which I think resonates with mine quite well.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Induction and Side-Effects</title>
        <published>2018-10-08T00:00:00+00:00</published>
        <updated>2018-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2018-10-08-induction-and-side-effects/"/>
        <id>https://beta.lambdaland.org/posts/2018-10-08-induction-and-side-effects/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2018-10-08-induction-and-side-effects/">&lt;p&gt;Today in my proofs class (MATH 290 at BYU) we talked about the concept &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mathematical_induction&quot;&gt;induction&lt;&#x2F;a&gt;. I like this, because it sounds a lot like recursion.&lt;&#x2F;p&gt;
&lt;p&gt;On the Wikipedia article, there’s an excerpt from a book that illustrates the principle with an analogy using a ladder:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Mathematical induction proves that we can climb as high as we like on a ladder, by proving that we can climb onto the bottom rung (the basis) and that from each rung we can climb up to the next one (the step).&lt;br &#x2F;&gt;
— &lt;em&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Concrete_Mathematics&quot;&gt;Concrete Mathematics&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;, page 3 margins&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The problem with this, however, is that climbing a ladder has side-effects! Namely, when you climb up a step, you get tired. Eventually, there comes a point where you get so tired that you collapse from exhaustion, fall off the ladder and smack into the hard, uncaring ground of reality below.&lt;&#x2F;p&gt;
&lt;p&gt;This will happen to you too if your recursive functions have side effects: you code will be &lt;em&gt;really&lt;&#x2F;em&gt; hard to debug, and eventually, a bug somewhere in the state of your system will deftly shove your process off the call stack to crash on the cold, hard, uncaring silicon below.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Life Hacks: Text Notifications</title>
        <published>2018-08-11T00:00:00+00:00</published>
        <updated>2018-08-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2018-08-11-life-hacks-text-notifications/"/>
        <id>https://beta.lambdaland.org/posts/2018-08-11-life-hacks-text-notifications/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2018-08-11-life-hacks-text-notifications/">&lt;h2 id=&quot;life-hacks-text-notifications&quot;&gt;Life Hacks: Text Notifications&lt;&#x2F;h2&gt;
&lt;p&gt;So many notifications come to us in the form of an audible alert, and this can sometimes be inconvenient. Who likes having their phone go off in church? The problem is that sound propagates regardless of the intended target. Touch, on the other hand, is an inherently personal sensation. Setting your phone to vibrate lets you know you’re being alerted, without notifying everyone else in the room as well.&lt;&#x2F;p&gt;
&lt;p&gt;Unless you read Braille, touch has far less bandwidth than sound. However, you can pack a small amount of information into a vibration, like who’s calling or texting you. There’s a sweet feature on iPhones that lets you set custom vibration patterns for your contacts. Here’s how to set it up:&lt;&#x2F;p&gt;
&lt;p&gt;Go to your “Contacts” app. I’ve got a version of my personal contact card that I AirDrop to people when they want my contact information. I’ll use that to demonstrate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;content&#x2F;images&#x2F;2018&#x2F;08&#x2F;IMG_4858.jpg&quot; alt=&quot;My contact card&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Hit &lt;code&gt;Edit&lt;&#x2F;code&gt; in the top right corner, then scroll down until you see &lt;code&gt;Text Tone&lt;&#x2F;code&gt;. Click on that.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;content&#x2F;images&#x2F;2018&#x2F;08&#x2F;IMG_4859.jpg&quot; alt=&quot;The contact edit screen&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You’ll see a bunch of options where you can set a custom ringtone for that person. You can &lt;em&gt;also&lt;&#x2F;em&gt; set a custom vibration pattern. Right now, mine is set to “Default”. Go ahead an click on that.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;content&#x2F;images&#x2F;2018&#x2F;08&#x2F;IMG_4860.jpg&quot; alt=&quot;Vibration edit screen&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are a bunch of standard patterns you can choose from. You can also create some custom ones! I have a lot of custom vibrations:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;content&#x2F;images&#x2F;2018&#x2F;08&#x2F;IMG_4864.jpg&quot; alt=&quot;My custom vibrations&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Down at the very bottom of the list is an option to create a new one. Tapping on that will give you a screen like this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;content&#x2F;images&#x2F;2018&#x2F;08&#x2F;IMG_4862.jpg&quot; alt=&quot;Screenshot of new vibration editor&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is what setting a new vibration pattern looks like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;content&#x2F;images&#x2F;2018&#x2F;08&#x2F;IMG_4863.jpg&quot; alt=&quot;Creating a new vibration in progress&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I encode the initials of my most frequent contacts in &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Morse_code&quot;&gt;Morse Code&lt;&#x2F;a&gt;. It lets me know who’s texting me without having to take my phone out of my pocket. It helps me know if I should answer immediately, or if the conversation can wait for a minute or two. It took me a week or two to be able to distinguish between the texts, but now I can recognize who is texting or calling me immediately!&lt;&#x2F;p&gt;
&lt;p&gt;Does anyone know if Android supports the same? Let me know, and I’ll post about that here.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note to people from Facebook: I won’t know if you tell me via one of the contact methods I talked about &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ashton.wiersdorf.org&#x2F;2018&#x2F;06&#x2F;23&#x2F;leaving-facebook&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Leaving Facebook</title>
        <published>2018-06-23T00:00:00+00:00</published>
        <updated>2018-06-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2018-06-23-leaving-facebook/"/>
        <id>https://beta.lambdaland.org/posts/2018-06-23-leaving-facebook/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2018-06-23-leaving-facebook/">&lt;p&gt;&lt;em&gt;Deutsche Übersetzung folgt.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I’ve left* Facebook.&lt;&#x2F;p&gt;
&lt;p&gt;There’s an asterisk there. I’m not going to delete my account, but I’m no longer checking Facebook more than once or twice a month, if that. I’m not trying to be a recluse—below are a few ways to contact me that I &lt;em&gt;do&lt;&#x2F;em&gt; check far more often than Facebook. I want to be your friend, but I’d rather that friendship be through a real connection rather than some online “status”.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-i-m-leaving&quot;&gt;Why I’m Leaving&lt;&#x2F;h2&gt;
&lt;p&gt;First of all, I care deeply about my online privacy. I’m not perfect, but I try to keep myself free from trackers so I can decide what I see online instead of &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stratechery.com&#x2F;2018&#x2F;the-bill-gates-line&#x2F;&quot;&gt;aggregators like Facebook and Google&lt;&#x2F;a&gt;. Facebook is out to get you and your contact information. I don’t like it.&lt;&#x2F;p&gt;
&lt;p&gt;Secondly, I don’t like Facebook’s closed model of the Internet—they make it so search engines can’t find even public Facebook posts. Their model not what I want for anything I choose to share with the world—this blog is much better. Additionally, with my blog, I have a much richer medium for publishing my thoughts and writing.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, I don’t think Facebook merits a daily scroll-through. The information that I care about I find in other news sources and online in manuals. For entertainment, I usually read books or play a game on my phone. Reading about the minutia of people’s lives is not interesting to me.&lt;&#x2F;p&gt;
&lt;p&gt;That being said…&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-m-still-keeping-my-account&quot;&gt;I’m still keeping my account&lt;&#x2F;h2&gt;
&lt;p&gt;Why? Because all you guys use it, and I want to know when you get married, have a baby, when there’s a mission reunion, etc. I would &lt;em&gt;really&lt;&#x2F;em&gt; prefer to learn about these things via some other medium, but until we all migrate to &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keybase.io&quot;&gt;Keybase&lt;&#x2F;a&gt; or something, I’m going to keep one eye on what my friends like to publish on Facebook. Even then, I’ll still likely miss many things. ¯\_(ツ)_&#x2F;¯&lt;&#x2F;p&gt;
&lt;p&gt;I’ll also link to my blog posts. There’s stuff I’d like to share with you guys, and this is the way I’d like to do it. It gives me a richer medium to communicate. Furthermore, writing a blog post is more arduous than writing something on Facebook—if I write something, it means I will have found it sufficiently important to spend some time on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-contact-me&quot;&gt;How to contact me&lt;&#x2F;h2&gt;
&lt;p&gt;A few options to contact me:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Email—&lt;em&gt;my first name&lt;&#x2F;em&gt; dot &lt;em&gt;then my last name&lt;&#x2F;em&gt; at mailblock dot net.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; That’s probably the easiest.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keybase.io&#x2F;ashton314&quot;&gt;Keybase&lt;&#x2F;a&gt;—it’s a free messaging&#x2F;file sharing app. My Keybase ID is &lt;code&gt;ashton314&lt;&#x2F;code&gt;. I prefer this method: it’s secure and private.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ashton314&quot;&gt;GitHub&lt;&#x2F;a&gt;—really only if it’s about code.&lt;&#x2F;li&gt;
&lt;li&gt;Friends—find someone who has my number and ask them for it. Please don’t send it over Facebook Messenger, though.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;I’ve already been pretty sparing in my Facebook interactions. This post is just to let you know why I might have missed an announcement or two. :) It’s nothing personal—I’m just not on Facebook very often.&lt;&#x2F;p&gt;
&lt;div class=&quot;asterism&quot;&gt;
⁂
&lt;&#x2F;div&gt;
&lt;h1 id=&quot;deutsch&quot;&gt;Deutsch&lt;&#x2F;h1&gt;
&lt;p&gt;Ich habe Facebook verlassen.*&lt;&#x2F;p&gt;
&lt;p&gt;Es gibt noch einige Bedingungen, aber! Ich werde zwar meine Konto nicht löschen, aber ich gehe auf Facebook ziemlich selten—höchstens ein oder zwei Mal im Monat. Ich bin kein Einsiedler; ich will einfach ich auf eine persönlicher Ebene ein Freund sein. Mir ist es Egal ob wir ins Internet als “Freunden” bezeichnet werden.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;warum-ich-facebook-verlasse&quot;&gt;Warum ich Facebook verlasse&lt;&#x2F;h2&gt;
&lt;p&gt;Erstens, mir ist meine Privatsphäre sehr wichtig. Ich will es nicht, dass Facebook meine Taten ins Internet folgt. Ich habe zwar nichts zu verbergen. Das heißt aber nicht, dass Facebook meine jegliche Tat wissen soll.&lt;&#x2F;p&gt;
&lt;p&gt;Zweitens, ich mag wie Facebook das Internet verwendet gar nicht. Wenn ich etwas auf Facebook schreibe, können Such-machine es nicht finden. Wenn ich ein Link zu etwas erstellen will, macht Facebook das unsicher. Es kann sein, dass wenn jemand etwas postet, kann ich es sehen, aber du nicht.&lt;&#x2F;p&gt;
&lt;p&gt;Zum Schluss, ich glaube es nicht, dass ich täglich auf Facebook gehen soll. Mir ist es wichtiger andere Sachen zu lesen, statt dass, was Facebook mir gibt.&lt;&#x2F;p&gt;
&lt;p&gt;Jedoch…&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ich-losche-mein-konto-nicht&quot;&gt;Ich lösche mein Konto nicht.&lt;&#x2F;h2&gt;
&lt;p&gt;Der Grund dafür ist einfach: ihr seid alle noch auf Facebook. Ich freue mich wann ich von ihre schöne Lebenserfahrungen höre. Ich möchte es wissen, wann ihr heiraten, ein Baby bekommen, wenn es ein Missionstreffen gibt, usw. Ich höre es liber durch ein anderes Mittel als Facebook, aber bis wir alle auf &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keybase.io&quot;&gt;Keybase&lt;&#x2F;a&gt; sind, werde ich noch ein Facebook Konto behalten. Ich werde aber viele Dinge verpassen. Bitte wissen, dass es nicht persönlich gemeint ist: wir sind noch Freunden, ich gehe einfach ganz ganz selten auf Facebook.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wie-man-mich-kontaktieren-kann&quot;&gt;Wie man mich kontaktieren kann&lt;&#x2F;h2&gt;
&lt;p&gt;Es gibt einige Möglichkeiten:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Email—&lt;em&gt;mein erster Name&lt;&#x2F;em&gt; Punkt &lt;em&gt;mein letzter Name&lt;&#x2F;em&gt; at mailblock Punkt net.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Das ist wahrscheinlich am einfachsten.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keybase.io&#x2F;ashton314&quot;&gt;Keybase&lt;&#x2F;a&gt;—es ist eine Kostenlose Nachricht und Filesharing App. Mein Keybase ID ist &lt;code&gt;ashton314&lt;&#x2F;code&gt;. Mir ist diese Methode am besten: es ist sicher und privat.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ashton314&quot;&gt;GitHub&lt;&#x2F;a&gt;—wirklich ist das nur wenn es um Code geht.&lt;&#x2F;li&gt;
&lt;li&gt;Friends—find einfach jemand, der mein Handynummer schon hat.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;zum-schluss&quot;&gt;Zum Schluß&lt;&#x2F;h2&gt;
&lt;p&gt;Ich bin schon ganz selten bei Facebook. Ich hoffe, dass ihr es versteht, dass wenn ich vielleicht etwas wichtiges verpasst habe, war es gar nicht persönlich gemeint—ich bin halt fast niemals auf Facebook.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;I’m not writing that in normal form because I don’t want a web scraper to find it and spam me. Yuck. I like it when search engines find my blog posts. I don’t like it when they find my email address. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;Ich hab mein Emailaddresse so geschrieben, damit ich kein Spam bekommen werde. Ich mag es, wenn das Internet mein Post sieht. Ich mag es nicht, wenn schlechte Programmen mein Emailaddresse finden. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Drafting</title>
        <published>2017-11-18T00:00:00+00:00</published>
        <updated>2017-11-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2017-11-18-drafting/"/>
        <id>https://beta.lambdaland.org/posts/2017-11-18-drafting/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2017-11-18-drafting/">&lt;p&gt;I once asked my dad over email how to improve my the potency of my words and thoughts. His reply came back as one word:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Revision.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Good writing does not emerge spontaneously; it comes as one practices writing. A “draft” is a pass of writing a particular work. It’s like sketching in art: when an artist starts a painting, they usually start with a rough sketch outlining where the ﬁgures will be, what the landscape will be like, etc. These sketches are composed of many lines: each coming closer to their ﬁnal position.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.leonardodavinci.net&#x2F;images&#x2F;drawings&#x2F;rearing-horse.jpg&quot; alt=&quot;Rearing Horse by Leonardo da Vinci&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When I draft, I start out with a few different freewrites. I usually start with a stream of consciousness to get my ideas out on paper and to sort of flesh out what I actually want to talk about. Then I will beat out a very rough draft. After this initial draft, I usually will have a good idea of how I want to treat the subject matter. I will do things like read my paper aloud to hear how it flows, check for grammatical inconsistencies, look for more concise phrases that convey my ideas more clearly. Occasionally I will decide that I need to change how I structure my argument entirely. In these situations I will often do a complete rewrite.&lt;&#x2F;p&gt;
&lt;p&gt;I usually use something akin to &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Software_versioning#Degree_of_compatibility&quot;&gt;semantic versioning&lt;&#x2F;a&gt;—the first version number of my draft indicates the major write of the paper, (e.g. 0.0.1 for the rough draft, 1.0.0 for the first full draft after the rough draft, 2.0.0 for the next full rewrite, etc.) the second number might indicate significant changes in the text, but not complete structural changes, and the third number indicates minor changes, such as spelling and grammar errors.&lt;&#x2F;p&gt;
&lt;p&gt;I don’t follow this system too rigorously; it’s just a kind of fun thing I use to keep track of my drafts. My brain is messy some times, and I’m okay with that.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rapid Website Development with Mojolicious and Polymer</title>
        <published>2017-11-09T00:00:00+00:00</published>
        <updated>2017-11-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2017-11-09-quick-website-programming-with-mojolicious-and-polymer/"/>
        <id>https://beta.lambdaland.org/posts/2017-11-09-quick-website-programming-with-mojolicious-and-polymer/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2017-11-09-quick-website-programming-with-mojolicious-and-polymer/">&lt;p&gt;My girlfriend works for BYU SA—it’s the division of BYU that’s responsible for planning and running events. As part of her job, she has to review song lyrics and make sure that the song is okay to play at BYU functions.&lt;&#x2F;p&gt;
&lt;p&gt;This can get rather irksome. Imagine reading text &lt;em&gt;looking&lt;&#x2F;em&gt; for vulgar words or phrases. Yuck. I took some time this evening to write a little website that checks &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;metrolyrics.com&quot;&gt;MetroLyrics&lt;&#x2F;a&gt; for any vulgar words or phrases. I have an extensible blacklist which gets initialized at server start by some phrases from &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.frontgatemedia.com&#x2F;a-list-of-723-bad-words-to-blacklist-and-how-to-use-facebooks-moderation-tool&#x2F;&quot;&gt;FrontGate&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I coded this up with &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;mojolicious.org&quot;&gt;Mojolicious&lt;&#x2F;a&gt; and &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.polymer-project.org&quot;&gt;Polymer Web Components&lt;&#x2F;a&gt;. Polymer might have been a little overkill, but it saved me from writing lots of boring jQuery to set variable.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s what the site looks like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;content&#x2F;images&#x2F;2017&#x2F;11&#x2F;Screen-Shot-2017-11-08-at-11.12.02-PM.png&quot; alt=&quot;Sing Clearly&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can look at the code for the repository &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ashton314&#x2F;sing_clearly&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This all took about 3 hours, the last of which was spent mostly getting some of the finer points of the user interface to work.&lt;&#x2F;p&gt;
&lt;p&gt;I’d be happy to get some contributions to my project, if anyone is feeling a little bored. ;-) Some more robust song searching would be nice, as well as better heuristics for bad phrases and whatnot.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Eh, Docker, we have a problem here…</title>
        <published>2017-10-26T00:00:00+00:00</published>
        <updated>2017-10-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2017-10-26-eh-blog-we-have-a-problem-here/"/>
        <id>https://beta.lambdaland.org/posts/2017-10-26-eh-blog-we-have-a-problem-here/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2017-10-26-eh-blog-we-have-a-problem-here/">&lt;p&gt;&lt;em&gt;Quick note for those who don’t know about Docker:&lt;&#x2F;em&gt; &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.docker.com&#x2F;what-docker&quot;&gt;Docker&lt;&#x2F;a&gt; is a program that lets me take packaged-up programs (called &lt;em&gt;images&lt;&#x2F;em&gt; or &lt;em&gt;containers&lt;&#x2F;em&gt;) and run them without having to worry much about dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;Today I decided to upgrade my version of &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ghost.org&#x2F;&quot;&gt;Ghost Blog&lt;&#x2F;a&gt;. I’m using the &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;_&#x2F;ghost&#x2F;&quot;&gt;Docker image&lt;&#x2F;a&gt; on a Digital Ocean droplet. Updating should be simple, I thought. I would take down the blog then spin it back up again after pulling down the latest Docker image. I ran &lt;code&gt;docker stop ghost-blog&lt;&#x2F;code&gt;, removed the container with &lt;code&gt;docker rm ghost-blog&lt;&#x2F;code&gt; then ran &lt;code&gt;docker pull ghost:latest&lt;&#x2F;code&gt;. The container came down without a problem.&lt;&#x2F;p&gt;
&lt;p&gt;Then the trouble began.&lt;&#x2F;p&gt;
&lt;p&gt;I tried restarting the image:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;docker run -d --name ghost-blog -p 80:2368 -v &#x2F;home&#x2F;ghost&#x2F;blog-data:&#x2F;var&#x2F;lib&#x2F;ghost&#x2F;content ghost&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But when I ran &lt;code&gt;docker ps&lt;&#x2F;code&gt;, no docker containers were running. I tried looking at the log of the &lt;code&gt;ghost-blog&lt;&#x2F;code&gt; container and was greeted with this message:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tar: &#x2F;var&#x2F;lib&#x2F;ghost&#x2F;content.orig: Cannot open: No such file or directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tar: Error is not recoverable: exiting now&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tar: This does not look like a tar archive&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tar: Exiting with failure status due to previous errors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hhmmm… I tried creating &lt;code&gt;&#x2F;var&#x2F;lib&#x2F;ghost&#x2F;content.orig&lt;&#x2F;code&gt;, but that didn’t help. I then copied my &lt;code&gt;blog-data&#x2F;&lt;&#x2F;code&gt; folder, blew the old folder away, then tried running again, but to no avail.&lt;&#x2F;p&gt;
&lt;p&gt;I was out of ideas, so I decided to inquire at the great oracle of &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;duckduckgo.com&#x2F;?q=docker+ghost+tar%3A+%2Fvar%2Flib%2Fghost%2Fcontent.orig%3A+Cannot+open%3A+No+such+file+or+directory+tar%3A+Error+is+not+recoverable%3A+exiting+now+tar%3A+This+does+not+look+like+a+tar+archive+tar%3A+Exiting+with+failure+status+due+to+previous+errors&amp;amp;bext=msl&amp;amp;atb=v43-6_s&amp;amp;ia=web&quot;&gt;DuckDuckGo&lt;&#x2F;a&gt;. The &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;docker-library&#x2F;ghost&#x2F;issues&#x2F;69&quot;&gt;first result&lt;&#x2F;a&gt; was this lovely issue on GitHub that covered &lt;em&gt;exactly&lt;&#x2F;em&gt; the problem I was facing.&lt;&#x2F;p&gt;
&lt;p&gt;I created the directory specified and was able to fire up the docker container without a problem. I think I must have made an incompatible upgrade. ¯_(ツ)_&#x2F;¯&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backup-woes&quot;&gt;Backup Woes&lt;&#x2F;h2&gt;
&lt;p&gt;Running around as the root user of a system is always dangerous. I was painfully reminded of that today when I accidentally deleted my backup folder instead of moving its contents to the original location. 🤦🏻‍♂️Oops.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Fortunately&lt;&#x2F;em&gt;, I had made another backup of all my content saved as a JSON file on my laptop. I fired up the docker container, opened to the website in a web browser, and imported all my old files. Day saved. 😌&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Unfortunately&lt;&#x2F;em&gt; I lost all my configurations. Not that there was a &lt;em&gt;lot&lt;&#x2F;em&gt;, but I did loose the Disqus integration as well as some settings for me as an administrator. Alas. I’ll fix the comments sometime later. Probably &lt;em&gt;after&lt;&#x2F;em&gt; midterms…&lt;&#x2F;p&gt;
&lt;p&gt;So, lessons: make backups. Then don’t delete the backups.&lt;&#x2F;p&gt;
&lt;p&gt;I &lt;em&gt;am&lt;&#x2F;em&gt; enjoying the Ghost blog. It’s pretty minimal and doesn’t get in my way. I just wish I had been a little more careful today.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Emacs Tips and Tricks</title>
        <published>2017-09-23T00:00:00+00:00</published>
        <updated>2017-09-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://beta.lambdaland.org/posts/2017-09-23-emacs-tips-and-tricks/"/>
        <id>https://beta.lambdaland.org/posts/2017-09-23-emacs-tips-and-tricks/</id>
        
        <content type="html" xml:base="https://beta.lambdaland.org/posts/2017-09-23-emacs-tips-and-tricks/">&lt;h2 id=&quot;to-learn-about&quot;&gt;To Learn About&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;☒ Company-mode (completion framework for lots of stuff)&lt;&#x2F;li&gt;
&lt;li&gt;☒ YASnippets (templates)&lt;&#x2F;li&gt;
&lt;li&gt;☒ Auto-YASnippets (something like that—I installed it for temporary
templates)&lt;&#x2F;li&gt;
&lt;li&gt;☒ Alchemist mode (integrates with company mode—tooling for Elixir)&lt;&#x2F;li&gt;
&lt;li&gt;☐ What do &lt;code&gt;M-.&lt;&#x2F;code&gt; and &lt;code&gt;M-,&lt;&#x2F;code&gt; do?&lt;&#x2F;li&gt;
&lt;li&gt;☐ &lt;code&gt;font-lock-add-keywords&lt;&#x2F;code&gt; would let me add new keywords to a
language&lt;&#x2F;li&gt;
&lt;li&gt;☐ hi-lock&lt;&#x2F;li&gt;
&lt;li&gt;☐ highlight-phrase, unhighlight-regex&lt;&#x2F;li&gt;
&lt;li&gt;☒ &lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.emacswiki.org&#x2F;emacs&#x2F;Registers&quot;&gt;Registers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;☐ Auto-loading packages to make startup time shorter&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;things-that-make-me-happy&quot;&gt;Things that make me happy&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Undo in region (just highlight something and hit undo)&lt;&#x2F;li&gt;
&lt;li&gt;Generate Backus-Nauer Forms with a slightly modified syntax with
&lt;code&gt;ebnf-eps-buffer&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;helm&quot;&gt;Helm&lt;&#x2F;h2&gt;
&lt;p&gt;You can filter buffers by pattern with Helm. Type: &lt;code&gt;@pattern&lt;&#x2F;code&gt; to find
buffers matching &lt;code&gt;pattern&lt;&#x2F;code&gt;. If you want to have spaces in the pattern,
you must escape them with a backslash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;searching-with-the-silver-searcher&quot;&gt;Searching with the Silver Searcher&lt;&#x2F;h3&gt;
&lt;p&gt;You’ll need &lt;code&gt;helm-ag&lt;&#x2F;code&gt;. After searching, you get the following
keybindings:&lt;&#x2F;p&gt;
&lt;h5 id=&quot;key-bindings&quot;&gt;Key Bindings&lt;&#x2F;h5&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 19%&quot; &#x2F;&gt;
&lt;col style=&quot;width: 80%&quot; &#x2F;&gt;
&lt;&#x2F;colgroup&gt;
&lt;thead&gt;
&lt;tr class=&quot;header&quot;&gt;
&lt;th&gt;Key&lt;&#x2F;th&gt;
&lt;th&gt;Action&lt;&#x2F;th&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;thead&gt;
&lt;tbody&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td&gt;&lt;code&gt;C-c o&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Open other window&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td&gt;&lt;code&gt;C-l&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Search in parent directory&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td&gt;&lt;code&gt;C-c C-e&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Switch to edit mode&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td&gt;&lt;code&gt;C-x C-s&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Save ag results to buffer(Ask save buffer name if prefix key is specified)&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td&gt;&lt;code&gt;C-c C-f&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Enable helm-follow-mode&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td&gt;&lt;code&gt;C-c &amp;gt;&lt;&#x2F;code&gt;, &lt;code&gt;right&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Move to next file&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td&gt;&lt;code&gt;C-c &amp;lt;&lt;&#x2F;code&gt;, &lt;code&gt;left&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Move to previous file&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td&gt;&lt;code&gt;C-c ?&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Show help message&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;h5 id=&quot;edit-mode-keymap&quot;&gt;Edit mode keymap&lt;&#x2F;h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr class=&quot;header&quot;&gt;
&lt;th&gt;Key&lt;&#x2F;th&gt;
&lt;th&gt;Action&lt;&#x2F;th&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;thead&gt;
&lt;tbody&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td&gt;&lt;code&gt;C-c C-c&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Commit changes&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td&gt;&lt;code&gt;C-c C-k&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Abort&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td&gt;&lt;code&gt;C-c C-d&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Mark delete line&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td&gt;&lt;code&gt;C-c C-u&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Unmark&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;h5 id=&quot;saved-buffer-keymap&quot;&gt;Saved buffer keymap&lt;&#x2F;h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr class=&quot;header&quot;&gt;
&lt;th&gt;Key&lt;&#x2F;th&gt;
&lt;th&gt;Action&lt;&#x2F;th&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;thead&gt;
&lt;tbody&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td&gt;&lt;code&gt;RET&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Jump to current line posion&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td&gt;&lt;code&gt;C-o&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Jump to current line posion in other window&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td&gt;&lt;code&gt;g&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Update result&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;h2 id=&quot;registers&quot;&gt;Registers&lt;&#x2F;h2&gt;
&lt;p&gt;Any letter can be a register. (Uppercase and lowercase are distinct.) In
the follinwg examples, &lt;code&gt;&amp;lt;r&amp;gt;&lt;&#x2F;code&gt; represents a register name.&lt;&#x2F;p&gt;
&lt;p&gt;Working with the point:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-x r SPC &amp;lt;r&amp;gt;&lt;&#x2F;code&gt; Store point in register (mnemonic: C-SPC saves
current mark)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;C-x r j &amp;lt;r&amp;gt;&lt;&#x2F;code&gt; Jump to point saved in register (mnemonic: &lt;em&gt;j&lt;&#x2F;em&gt;ump)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Working with text:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-x r s &amp;lt;r&amp;gt;&lt;&#x2F;code&gt; &lt;em&gt;S&lt;&#x2F;em&gt;ave region into register&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;C-x r i &amp;lt;r&amp;gt;&lt;&#x2F;code&gt; &lt;em&gt;I&lt;&#x2F;em&gt;nsert contents of register (also works for numbers)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Working with numbers:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-u NUMBER C-x r n &amp;lt;r&amp;gt;&lt;&#x2F;code&gt; Save a &lt;em&gt;n&lt;&#x2F;em&gt;umber&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;C-u NUMBER C-x r + &amp;lt;r&amp;gt;&lt;&#x2F;code&gt; Increment register &lt;code&gt;&amp;lt;r&amp;gt;&lt;&#x2F;code&gt; by &lt;code&gt;NUMBER&lt;&#x2F;code&gt; (if
&lt;code&gt;C-u NUMBER&lt;&#x2F;code&gt; omitted, increments by 1)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Other:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-x C-k r &amp;lt;r&amp;gt;&lt;&#x2F;code&gt; Save last kbd macro to register&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;special-modes&quot;&gt;Special Modes&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;racket&quot;&gt;Racket&lt;&#x2F;h3&gt;
&lt;p&gt;Start everything off right with &lt;code&gt;M-x run-geiser RET racket RET&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-c C-d TAB&lt;&#x2F;code&gt; Open up documentation for command under point&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;calc&quot;&gt;Calc&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TAB&lt;&#x2F;code&gt; rotate&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;web-mode&quot;&gt;Web Mode&lt;&#x2F;h3&gt;
&lt;p&gt;I do a fair amount of web programming. &lt;code&gt;web-mode&lt;&#x2F;code&gt; is awesome! There are
way too many keystrokes for me to list. Here are my favorite, though:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-c C-e &#x2F;&lt;&#x2F;code&gt; Close element. (Mnemonic: C-&lt;em&gt;element&lt;&#x2F;em&gt; &#x2F; (for closing
HTML tags))&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-c C-f&lt;&#x2F;code&gt; Fold. Collapses current tag and subtree. Same keystroke to
unfold.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;markdown-mode&quot;&gt;Markdown Mode&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-c C-]&lt;&#x2F;code&gt; Complete markup of element. (e.g. sticks “###” at the
&lt;em&gt;end of a line&lt;&#x2F;em&gt; on a h3 element&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;TAB&lt;&#x2F;code&gt; When called on a heading, collapses&#x2F;expands the heading.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Shift-TAB&lt;&#x2F;code&gt; Cycles global folding&#x2F;visibility&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Text keys: (all start with &lt;code&gt;C-c C-s&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-c C-s s&lt;&#x2F;code&gt; Make current word&#x2F;region bold (&lt;code&gt;s&lt;&#x2F;code&gt; is for strong)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-c C-s e&lt;&#x2F;code&gt; Italics. (&lt;code&gt;e&lt;&#x2F;code&gt; for emphasis)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;bookmarks&quot;&gt;Bookmarks&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;I installed the &lt;code&gt;bm&lt;&#x2F;code&gt; module. Run &lt;code&gt;bm-toggle&lt;&#x2F;code&gt; to book mark a line
visually.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Native bookmarks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x r m&lt;&#x2F;code&gt; New bookmark. Prompts for a name. Mnemonic: “&lt;em&gt;m&lt;&#x2F;em&gt;ark”&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x r b&lt;&#x2F;code&gt; Jump to a bookmark. Mnemonic: “&lt;em&gt;b&lt;&#x2F;em&gt;ookmark”, or “&lt;em&gt;b&lt;&#x2F;em&gt;ack to
&lt;em&gt;b&lt;&#x2F;em&gt;ookmark”&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x r l&lt;&#x2F;code&gt; List bookmarks.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Jumping to a bookmark will do so in the &lt;em&gt;current window&lt;&#x2F;em&gt;, and will put
you where the point last was in that buffer. If you are already in the
buffer, then it will jump to the point where to bookmark was set.&lt;&#x2F;p&gt;
&lt;p&gt;Bookmarks persist over a session—I’m not sure where the file is, but
they do get stored in some file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;expansion&quot;&gt;Expansion&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;M-&#x2F;&lt;&#x2F;code&gt; will do “dynamic expansion”—if there is a word in one of the
buffers of the current session that starts with whatever your cursor is
on, it will expand to that word. Multiple consecutive invocations of
this function will cycle through available expansions.&lt;&#x2F;p&gt;
&lt;p&gt;There’s a way to do manual expansion, but I don’t know it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;window-enlargements&quot;&gt;Window enlargements&lt;&#x2F;h2&gt;
&lt;p&gt;I’ve defined a few nice functions. Here they are:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defun&lt;&#x2F;span&gt;&lt;span&gt; sticky-enlarge-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;prefix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;interactive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;P&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;enlarge-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; prefix &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;car&lt;&#x2F;span&gt;&lt;span&gt; prefix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;unless&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;current-message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;(Use &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; and &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; to adjust window size)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;make-sparse-keymap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;enlarge-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;shrink-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;set-transient-map&lt;&#x2F;span&gt;&lt;span&gt; map t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;defun&lt;&#x2F;span&gt;&lt;span&gt; sticky-shrink-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;prefix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;interactive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;P&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;shrink-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; prefix &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;car&lt;&#x2F;span&gt;&lt;span&gt; prefix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B48EAD;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;unless&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;current-message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;(Use &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; and &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt; to adjust window size)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81A1C1;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;make-sparse-keymap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;enlarge-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;shrink-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;set-transient-map&lt;&#x2F;span&gt;&lt;span&gt; map t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; global-map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;C-x }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;sticky-enlarge-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; global-map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;C-x {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;sticky-shrink-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; global-map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&amp;lt;f7&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;shrink-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; global-map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&amp;lt;f8&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;balance-windows&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; global-map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88C0D0;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A3BE8C;&quot;&gt;&amp;lt;f9&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;&amp;quot;) &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;enlarge-window-horizontally&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECEFF4;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;functions&quot;&gt;Functions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;toggle-truncate-lines&lt;&#x2F;code&gt; will toggle how long lines are displayed&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x C-d&lt;&#x2F;code&gt; is essentially &lt;code&gt;ls&lt;&#x2F;code&gt; — lists the contents of a directory&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-u M-|&lt;&#x2F;code&gt; pipe region to a shell command and replace it with the
output&lt;&#x2F;p&gt;
&lt;p&gt;You can get sweet &lt;code&gt;sed&lt;&#x2F;code&gt;-like behavior with something like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; perl -ne &amp;#39;s&#x2F;^(\d+)\.(\d+)&#x2F;&amp;lt;&amp;lt;1 Thes. $1:$2&amp;gt;&amp;gt;&#x2F;g; print&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;macro-wisdom&quot;&gt;Macro wisdom&lt;&#x2F;h2&gt;
&lt;p&gt;Put cursor where it is supposed to go, begin recording (&lt;code&gt;C-x (&lt;&#x2F;code&gt;), do
thingy, isearch to next location, and then stop recording. (&lt;code&gt;C-x )&lt;&#x2F;code&gt;)
This lets you see what is going to be edited next, and hit &lt;code&gt;C-s C-s&lt;&#x2F;code&gt; if
you want to skip to the next match.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;f3&amp;gt;&lt;&#x2F;code&gt; Is a very fancy key. Normally, it will begin recording a macro.
Once you are defining a macro, hitting &lt;code&gt;&amp;lt;f3&amp;gt;&lt;&#x2F;code&gt; again will insert the
current macro counter.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;f4&amp;gt;&lt;&#x2F;code&gt; is its best friend. Hitting &lt;code&gt;&amp;lt;f4&amp;gt;&lt;&#x2F;code&gt; while defining a macro will
end the macro. Hitting &lt;code&gt;&amp;lt;f4&amp;gt;&lt;&#x2F;code&gt; otherwise will then run the last defined
keyboard macro. Running &lt;code&gt;C-u &amp;lt;f4&amp;gt;&lt;&#x2F;code&gt; runs the second macro in macro ring.
Running &lt;code&gt;C-u 4 &amp;lt;f4&amp;gt;&lt;&#x2F;code&gt; runs the first macro 4 times. (Adjust 4 as you
will.)&lt;&#x2F;p&gt;
&lt;p&gt;You can use Lisp inside of a macro. For example, to insert incrementing
numbers, do:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;M-: (setq x 1) RET&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C-(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C-u M-: x RET&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;M-: (setq x (+ x 1))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;whatever else&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C-)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can repeat a macro until an error is signaled with &lt;code&gt;C-u 0 C-x e&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You can also run &lt;code&gt;apply-macro-to-region-lines&lt;&#x2F;code&gt; (&lt;code&gt;C-x C-k r&lt;&#x2F;code&gt;) to fire a
macro on every line in the region.&lt;&#x2F;p&gt;
&lt;p&gt;To prompt a user for input while writing a macro, do: &lt;code&gt;C-u C-x q&lt;&#x2F;code&gt;. This
is a variant of &lt;code&gt;C-x q&lt;&#x2F;code&gt; which queries the user.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;recursive-editing&quot;&gt;Recursive editing&lt;&#x2F;h3&gt;
&lt;p&gt;Hitting &lt;code&gt;C-r&lt;&#x2F;code&gt; will enter a recursive editing level &lt;em&gt;when the macro is
run&lt;&#x2F;em&gt;, but not while you are recording.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;C-x q&lt;&#x2F;code&gt; enters a query state: &lt;code&gt;y&lt;&#x2F;code&gt; continues to execute the macro, &lt;code&gt;n&lt;&#x2F;code&gt;
aborts the &lt;em&gt;current&lt;&#x2F;em&gt; iteration, and &lt;code&gt;q&lt;&#x2F;code&gt; aborts all together.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;C-u C-x q&lt;&#x2F;code&gt; lets you enter in some text.&lt;&#x2F;p&gt;
&lt;p&gt;To finish recursive editing, type &lt;code&gt;C-M-c&lt;&#x2F;code&gt;. To abort and halt execution,
type &lt;code&gt;C-]&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rectangles&quot;&gt;Rectangles&lt;&#x2F;h2&gt;
&lt;p&gt;To select text in a rectangle, use &lt;code&gt;C-x SPC&lt;&#x2F;code&gt;. The region will then
highlight like a rectangle. The kill and yank commands will work like
normal (i.e. hitting &lt;code&gt;C-k&lt;&#x2F;code&gt; will kill the rectangle.)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x r M-w&lt;&#x2F;code&gt; Copy rectangle as kill. (Think &lt;code&gt;M-w&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x r N&lt;&#x2F;code&gt; Inserts numbered lines in the rectangle. Accepts a prefix
argument to change at what number the lines start at.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;M-x string-insert-rectangle&lt;&#x2F;code&gt; Prompts for a string and inserts it at
the current rectangle. So you can go from this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; two&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; three&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; four&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; - one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; - two&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; - three&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; - four&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;by setting the mark on the &lt;code&gt;o&lt;&#x2F;code&gt; of &lt;code&gt;one&lt;&#x2F;code&gt;, then moving to the &lt;code&gt;f&lt;&#x2F;code&gt; in
&lt;code&gt;four&lt;&#x2F;code&gt;, then running the command.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;misc-keystrokes&quot;&gt;Misc. Keystrokes&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x &amp;lt;right arrow&amp;gt;&lt;&#x2F;code&gt; cycle through buffers&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x C-q&lt;&#x2F;code&gt; toggle read-only mode in current buffer&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x C-;&lt;&#x2F;code&gt; to set comment column to cursor’s current column&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x C-h&lt;&#x2F;code&gt; Really &lt;code&gt;&amp;lt;any prefix&amp;gt; C-h&lt;&#x2F;code&gt; shows a listing of all possible
completions after the prefix character.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x 8 RET&lt;&#x2F;code&gt; Insert arbitary unicode character by name. You can
insert snowmen like this!&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x 8 &amp;lt;char&amp;gt;&lt;&#x2F;code&gt; There are a bunch of characters that you can insert
after this. “&amp;lt;” will insert “«”&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x n n&lt;&#x2F;code&gt; Only displays the region. Good for focusing. Use &lt;code&gt;C-x n w&lt;&#x2F;code&gt;
to display everything.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x $&lt;&#x2F;code&gt; To hide lines in the current buffer, type ‘C-x $’
(‘set-selective-display’) with a numeric argument N. Then lines with
at least N columns of indentation disappear from the screen.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-u&lt;&#x2F;code&gt; Prefix argument. The default is 4. If you want to grow the
current window by, say, 15 lines, do following: &lt;code&gt;C-u 15 C-x ^&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-u &amp;lt;number&amp;gt; &amp;lt;key&amp;gt;&lt;&#x2F;code&gt; Repeats &lt;code&gt;&amp;lt;key&amp;gt;&lt;&#x2F;code&gt; &lt;code&gt;&amp;lt;number&amp;gt;&lt;&#x2F;code&gt; times. It’s
different for inserting digits. If you wanted to insert &lt;code&gt;5&lt;&#x2F;code&gt; seven
times, type &lt;code&gt;C-u 7 C-u 5&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x C-k C-i&lt;&#x2F;code&gt; Inserts the current value of the keyboard macro
counter and increments it. When &lt;code&gt;C-u&lt;&#x2F;code&gt; proceeds the command, the
previous value is inserted, and the counter is not updated. A prefix
argument specifies a different increment.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x C-k C-c&lt;&#x2F;code&gt; Prompts for the initial value of the keyboard macro.
Must be called prior to starting macro definition to be used this
way. It has another behavior if called during macro definition. See
&lt;a class=&quot;link-external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.emacswiki.org&#x2F;emacs&#x2F;EmacsKeyboardMacroCounter&quot;&gt;this
page&lt;&#x2F;a&gt; for
help.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x C-k n&lt;&#x2F;code&gt; Give the last kbd macro a name, which you can then call&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ESC-^&lt;&#x2F;code&gt; Join this line to the previous and fix up whitespace at
join. Useful if &lt;code&gt;auto-fill-mode&lt;&#x2F;code&gt; was turned on and you need to
unwrap a line.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;f1&amp;gt;&lt;&#x2F;code&gt; Run help&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;f2&amp;gt;&lt;&#x2F;code&gt; Appears to be a prefix command, much like &lt;code&gt;C-x&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;f10&amp;gt;&lt;&#x2F;code&gt; Opens the menu. As in, the one at the top of the screen that
you never have actually used. With ACTUAL GRAPHICS!!&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C-x RET f&lt;&#x2F;code&gt; Allows you to set the encoding when saving the file.
Useful for stripping bad line endings in DOS files.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;dired&quot;&gt;Dired&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-o&lt;&#x2F;code&gt; In dired, opens the file the cursor is on in the other window.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;occur&quot;&gt;Occur&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-u M-s o &amp;lt;pattern&amp;gt; RET&lt;&#x2F;code&gt; Copies all strings mattching &lt;code&gt;&amp;lt;pattern&amp;gt;&lt;&#x2F;code&gt;
(if you use &lt;code&gt;.*thingy.*&lt;&#x2F;code&gt; it will copy the whole line with “thingy”
in it) into buffer called &lt;code&gt;*Occur*&lt;&#x2F;code&gt; ### Regexes&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Not like Perl. In &lt;code&gt;(?:aaa|bbb)&lt;&#x2F;code&gt;, the characters &lt;code&gt;(&lt;&#x2F;code&gt;, &lt;code&gt;)&lt;&#x2F;code&gt;, and &lt;code&gt;|&lt;&#x2F;code&gt; all
match themselves. If you want perl-like behavior, escape them:
&lt;code&gt;\(?:aaa\|bbb\)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;But when you want to type that in a string literal, use
&lt;code&gt;&quot;\\(?:aaa\\|bbb\\)&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;character-classes&quot;&gt;Character Classes&lt;&#x2F;h4&gt;
&lt;p&gt;Some common character classes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.&lt;&#x2F;code&gt; works as expected (any char)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;[[:ascii:]]+&lt;&#x2F;code&gt; any ascii character&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;[_A-Za-z0-9]+&lt;&#x2F;code&gt; letters, digits, underscores&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&quot;\([^&quot;]+\)&quot;&lt;&#x2F;code&gt; capture text between double quotes (not accounting for
escaped chars)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;regex-search-and-replace&quot;&gt;Regex search and replace:&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;M-x replace-regexp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Replace regexp: right\|left&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Replace regexp with: \,(if (equal &amp;quot;right&amp;quot; \&amp;amp;amp;) &amp;quot;left&amp;quot; &amp;quot;right&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Looks like the &lt;code&gt;\,(...)&lt;&#x2F;code&gt; syntax says “evaluate me”. :)&lt;&#x2F;p&gt;
&lt;h4 id=&quot;regex-search-and-replace-with-captured-bit&quot;&gt;Regex search and replace with captured bit&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D8DEE9; background-color: #2E3440;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;M-x replace-regexp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Replace regexp: subject(\([A-Za-z]+\))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Replace regexp with: \1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That gets subject(*), and retuns *&lt;&#x2F;p&gt;
&lt;h2 id=&quot;programming-languages&quot;&gt;Programming Languages&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;c&quot;&gt;C&lt;&#x2F;h3&gt;
&lt;p&gt;Compile (using &lt;code&gt;make -k&lt;&#x2F;code&gt;) with &lt;code&gt;M-x compile&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Any errors will show up in a special buffer; visit with &lt;kbd&gt;C-x
`&lt;&#x2F;kbd&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
