<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Software-Dev on Andrew Quinn&#39;s TILs</title>
    <link>https://til.andrew-quinn.me/tags/software-dev/</link>
    <description>Recent content in Software-Dev on Andrew Quinn&#39;s TILs</description>
    <image>
      <title>Andrew Quinn&#39;s TILs</title>
      <url>https://til.andrew-quinn.me/papermod-cover.png</url>
      <link>https://til.andrew-quinn.me/papermod-cover.png</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 25 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://til.andrew-quinn.me/tags/software-dev/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>The long death of programming languages</title>
      <link>https://til.andrew-quinn.me/posts/the-long-death-of-programming-languages/</link>
      <pubDate>Wed, 25 Feb 2026 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/the-long-death-of-programming-languages/</guid>
      <description>&lt;p&gt;I wrote my first Clojure program in anger a few months ago.
Only, it&amp;rsquo;s not accurate to
say that I wrote it; AI did most of the writing, and I directed it on what my
design goals were and why.
Architecturally, you could call it was a stateless
&lt;a href=&#34;https://learn.microsoft.com/en-us/azure/architecture/patterns/anti-corruption-layer&#34;&gt;anti-corruption layer&lt;/a&gt;,
yapping between some REST endpoints and some ancient proprietary serialization.&lt;/p&gt;
&lt;p&gt;I had never written a Clojure program of nontrivial size before. Indeed I had
barely touched any Lisp at all
since working through &lt;a href=&#34;https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/index.html&#34;&gt;SICP&lt;/a&gt;
during a high school summer vacation, over a decade ago.
That didn&amp;rsquo;t matter. Much more important was emphasizing certain invariants from
the start, like the aforementioned statelessness, which made it very easy to
unit and integration test, which was the true challenge.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Lua is a pretty good config language</title>
      <link>https://til.andrew-quinn.me/posts/lua-is-a-pretty-good-config-language/</link>
      <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/lua-is-a-pretty-good-config-language/</guid>
      <description>&lt;p&gt;Lua and Scheme occupy curiously similar places in my noggin, becuase my
primary use case for both has been as scripting languages embedded into other,
larger projects. Lua of course is basically designed for this job, but it&amp;rsquo;s
a solid intermediate format to target even if you have no immediate intentions
to use the programming language parts at all. A TSV file like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;10.0.0.5  192.168.1.1 80  tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;10.0.0.6  192.168.1l.1  443 tcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;can be given a lot more structure on the cheap
by writing a small transpiler of sorts to turn it into&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Where is the DevOps for Yocto?</title>
      <link>https://til.andrew-quinn.me/posts/where-is-the-devops-for-yocto/</link>
      <pubDate>Sat, 27 Sep 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/where-is-the-devops-for-yocto/</guid>
      <description>&lt;p&gt;The cozy world of DevOps has spoiled me with tools like Ansible,
Terraform, and Packer. In the situations where I have a Linux machine
already booted up, and sometimes already connected to the Internet, I
can make things really easy on myself by slinging these tools in my
usual way for repeatable, reproducible machines that may or may not come
with the attendant headaches of immutable infrastructure (sorry, Nix,
I&amp;rsquo;m not in love with you, I&amp;rsquo;m in love with the idea of you).&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>It&#39;s okay to solve a problem twice</title>
      <link>https://til.andrew-quinn.me/posts/it-s-okay-to-solve-a-problem-twice/</link>
      <pubDate>Fri, 22 Aug 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/it-s-okay-to-solve-a-problem-twice/</guid>
      <description>&lt;p&gt;Quoth
&lt;a href=&#34;https://www.catb.org/~esr/faqs/hacker-howto.html#believe2&#34;&gt;&amp;ldquo;How to Become a Hacker&amp;rdquo;&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2. No problem should ever have to be solved twice.
Creative brains are a valuable, limited resource. They shouldn&#39;t be wasted on re-inventing the wheel when there are so many fascinating new problems waiting out there.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Much more at the original post, including preemptive rebuttals to what
I&amp;rsquo;m about to describe. This post is entirely about cataloguing my own
error.&lt;/p&gt;
&lt;p&gt;I took this maxim, perhaps, a little too close to heart when I was
starting out as a software guy, 15-odd years ago. This is my
apology to past me. Past me, I apologize.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>You don&#39;t need CGO to use SQLite in your Go binary</title>
      <link>https://til.andrew-quinn.me/posts/you-don-t-need-cgo-to-use-sqlite-in-your-go-binary/</link>
      <pubDate>Fri, 18 Jul 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/you-don-t-need-cgo-to-use-sqlite-in-your-go-binary/</guid>
      <description>&lt;p&gt;At least not for most use cases. You can just use
&lt;a href=&#34;https://pkg.go.dev/modernc.org/sqlite#section-readme&#34;&gt;modernc.org/sqlite&lt;/a&gt;
instead as your SQLite driver.&lt;/p&gt;
&lt;p&gt;For people who aren&amp;rsquo;t in the Go know, &amp;ldquo;pure&amp;rdquo; Go programs are trivially
easy to compile cross-platform to all the major platforms by default.
You read that right - you can just &lt;code&gt;go build&lt;/code&gt; a single Windows
executable, Mac executable, and Linux executable &lt;em&gt;on the same machine&lt;/em&gt;
and just ship it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt; 1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt; 2&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-3&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-3&#34;&gt; 3&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-4&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-4&#34;&gt; 4&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-5&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-5&#34;&gt; 5&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-6&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-6&#34;&gt; 6&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-7&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-7&#34;&gt; 7&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-8&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-8&#34;&gt; 8&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-9&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-9&#34;&gt; 9&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-10&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-10&#34;&gt;10&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-11&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-11&#34;&gt;11&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-12&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-12&#34;&gt;12&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-13&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-13&#34;&gt;13&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-14&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-14&#34;&gt;14&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# This can all happen on the same box!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export CGO_ENABLED&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# no c cross-compilation please&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export GOOS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;linux
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GOARCH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;amd64 go build -o hello-linux-amd64 hello.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GOARCH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;arm64 go build -o hello-linux-arm64 hello.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export GOOS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;darwin   &lt;span style=&#34;color:#75715e&#34;&gt;# aka mac&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GOARCH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;amd64 go build -o hello-darwin-amd64 hello.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GOARCH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;arm64 go build -o hello-darwin-arm64 hello.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export GOOS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;windows
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GOARCH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;amd64 go build -o hello-windows-amd64.exe hello.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GOARCH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;arm64 go build -o hello-windows-arm64.exe hello.go
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This was the real reason I chose Go over Python for
&lt;a href=&#34;https://github.com/hiAndrewQuinn/tsk/&#34;&gt;&lt;code&gt;tsk&lt;/code&gt;, my instant-search Finnish to English pocket dictionary&lt;/a&gt;.
I wanted to be able to give Windows users a single &lt;code&gt;.exe&lt;/code&gt; they could
just &lt;em&gt;run&lt;/em&gt; and have work out of the box.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>LLM, JavaScript, GitHub Pages, localStorage: A recipe for free apps anyone can use</title>
      <link>https://til.andrew-quinn.me/posts/llm-javascript-github-pages-localstorage-a-recipe-for-free-apps-anyone-can-use/</link>
      <pubDate>Wed, 18 Jun 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/llm-javascript-github-pages-localstorage-a-recipe-for-free-apps-anyone-can-use/</guid>
      <description>&lt;p&gt;Earlier today on Hacker News
&lt;a href=&#34;https://pontus.granstrom.me/scrappy/&#34;&gt;Scrappy made the rounds&lt;/a&gt;,
with the explicit tagline &amp;ldquo;make little apps for you and your friends&amp;rdquo;.
I always like to see new projects in this vein.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why I&amp;rsquo;d like to outline my alternative approach, which&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Works cross-platform and on mobile devices by default,&lt;/li&gt;
&lt;li&gt;Doesn&amp;rsquo;t require any app store tomfoolery,&lt;/li&gt;
&lt;li&gt;Has great uptime built in,&lt;/li&gt;
&lt;li&gt;Gives you just enough data persistence to not get in your way, and&lt;/li&gt;
&lt;li&gt;Is owned by you, forever.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the stack I used to build
&lt;a href=&#34;https://hiandrewquinn.github.io/diet-checklist/&#34;&gt;my diet checklist&lt;/a&gt;,
which I keep as a little icon on my phone&amp;rsquo;s home page.
Here it is:&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Cross-platform TUIs are easier than cross-platform GUIs</title>
      <link>https://til.andrew-quinn.me/posts/cross-platform-tuis-are-easier-than-cross-platform-guis/</link>
      <pubDate>Tue, 20 May 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/cross-platform-tuis-are-easier-than-cross-platform-guis/</guid>
      <description>&lt;p&gt;Below is a GIF of
&lt;a href=&#34;https://github.com/hiAndrewQuinn/tsk&#34;&gt;&lt;code&gt;tsk&lt;/code&gt;, my pocket Finnish-to-English dictionary&lt;/a&gt;,
running in my terminal emulator of choice under Linux.
It&amp;rsquo;s what the kids call a
&lt;a href=&#34;https://github.com/rothgar/awesome-tuis&#34;&gt;TUI&lt;/a&gt;,
a graphical program that just happens to drive its graphics
using terminal graphics instead of graphics-graphics.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Insert GIF here.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You can probably tell that this program fits neatly into the
&lt;a href=&#34;https://bradfrost.com/blog/link/an-app-can-be-a-home-cooked-meal/&#34;&gt;&amp;ldquo;home-cooked meal&amp;rdquo;&lt;/a&gt;
clade of programs. There is a very straightforward problem I want solved -
fast, single-executable-portable dictionary lookup, with a few conveniences
for the busy language learner layered on top. I am quite happy with &lt;code&gt;tsk&lt;/code&gt; in
its current iteration and don&amp;rsquo;t plan to add much more to it anytime soon.
It would still save me a lot of time and hassle if I were the only person who
could use it.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Binary search isn&#39;t about search III. Loop invariant of rightmost element search</title>
      <link>https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search-iii-loop-invariant-of-rightmost-element-search/</link>
      <pubDate>Sun, 09 Mar 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search-iii-loop-invariant-of-rightmost-element-search/</guid>
      <description>&lt;p&gt;If you followed
&lt;a href=&#34;https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search/&#34;&gt;&amp;ldquo;Binary search isn&amp;rsquo;t about search&amp;rdquo;&lt;/a&gt;
and
&lt;a href=&#34;https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search-ii-loop-invariant-of-leftmost-element-search/&#34;&gt;&amp;ldquo;Binary search isn&amp;rsquo;t about search II&amp;rdquo;&lt;/a&gt;
properly, the following statements should suffice as a summary:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;L[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;:l] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; T &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; L[r:len(L)]    &lt;span style=&#34;color:#75715e&#34;&gt;# ordinary binary search loop invariant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;L[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;:l] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; T &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; L[r:len(L)]   &lt;span style=&#34;color:#75715e&#34;&gt;# leftwise binary search loop invariant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s complete the triptych. Take a wild guess what invariant we use for &lt;em&gt;rightmost&lt;/em&gt; element binary search:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-1-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-1-1&#34;&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;L[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;:l] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; T &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; L[r:len(L)]   &lt;span style=&#34;color:#75715e&#34;&gt;# rightwise binary search loop invariant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;a-motivating-example&#34;&gt;A motivating example&lt;/h2&gt;
&lt;p&gt;Consider again an array like&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Binary search isn&#39;t about search</title>
      <link>https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search/</link>
      <pubDate>Fri, 07 Mar 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/binary-search-isn-t-about-search/</guid>
      <description>&lt;p&gt;Suppose you&amp;rsquo;re trying to track down a bug that appeared in a series of Git commits.
You&amp;rsquo;ve been idly keeping track of where this bug appears in your
&lt;a href=&#34;https://github.com/not-an-aardvark/lucky-commit&#34;&gt;lucky&lt;/a&gt;
commits by hand, while busy with other things. So far you&amp;rsquo;ve compiled this table:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt; 1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt; 2&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-3&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-3&#34;&gt; 3&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-4&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-4&#34;&gt; 4&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-5&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-5&#34;&gt; 5&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-6&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-6&#34;&gt; 6&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-7&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-7&#34;&gt; 7&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-8&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-8&#34;&gt; 8&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-9&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-9&#34;&gt; 9&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-10&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-10&#34;&gt;10&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000000    🧼 clean, no bug.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000001    🧼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000002    🧼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000003    🧼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000004    🧼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000005    🧼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000006    🐛 bug first appears here.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000007    🐛
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000008    🐛
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0000009    🤔 bug mysteriously disappears...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Then an EMP explodes in your vicinity and scrambles your memory circuits. The Internet
is down, you don&amp;rsquo;t have the
&lt;a href=&#34;https://git-scm.com/docs/git-bisect&#34;&gt;git-bisect man pages&lt;/a&gt;
downloaded locally, and all you remember is that your first commit was good, your last
commit was good but for reasons you don&amp;rsquo;t understand, and &lt;em&gt;something&lt;/em&gt; bad is probably
still lurking in there. But where?&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>SQLite is learnable</title>
      <link>https://til.andrew-quinn.me/posts/the-learnability-of-sqlite/</link>
      <pubDate>Tue, 18 Feb 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/the-learnability-of-sqlite/</guid>
      <description>&lt;p&gt;This is a response to
&lt;a href=&#34;https://pid1.dev/posts/siren-call-of-sqlite-on-the-server/&#34;&gt;pid1.call&amp;rsquo;s &amp;ldquo;Siren Call of SQlite on the Server&amp;rdquo;&lt;/a&gt;,
which itself is a response to articles like
&lt;a href=&#34;https://blog.wesleyac.com/posts/consider-sqlite&#34;&gt;Wesley Aptekar-Cassels&amp;rsquo;s &amp;ldquo;Consider SQLite&amp;rdquo;&lt;/a&gt;
espousing SQLite as a server-side technology.
Cards on the table, I both love SQLite &lt;em&gt;and&lt;/em&gt;
think pid1 has the more correct take here.&lt;/p&gt;
&lt;p&gt;When I decided on a dime after college to move countries
and be with my wife, part of the package deal was that
I had to throw away my dreams of easing into the software
industry by resting on the laurels of my
&lt;a href=&#34;https://www.northwestern.edu/&#34;&gt;strong, but not MIT-level-known-worldwide-strong, alma mater&lt;/a&gt;
(sorry Wildcats).
Electrical engineering was just not going to be
feasible for a then-monolingual
English speaker in Finland, and besides,
I majored in it 90% out of curiosity anyway. I always intended
to return to my once and future home, the shell, after my
&lt;a href=&#34;https://en.wikipedia.org/wiki/Rumspringa&#34;&gt;Rumspringa with electrons&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>The self-hosted to DevOps engineer pipeline</title>
      <link>https://til.andrew-quinn.me/posts/the-self-hosted-to-devops-engineer-pipeline/</link>
      <pubDate>Wed, 18 Sep 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/the-self-hosted-to-devops-engineer-pipeline/</guid>
      <description>&lt;p&gt;What&amp;rsquo;s the best way to get a job? Show someone with a job to do that you
can do the job within their
&lt;a href=&#34;https://en.wikipedia.org/wiki/Project_management_triangle&#34;&gt;iron triangle&lt;/a&gt;.
What&amp;rsquo;s the best way you can show someone you can handle a complicated
k8s deployment, with 7 different CNCF-approved add-ons, zero-downtime
rollouts and a whole bunch of YAML files? Probably by competently and
publicly running &lt;em&gt;your own&lt;/em&gt; complicated k8s infrastructure.&lt;/p&gt;
&lt;p&gt;Self-hosters remind me a lot of the sysadmins of yore, who mostly ended
up in the profession because they just &lt;em&gt;couldn&amp;rsquo;t help&lt;/em&gt; but mess around with
their underlying computing machine until they knew all kinds of weird
nooks and crannies within it. I trace my own lineage in software
deveopment back to the day my parents finally purchased a Dell laptop
and a 300 Kbps Internet connection (residential wiring in Boston left
something to be desired), and promptly broke the Windows registry and
installed Ubuntu without them ever realizing anything had changed.
The next year I got my first internship through a high school program
as a Unix admin intern at
&lt;a href=&#34;https://www.akamai.com/&#34;&gt;Akamai&lt;/a&gt;, and the rest is history.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How I ask GPT-4 to make tiny Python scripts in practice</title>
      <link>https://til.andrew-quinn.me/posts/how-i-ask-gpt-4-to-make-tiny-python-scripts-in-practice/</link>
      <pubDate>Thu, 22 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/how-i-ask-gpt-4-to-make-tiny-python-scripts-in-practice/</guid>
      <description>&lt;ol&gt;
&lt;li&gt;First get a working script. &amp;ldquo;Hey GPT-4, write me a ChatGPT script that does &lt;X&gt;.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Manually check over the script and iterate until it&amp;rsquo;s giving me what I want.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Now wrap the script into a &lt;a href=&#34;https://click.palletsprojects.com/en/8.1.x/&#34;&gt;&lt;code&gt;click&lt;/code&gt;&lt;/a&gt; command-line interface.&amp;rdquo; I almost always specify to use an &lt;code&gt;--input&lt;/code&gt; flag and an &lt;code&gt;--output&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;If the data it&amp;rsquo;s working with is human-readable, &amp;ldquo;Make it so that if &lt;code&gt;--input&lt;/code&gt; is not specified, it reads data from stdin.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;If the data it&amp;rsquo;s writing is human-readable, &amp;ldquo;Make it so that if &lt;code&gt;--output&lt;/code&gt; is not specified, it emits data to stdout.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;If the script is complicated enough that error logging is warranted: &amp;ldquo;Add logging and &lt;a href=&#34;https://pypi.org/project/colorlog/&#34;&gt;&lt;code&gt;colorlog&lt;/code&gt;&lt;/a&gt;. Ensure all error messages are written to &lt;code&gt;stderr&lt;/code&gt; so that it does not clash with output.&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This advice is optimized for &lt;strong&gt;small&lt;/strong&gt; Python scripts, usually under 200 lines in total,
for automating semi-mundane tasks like&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>My pet theory of how great software gets started</title>
      <link>https://til.andrew-quinn.me/posts/my-pet-theory-of-how-great-software-gets-started/</link>
      <pubDate>Tue, 16 Jul 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/my-pet-theory-of-how-great-software-gets-started/</guid>
      <description>&lt;p&gt;(Inspired by
&lt;a href=&#34;https://news.ycombinator.com/item?id=40974768&#34;&gt;yungporko&amp;rsquo;s Ask HN post&lt;/a&gt;,
which got me thinking.)&lt;/p&gt;
&lt;p&gt;Pretty much every community, dojo, workplace, subculture, scene you can imagine
in the modern day had a software sub-scene embedded within it. It can be as
small as &amp;ldquo;that guy who does our Excel&amp;rdquo;, or as large as
&lt;a href=&#34;https://www.pouet.net/&#34;&gt;the scene itself&lt;/a&gt;
. This is owing to the fantastic generality of software as a way to make almost
anything more efficient, but we won&amp;rsquo;t go on that tangent now.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Valuable software is about letting people do new things</title>
      <link>https://til.andrew-quinn.me/posts/valuable-software-is-about-doing-new-things/</link>
      <pubDate>Fri, 21 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/valuable-software-is-about-doing-new-things/</guid>
      <description>&lt;p&gt;Today I released a dump of
&lt;a href=&#34;https://github.com/Selkouutiset-Archive/selkokortti/releases/tag/summer-2024&#34;&gt;six months of flashcards&lt;/a&gt;
I autogenerated from
&lt;a href=&#34;../lessons-learned-from-6-months-of-operating-a-teensy-tiny-news-archive/&#34;&gt;my tiny Finnish news archive&lt;/a&gt;
to make the lives of my fellow language learners easier.
The actual code which generates this archive is
&lt;a href=&#34;https://github.com/Selkouutiset-Archive/selkokortti/blob/main/main.py&#34;&gt;about 300 lines of Python&lt;/a&gt;
.
The basic value add for the user:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;What you want&lt;/strong&gt;: Better fluency in Finnish.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What you need&lt;/strong&gt;: Practice. Lots of it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What this gives you&lt;/strong&gt;: GOTO 2.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is emphatically &lt;em&gt;not&lt;/em&gt; the kind of product, or use case,
I would stumble upon as a brain-in-the-vat developer. It is
a niche offering, one I only found because I actually
got out into the world and tried to &lt;em&gt;do something hard&lt;/em&gt;.
In so doing, I recognized the possibility of building a tool
that could help me in this &lt;em&gt;non-programming&lt;/em&gt; endeavour.
So I built it. And I&amp;rsquo;m proud of it.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Layers of abstraction for me, not for thee</title>
      <link>https://til.andrew-quinn.me/posts/layers-of-abstraction-for-me-not-for-thee/</link>
      <pubDate>Tue, 18 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/layers-of-abstraction-for-me-not-for-thee/</guid>
      <description>&lt;p&gt;Consider the problem of &amp;ldquo;how do I run more than 1 terminal at a time&amp;rdquo;.
At this moment, I have at least 5 different ways I can effectively
solve this issue:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I can, from a different physical computer, SSH in to a new session.&lt;/li&gt;
&lt;li&gt;I can, from the same physical computer, switch to a different &lt;code&gt;tty&lt;/code&gt;
session with &amp;hellip; &lt;code&gt;C-S-F2&lt;/code&gt; through &lt;code&gt;6&lt;/code&gt; or something. (Rare, but
sometimes it comes in really handy.)&lt;/li&gt;
&lt;li&gt;I can, in the same user session, open 2 separate windows of a terminal
emulator.&lt;/li&gt;
&lt;li&gt;I can, in the same terminal emulator, open a new tab.&lt;/li&gt;
&lt;li&gt;I can, in the same emulated terminal, run &lt;code&gt;tmux&lt;/code&gt; and open a new
pane.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are yet more exotic options like
&lt;a href=&#34;https://en.wikipedia.org/wiki/Serial_over_LAN&#34;&gt;Serial over LAN&lt;/a&gt;
that I&amp;rsquo;m only theoretically aware of.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>OpenBSD, the computer appliance maker&#39;s secret weapon</title>
      <link>https://til.andrew-quinn.me/posts/openbsd-the-computer-appliance-maker-s-secret-weapon/</link>
      <pubDate>Wed, 05 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/openbsd-the-computer-appliance-maker-s-secret-weapon/</guid>
      <description>&lt;p&gt;Between our ESP32 prokaryotic organisms and our 24/7 Internet-enabled
megafauna servers, there exists a vast and loosely-defined ecosystem of things
the
B2B world likes to call &lt;strong&gt;computer appliances&lt;/strong&gt;. Picture a bespoke Pi 4 packaged
up neatly with some Python scripts, a little fancy plastic embossing, and maybe
a well-guarded &lt;code&gt;id_ed25519.pub&lt;/code&gt; in case you end up in hot water during the
(long - very long, stable cash flow for generations long) maintenance contract,
and you&amp;rsquo;re in the ballpark.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Doing is normally distributed, learning is log-normal</title>
      <link>https://til.andrew-quinn.me/posts/doing-is-normally-distributed-learning-is-log-normal/</link>
      <pubDate>Tue, 28 May 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/doing-is-normally-distributed-learning-is-log-normal/</guid>
      <description>&lt;p&gt;There are few things I think about more than the essays on
&lt;a href=&#34;https://gwern.net/index&#34;&gt;gwern.net&lt;/a&gt;,
and there are few with as satisfying a theoretical payout
to contemplate in my orb as
&lt;a href=&#34;https://gwern.net/note/pipeline&#34;&gt;his essay on &amp;ldquo;leaky pipelines&amp;rdquo;&lt;/a&gt;,
aka log-normal distributions.&lt;/p&gt;
&lt;p&gt;The skulk: Say you&amp;rsquo;re working on a Laravel web app.
You&amp;rsquo;re about 90% sure you know how to start the app. You&amp;rsquo;re
80% sure you know how to handle the infra you&amp;rsquo;ll need to
get it online. And you&amp;rsquo;re 70% sure you know how to get your
first customer. What is your chance of successfully going
from zero to first customer? 0.9 * 0.8 * 0.7 = a little over
0.5. That&amp;rsquo;s &amp;hellip; a lot less encouraging than any of the
previous numbers, if you buy my multi-step modelling.&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
