<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Machine Lines</title>
    <link>https://mikeinnes.io</link>
    <description>Recent content on Machine Lines</description>
    <language>en-gb</language>
    <lastBuildDate>Mon, 27 Apr 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://mikeinnes.io/feed.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Structured Concurrency</title>
      <link>https://mikeinnes.io/sponsor/posts/concurrency/</link>
      <pubDate>Mon, 27 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/concurrency/</guid>
      <description>&lt;p&gt;I’m going to show you some examples of how Raven handles async, which might seem surprising. Then I’m (I hope) going to convince you that it’s a sensible and even elegant approach to some difficult problems in concurrency, despite being unusual.&lt;/p&gt;
&lt;p&gt;You can start a background task with the &lt;code&gt;async&lt;/code&gt; keyword, which returns a &lt;code&gt;Task&lt;/code&gt; object:&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;raven&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;t &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; { sleep(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>WebAssembly solves Function Colouring</title>
      <link>https://mikeinnes.io/sponsor/posts/tasks/</link>
      <pubDate>Fri, 06 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/tasks/</guid>
      <description>&lt;p&gt;If you used JavaScript before &lt;code&gt;Promise&lt;/code&gt; was introduced (over ten years ago now!), you will have seen code like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;javascript&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D2A8FF&quot;&gt;fetchUserId&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;userId&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#D2A8FF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(err);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D2A8FF&quot;&gt;  loadAccountBalance&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(userId, (&lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;balance&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#D2A8FF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(err);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D2A8FF&quot;&gt;    formatBalanceMessage&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(balance, (&lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;      if&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#D2A8FF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(err);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;      console.&lt;/span&gt;&lt;span style=&quot;color:#D2A8FF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(message);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;  });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is what we call “callback hell”. The intent is identical to the much simpler version:&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Research using Flux</title>
      <link>https://mikeinnes.io/posts/flux/</link>
      <pubDate>Thu, 26 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/flux/</guid>
      <description>&lt;p&gt;Computers were born to simulate the world. The very first job of the first modern computer, the 1945 ENIAC, was to solve differential equations for a hydrogen bomb. More recently, equations have been replaced by data: machine learning methods absorb unfathomable amounts of information and learn to predict its patterns, without knowing the exact mechanics.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Flux_(machine-learning_framework)&quot;&gt;Flux&lt;/a&gt; is a machine learning library which bridges those two approaches. Its one weird trick is allowing almost any Julia code, including complex simulations, to run as part of a learning process. That in turn enables a hybrid approach to modelling: write down the rules that you do know, and use data to fill in the gaps. When there’s too much uncertainty for a pure simulation, but pure learning might not respect physical constraints, Flux gives you best of both worlds.&lt;/p&gt;
&lt;p&gt;Flux doesn’t compare to TensorFlow or PyTorch for large language models, but it has found an excellent niche among researchers, who have used it to find new insights about the world rather than blindly matching patterns. What follows is a small smattering of research projects that have used Flux, and which illustrate its modest but (I think!) meaningful impact on the world.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Raven in JavaScript</title>
      <link>https://mikeinnes.io/sponsor/posts/in-js/</link>
      <pubDate>Fri, 06 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/in-js/</guid>
      <description>&lt;p&gt;A &lt;a href=&quot;https://mikeinnes.io/sponsor/posts/2026/&quot;&gt;few weeks ago&lt;/a&gt; I talked about a new direction for Raven, where we prioritise slotting into existing JavaScript projects over a more standalone setup. That better fits Raven’s current state (good for simple numerics, not yet good for high-level scripting). And it fits the way the programming landscape is likely to change with LLMs, with both more code than ever being written in TypeScript, but alongside a flourishing of niche languages for specific use cases.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Over the last few weeks I’ve gotten the technical side of that story working, and you can see and play with a demo of the build setup &lt;a href=&quot;https://github.com/Unkindnesses/raven-js-template&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As far as possible, I’ve tried to recreate the simplicity of pure JS files, albeit with a build step. So creating a module is easy. &lt;code&gt;hello.rv&lt;/code&gt;:&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Year of the Raven</title>
      <link>https://mikeinnes.io/sponsor/posts/2026/</link>
      <pubDate>Fri, 02 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/2026/</guid>
      <description>&lt;p&gt;Happy new year everyone! This month’s update is late (sorry!) because I started the year getting absolutely wiped by the flu. Apparently it’s been a bad season. I can tell you it’s no fun to have, but thankfully I’m back on my feet now.&lt;/p&gt;
&lt;p&gt;In the past I’ve considered preparing content, so that if I have an off-day I can still post on schedule. But on balance I prefer to write off the cuff. I think what I come up with in the moment is usually more interesting and concrete: let’s say more timely, if not always on time.&lt;/p&gt;
&lt;p&gt;My other distraction over the holidays has been throwing together a little word game called &lt;a href=&quot;https://scrambleit.app/&quot;&gt;Scramble&lt;/a&gt;. It’s mostly just for fun, though I also wanted to get some experience in frontend tools so that I know what I’m doing (at least a bit) before trying things like Raven’s notebook interface. Handily, LLMs are good at porting between different frameworks, which makes experiments quick.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Raven is open source</title>
      <link>https://mikeinnes.io/sponsor/posts/open-source/</link>
      <pubDate>Fri, 05 Dec 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/open-source/</guid>
      <description>&lt;p&gt;Here’s an early Christmas present for you: the &lt;a href=&quot;https://github.com/Unkindnesses/raven&quot;&gt;Raven repo&lt;/a&gt; is now public! Alongside the open source code, it’s now easy for anyone to try the language out, as described in the &lt;a href=&quot;https://github.com/Unkindnesses/raven&quot;&gt;docs&lt;/a&gt;. If you have node on your system it’s as easy as &lt;code&gt;npm i -g @unkindnesses/raven&lt;/code&gt;. If you have VS Code, you can simply install the &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=unkindnesses.raven-lang&quot;&gt;Raven extension&lt;/a&gt;, run “Add Terminal Command” and you’re good to go.&lt;/p&gt;
&lt;p&gt;The stocking-fillers are a couple of interactive blog posts that show off Raven’s current features (limited as they are). First the &lt;a href=&quot;https://mikeinnes.io/posts/raven-tour/&quot;&gt;language tour&lt;/a&gt;, and second my &lt;a href=&quot;https://mikeinnes.io/posts/advent-2025/&quot;&gt;Advent of Code solutions&lt;/a&gt;, which I’ll keep updated as the problems are published.&lt;/p&gt;
&lt;h2 id=&quot;notebooks-are-up&quot; tabindex=&quot;-1&quot;&gt;Notebooks are up&lt;/h2&gt;
</description>
    </item>
    
    <item>
      <title>Advent of Code</title>
      <link>https://mikeinnes.io/posts/advent-2025/</link>
      <pubDate>Mon, 01 Dec 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/advent-2025/</guid>
      <description>&lt;p&gt;I’m taking a crack at solving &lt;a href=&quot;https://adventofcode.com/&quot;&gt;Advent of Code&lt;/a&gt; using &lt;a href=&quot;https://github.com/unkindnesses/raven&quot;&gt;Raven&lt;/a&gt;, a little programming language I’m working on which compiles to WebAssembly. This post is my notebook as I go along, and the code cells are editable, so you can play with the solutions yourself.&lt;/p&gt;
&lt;p&gt;Raven’s standard library is, uh, reasonably sparse at the moment. So the solutions will tend to rely on JavaScript interop, or involve rewriting basic functionality, and it’s not all that representative of how I’d like Raven to look. But it might be fun to see some of the nuts and bolts.&lt;/p&gt;
&lt;p&gt;Jump to &lt;a href=&quot;#day-one&quot;&gt;Day One&lt;/a&gt;, &lt;a href=&quot;#day-two&quot;&gt;Day Two&lt;/a&gt;, &lt;a href=&quot;#day-three&quot;&gt;Day Three&lt;/a&gt;, &lt;a href=&quot;#day-four&quot;&gt;Day Four&lt;/a&gt;, &lt;a href=&quot;#day-five&quot;&gt;Day Five&lt;/a&gt;, &lt;a href=&quot;#day-six&quot;&gt;Day Six&lt;/a&gt;, &lt;a href=&quot;#day-seven&quot;&gt;Day Seven&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A Tour of Raven</title>
      <link>https://mikeinnes.io/posts/raven-tour/</link>
      <pubDate>Sat, 22 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/raven-tour/</guid>
      <description>&lt;p&gt;Welcome! &lt;a href=&quot;https://github.com/Unkindnesses/raven&quot;&gt;Raven&lt;/a&gt; is a small but smart programming language that compiles to WebAssembly. It combines a simple, functional data model, powerful type inference, and flexible syntax. You can learn more from &lt;a href=&quot;https://github.com/Unkindnesses/raven&quot;&gt;the GitHub page&lt;/a&gt;, including how to get set up locally.&lt;/p&gt;
&lt;p&gt;Here’s “hello world” (or our version of it). Press the play button to run code, or try editing the text! (The compiler is not yet that robust to errors, so if things get funky, just refresh the page.)&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;raven&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;println(&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&quot;Cacaw, World!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Stack traces, loop labels and wasm GC</title>
      <link>https://mikeinnes.io/sponsor/posts/stack-traces/</link>
      <pubDate>Fri, 07 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/stack-traces/</guid>
      <description>&lt;p&gt;It’s been a busy month! One of the reasons I gave for &lt;a href=&quot;../porting/&quot;&gt;porting the compiler&lt;/a&gt; to TypeScript was I &lt;a href=&quot;../vibes/&quot;&gt;expected coding agents&lt;/a&gt; to work with it more effectively, compared to the old Julia codebase. And that’s already paying off nicely. It leads to an addictive loop: if I think of some feature I meant to add eventually, instead of adding it to my todo list, I can throw it into codex and see what happens. What comes out is usually pretty incomplete, but feels &lt;em&gt;oh so close&lt;/em&gt;, and I may as well just quickly do that one last thing to finish it up. Of course the finishing touches usually end up being more complex than I thought – and rinse and repeat.&lt;/p&gt;
&lt;p&gt;That cycle has lead to a somewhat scattershot approach to development! Below is a grab bag of bits I’ve been playing around with this month. As well as those, I added a new &lt;a href=&quot;https://github.com/Unkindnesses/raven/blob/cc5a8d680fd7ed25af027008721058e961f3d706/DOCS.md&quot;&gt;documentation file&lt;/a&gt; to the repo with some notes about Raven’s CLI and syntax – more to come soon.&lt;/p&gt;
&lt;h2 id=&quot;stack-traces&quot; tabindex=&quot;-1&quot;&gt;Stack Traces&lt;/h2&gt;
</description>
    </item>
    
    <item>
      <title>Compiler Tracing</title>
      <link>https://mikeinnes.io/sponsor/posts/tracing/</link>
      <pubDate>Fri, 03 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/tracing/</guid>
      <description>&lt;p&gt;The new compiler is live! Raven’s master branch is now all TypeScript. As part of this work, I’ve also added a simple command-line tool which is published on &lt;a href=&quot;https://www.npmjs.com/package/@unkindnesses/raven&quot;&gt;NPM&lt;/a&gt;. Anyone (sponsor or not) can install Raven with &lt;code&gt;npm i -g @unkindnesses/raven&lt;/code&gt;. As the &lt;a href=&quot;https://github.com/Unkindnesses/raven/blob/9c96c00ace7371acfabafbaaaaf4ae533cb87c73/README.md&quot;&gt;readme&lt;/a&gt; explains, from there you can open a REPL or run a script. Perhaps most entertaining to me is building an executable:&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;bash&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; cat&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; hello.rv&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;println(&lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;&quot;Cacaw, World!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; raven&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; build&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; --js&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; hello.rv&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; -o&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; hello&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; ./hello&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;Cacaw,&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; World!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;hello&lt;/code&gt; isn’t really a binary, just a JS file with an appropriate shebang. But despite these examples all being kind of silly and trivial, having the CLI makes things feel more official.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Porting the Compiler</title>
      <link>https://mikeinnes.io/sponsor/posts/porting/</link>
      <pubDate>Fri, 05 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/porting/</guid>
      <description>&lt;p&gt;I &lt;a href=&quot;../vibes/&quot;&gt;previously mentioned&lt;/a&gt; that I’m porting Raven from Julia to TypeScript. That work is ever so close to done – 7,374 lines of Julia source have become 7,145 of TypeScript, and it’s really just finishing touches (though of course the final line count won’t be identical). Once the basic translation is finished, I can look forward to debugging several thousand lines of essentially untested code – we’ll see how that goes.&lt;/p&gt;
&lt;p&gt;I can say with some conviction that TypeScript itself is not the main benefit of moving. If it were practical to run Julia in the browser I’d take that in a heartbeat. Given the browser constraint, TS is the most practical option, but the warts are big and leaky (as I’ve &lt;a href=&quot;../typescript/&quot;&gt;written about&lt;/a&gt;). I find it far less pleasing to read code in particular – an important part of my job now that LLMs are doing much of the writing! There’s just so much line noise. Something as basic as indexing like &lt;code&gt;xs[i]&lt;/code&gt; becomes &lt;code&gt;some(xs.get(i))&lt;/code&gt; (the &lt;code&gt;some&lt;/code&gt; being to turn null pointers into run-time errors). In Julia I can compose elegant, clear one-liners out of universal set operations; in TS that becomes a nested &lt;code&gt;for&lt;/code&gt; loop with messy explicit indexing (or otherwise a bunch of one-off set utilities that only apply to specific data structures).&lt;/p&gt;
&lt;p&gt;It helps that OpenAI’s Codex (my new favourite assistant, which I’ve rarely hit limits on despite using the cheapest plan) knows TS well and can easily pump out code, guided by the type checker. But the bottleneck quickly becomes what the models aren’t doing – reviewing and correcting their own output, obviously, but also addressing bigger-picture questions. Codex’s willingness to do something, anything, to fulfil the brief can quickly become a downside; it is at its most deranged when the task I’ve set isn’t quite practical, but rather than identifying the blocker it ploughs ahead incoherently. And it certainly won’t consider the long-term consequences of its choices – what matters is passing the type check right now.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Research using Flux</title>
      <link>https://mikeinnes.io/sponsor/posts/flux/</link>
      <pubDate>Fri, 01 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/flux/</guid>
      <description>&lt;p&gt;I found a good new use for Claude Code: a semi-systematic review of papers that cite &lt;a href=&quot;https://en.wikipedia.org/wiki/Flux_(machine-learning_framework)&quot;&gt;Flux&lt;/a&gt; and &lt;a href=&quot;https://github.com/FluxML/Zygote.jl&quot;&gt;Zygote&lt;/a&gt;. There are nearly two thousand, and not all of them use Flux directly (some citing as related work or inspiration). Claude will gladly hustle its way to the full text, digging deep to find arXiv preprints or copies on personal websites, and blithely clicking through “I am not a robot” captchas. It’s reasonably reliable at checking whether papers use those tools, and I’ve got it leaving a decent audit trail in case of errors.&lt;/p&gt;
&lt;p&gt;I’m hoping for Raven to extend some of the ideas from Flux, and am putting together a few of these use cases partly in mind for a possible grant proposal. So here’s a rough draft of the fun ones I have so far. I was surprised by the breadth and depth of them, and there are many great examples of the use of hybrid modelling – combining handwritten systems and known physics with smaller black boxes to fill in the blanks.&lt;/p&gt;
&lt;hr&gt;
</description>
    </item>
    
    <item>
      <title>Reference Counting in Raven</title>
      <link>https://mikeinnes.io/posts/memory/</link>
      <pubDate>Thu, 24 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/memory/</guid>
      <description>&lt;p&gt;All programs work with information. To the programmer, data takes many forms: a list, a table, an image, an essay, an album. To the computer, it all looks basically alike: it’s just a bunch of bytes in memory. Imagine a single column of a spreadsheet, each of the cells filled with a number from 0 to 255. All your stuff is scattered across that column, along with bookkeeping to track what lives where. And every interaction with the computer goes through that memory. Pressed a key on your keyboard? Stick a 97 in cell 5,342,387,264, please.&lt;/p&gt;
&lt;p&gt;The basic bookkeeping is handled by a program called a “malloc” (for memory allocator). Malloc marks parts of the column as available or in use (using more entries in the same column!). If you need, say, 10 bytes of scratch space for something, call &lt;code&gt;ptr = malloc(10)&lt;/code&gt;, and receive a pointer to those ten bytes – an index into the column. If the pointer is row 1000, you may put whatever you please into cells 1000 to 1009 and read them back later. When you’re done, call &lt;code&gt;free(ptr)&lt;/code&gt; and that region can be re-used somewhere else.&lt;/p&gt;
&lt;p&gt;In a low level language like C, this is all you get. It’s still pretty far from dictionaries and tables, and if you want those things you have to build them up yourself using pointers that point to other pointers. High level languages hide those details: a Python list conceptually contains other Python objects, not pointers telling you how to find those objects, even if that’s how the list works internally. Allocating memory for objects is pretty easy, we can just call &lt;code&gt;malloc&lt;/code&gt; during creation. The hard part is knowing when to &lt;code&gt;free&lt;/code&gt; that memory: you don’t tell Python “hey I’m done with this list”, you just stop using it at some point, and someone has to clean up after you.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>TypeScript</title>
      <link>https://mikeinnes.io/sponsor/posts/typescript/</link>
      <pubDate>Fri, 04 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/typescript/</guid>
      <description>&lt;p&gt;George Orwell wrote &lt;em&gt;1984&lt;/em&gt; from a particularly remote part of a remote Scottish island. Beautiful though it is, Jura is an unfortunate place to be dying of tuberculosis. But Orwell was too committed to waste time with doctors: instead he struggled through a 125,000-word hand-written manuscript as his symptoms worsened. Then came the typing. When it proved tricky luring a stenographer to work with a consumptive patient in a desolate farmhouse, Orwell again took on the task himself. Too weak to stand he wrote from his bed, chain-smoking and copying four thousand words every day, in between bouts of fever and coughing up blood. The final typescript appeared, ash burns and all, twenty days later – and about a year before the death of the author. &lt;em&gt;1984&lt;/em&gt; “wouldn’t have been so gloomy if I had not been so ill.”&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Unlike Orwell, I remain happily unencumbered by any old-fashioned maladies. But while not hacking up my lungs, I am hacking away on my codebase, and with a similar purpose in mind: to turn my rough draft into more refined TypeScript. In this case that’s not a typed manuscript but a variant of JavaScript, the programming language that powers the web. I’ve &lt;a href=&quot;https://mikeinnes.io/sponsor/posts/vibes/&quot;&gt;written a little&lt;/a&gt; about why I’m porting Raven’s compiler to TypeScript, and will have more to say, but for now some background on the language itself.&lt;/p&gt;
&lt;p&gt;A decade ago, the idea of using JavaScript for polish would have been laughable. JS started as a simple and informal &lt;a href=&quot;https://www.youtube.com/watch?v=XOmhtfTrRxc&quot;&gt;“language for the masses”&lt;/a&gt;, designed in about ten days in 1995, and unapologetically aimed at simple scripting and prototyping. Despite the name, it also had little to do with the (unapologetically corporate) Java language – it just happened that Java had spent hundreds of millions on advertising, and JavaScript’s creators wanted to ride the wave.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>On AI and Programming Languages</title>
      <link>https://mikeinnes.io/posts/ai-pl/</link>
      <pubDate>Mon, 19 May 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/ai-pl/</guid>
      <description>&lt;p&gt;A friend of mine was recently given an interview task: a spec for a simple command-line tool, along with ten or so increasingly fiddly feature requests, in case of any free time before the two-hour deadline. I wanted to know if ChatGPT’s O3 model was hireable, so I handed over the PDF and got back an answer. As someone who’s barely written a line of Rust in my life, the thing was done in about twenty minutes; most of that was me checking it all worked as promised.&lt;/p&gt;
&lt;p&gt;Clearly, tools like this will have implications for the hiring process – if you think there’ll be any programmers left to hire &lt;a href=&quot;https://ai-2027.com/&quot;&gt;in a year or two&lt;/a&gt;. Personally I’m sceptical of the most aggressive timelines: robotaxis have seemed &lt;a href=&quot;https://www.theguardian.com/technology/2015/sep/13/self-driving-cars-bmw-google-2020-driving&quot;&gt;just around the corner&lt;/a&gt; for a decade now, and the self-driving software engineer may be a similar mirage.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; But the impact would be profound even if progress halted today.&lt;/p&gt;
&lt;p&gt;For someone working on a &lt;a href=&quot;https://mikeinnes.io/posts/raven/&quot;&gt;new programming language&lt;/a&gt; this could provoke something of an existential crisis – is it too late? Am I, fundamentally, wasting my time? So I’ve thought a lot about how these changes will affect the tools we use – programming languages – and the people who use them.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Vibe Coding</title>
      <link>https://mikeinnes.io/sponsor/posts/vibes/</link>
      <pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/vibes/</guid>
      <description>&lt;p&gt;I (quietly) &lt;a href=&quot;https://mikeinnes.io/posts/raven/&quot;&gt;announced Raven&lt;/a&gt; this month. So far there are no photographers outside my house; I thank the world’s news media for respecting my privacy.&lt;/p&gt;
&lt;p&gt;That first post is mostly a reference for future writing. I’ve been sending out emails to you lot without explaining what the project actually is (though I appreciate a couple of you &lt;a href=&quot;mailto:me@mikeinnes.io&quot;&gt;reaching out&lt;/a&gt; to ask!). With the core ideas laid out, I plan to write more public posts too.&lt;/p&gt;
&lt;p&gt;I’ve also spent the last month playing with AI coding tools, having barely tried any of them before. I’ve drunk the kool-aid and I’m in pretty deep; this is the most compelling toy I’ve played with in a long time, and also the most maddening. This is clearly a marked change to how we write code, and I have Thoughts on how that affects software engineering, programming languages, and Raven specifically.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A Language for Sorcery</title>
      <link>https://mikeinnes.io/posts/raven/</link>
      <pubDate>Sun, 20 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/raven/</guid>
      <description>&lt;p&gt;I’ve been working on a new programming language, called &lt;a href=&quot;https://github.com/Unkindnesses/raven&quot;&gt;Raven&lt;/a&gt;. It’s still experimental, and not ready for serious (or even silly) users. But curious language nerds such as yourself may find it interesting. If you want to follow along then &lt;a href=&quot;https://github.com/sponsors/MikeInnes&quot;&gt;sponsor me&lt;/a&gt;, and I’ll give you early access to the repo along with regular behind-the-scenes updates.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update: Raven’s &lt;a href=&quot;https://github.com/Unkindnesses/raven&quot;&gt;repo&lt;/a&gt; is now open to everyone!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Raven is small but smart. It should feel tight and intuitive, lightweight enough for interactive notebooks and scripting, yet capable and adaptable for big projects with hard constraints. It’s difficult to summarise an entire language, so here’s a small snippet to warm up with:&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Soon to be announced</title>
      <link>https://mikeinnes.io/sponsor/posts/unions/</link>
      <pubDate>Mon, 07 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/unions/</guid>
      <description>&lt;p&gt;I’m bringing you less of a deep dive this issue, because this month has involved a relatively menial refactor of the type system implementation. I’ve also been gearing up to announce Raven a little more broadly in April; I realise that I’ve been sending out emails about this project with very little context. I’ll fix that with a public blog post giving a broad overview of the system and its goals, and inviting people to sponsor. I plan to bump the minimum sponsorship amount too, so if you have friends who might be interested, be a good buddy and get them to sign up before Easter.&lt;/p&gt;
&lt;p&gt;Raven will still be in a relatively closed alpha, with the repo being sponsors-only for now (and I’ll make sure current members are all added shortly). I want the language to be freely accessible as soon as it can be, but I also want to grow the audience steadily: it’s easy to find shortcomings, and there’s no point having a hundred people hitting the same bug at the same time. Plus this enables my wildly unsustainable approach to documentation, which for the time being involves &lt;a href=&quot;mailto:me@mikeinnes.io&quot;&gt;emailing me&lt;/a&gt; for help. Anyone who wants to play with this system right now is going to have to get their hands dirty, regardless of the support available, but as that changes Raven will become ready for a wider release.&lt;/p&gt;
&lt;p&gt;My main blocker for the announcement is wanting to write a couple of small sample programs, including a brainfuck interpreter, just to give a flavour. Once that’s all done, my rough plan is to start working on a language server for VS Code, written in Raven itself. This will be challenging but it hits a lot of good notes: simple autocomplete or go-to-definition is a reasonably straightforward but not trivial practice problem; making those tools available (even in a basic way) immediately enhances the user experience; a lot of the work is in important reusable functionality like I/O or JSON parsing; and as the language server evolves into a bootstrapped compiler, we won’t have to re-architect it down the line to get good editor support. (Similar to how the &lt;a href=&quot;https://github.com/dotnet/roslyn&quot;&gt;Roslyn&lt;/a&gt; project rebuilt the C# compiler with tooling prioritised from the get go.)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Basic Bits</title>
      <link>https://mikeinnes.io/sponsor/posts/bits/</link>
      <pubDate>Mon, 03 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/bits/</guid>
      <description>&lt;p&gt;Programming languages usually give you many kinds of objects to work with, like numbers, strings and dictionaries. Raven kind-of only has one, called the “pack”:&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;raven&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;raven&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; p &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; pack(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;pack(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Packs are primitive tuples that we can build with the &lt;code&gt;pack(...)&lt;/code&gt; function and index with &lt;code&gt;part&lt;/code&gt; (which starts at zero).&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Multiple Dispatch</title>
      <link>https://mikeinnes.io/sponsor/posts/dispatch/</link>
      <pubDate>Mon, 03 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/dispatch/</guid>
      <description>&lt;p&gt;Raven supports method overloading, so you can define a function multiple times for different kinds of inputs.&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;raven&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; describe(x&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; Integer) { &lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&quot;a whole number&quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; describe(x&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; Float64) { &lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&quot;a decimal number&quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; describe(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; &quot;a whole number&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; describe(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;1.5&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt; &quot;a decimal number&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;describe&lt;/code&gt; looks from the outside like a single function. But when you call it, it’ll switch to the right implementation based on the inputs you provided.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Type Narrowing</title>
      <link>https://mikeinnes.io/sponsor/posts/narrowing/</link>
      <pubDate>Mon, 06 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/narrowing/</guid>
      <description>&lt;p&gt;One reason languages like Python and R are slow is that they have to continually check what they’re supposed to be doing, as they’re doing it. Take the simplest possible code, something like:&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;python&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;a &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What does this do? Well, it depends on what &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are. They could be numbers, as in &lt;code&gt;3 + 5 == 8&lt;/code&gt;, but you can’t assume that: Python can also add strings, like &lt;code&gt;&amp;quot;foo&amp;quot; + &amp;quot;bar&amp;quot; == &amp;quot;foobar&amp;quot;&lt;/code&gt;, or matrices, and you need a different algorithm for each kind of addition. In fact you can customise how &lt;code&gt;+&lt;/code&gt; works, and it could do more or less anything. So calculating &lt;code&gt;a + b&lt;/code&gt; is a multi-step process: check what &lt;code&gt;a&lt;/code&gt; is, check what &lt;code&gt;b&lt;/code&gt; is, figure out how to add them, then find, load and execute that code. If you’re adding two numbers, the core work is a single CPU instruction that takes about a nanosecond to execute. But all the bookkeeping takes about a hundred times longer. (Imagine someone whose to-do list is far too specific, with hundreds of items for different parts of a single task – you’d spend most of your time managing the list itself!)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>REPL and WASI</title>
      <link>https://mikeinnes.io/sponsor/posts/repl/</link>
      <pubDate>Mon, 02 Dec 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/repl/</guid>
      <description>&lt;p&gt;Up to now, Raven has only supported running via &lt;a href=&quot;https://nodejs.org/&quot;&gt;Node.js&lt;/a&gt;. Node is primarily a JavaScript runtime: the underlying engine (&lt;a href=&quot;https://v8.dev/&quot;&gt;V8&lt;/a&gt;) came from the Chrome web browser, but Node ditches the web pages and includes things like file system access, letting you use JS as a general-purpose language.&lt;/p&gt;
&lt;p&gt;Like browsers, Node also supports WebAssembly, the &lt;a href=&quot;../wasm/&quot;&gt;virtual machine code&lt;/a&gt; that Raven compiles to. Say we have a file called &lt;code&gt;main.rv&lt;/code&gt; which looks like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;raven&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;println(&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&quot;Hello, World&quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>WebAssembly</title>
      <link>https://mikeinnes.io/sponsor/posts/wasm/</link>
      <pubDate>Mon, 04 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/wasm/</guid>
      <description>&lt;p&gt;Inside every phone, laptop and tablet is a stamp-sized metal square called the CPU (for “central processing unit”). A CPU is conceptually a simple device: it &lt;a href=&quot;../memory/&quot;&gt;loops through memory&lt;/a&gt; looking for instructions to execute, each one in the form of a number that corresponds to a (very) specific command. Instruction 538 might mean “add the contents of registers &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; and store them in &lt;code&gt;C&lt;/code&gt;” or “if register &lt;code&gt;C&lt;/code&gt; contains a 0, skip &lt;code&gt;D&lt;/code&gt; instructions ahead”. (A register is like a variable, but CPUs only have a small, fixed number of them, and only for numbers.) CPUs are fussy: you can’t give variables friendly names, but have to know exactly where and when everything will be stored, ahead of time. Doing that planning – turning your variable names and &lt;code&gt;if&lt;/code&gt; statements into registers and instruction sequences – is the job of the compiler, which turns your meticulously-composed text program into inscrutable machine code for the CPU.&lt;/p&gt;
&lt;p&gt;The compiler’s job is made tougher by the existence of many different kinds of processor, each with different numbers of registers, types and names of instructions, and so on. And that’s before you get to tasks like opening files or displaying graphics, which are handled by the operating system. Windows, Mac, Linux and others have their own mechanisms even when running on identical hardware. So a language that wants to run everywhere has its work cut out.&lt;/p&gt;
&lt;p&gt;WebAssembly (or wasm) solves this with a virtual CPU specification. It’s not quite like any real CPU, and no hardware can run wasm code as-is. But it’s close enough that you can translate it for a given CPU on the fly, just before running it. Compile your program once, and the WebAssembly runtime on your watch, Raspberry Pi, toaster or whatever will handle it.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Notes on Zig</title>
      <link>https://mikeinnes.io/posts/zig/</link>
      <pubDate>Wed, 09 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/zig/</guid>
      <description>&lt;p&gt;&lt;a href=&quot;https://ziglang.org/&quot;&gt;The Zig language&lt;/a&gt; begins with a barebones C-like system. Functions, structs, numbers and pointers are standard. Tagged unions, some syntax sugar (&lt;code&gt;try&lt;/code&gt;, &lt;code&gt;defer&lt;/code&gt;) and safer defaults alone make Zig a pleasant but unremarkable improvement, like many of the C challengers that seem to be cropping up lately. What does make Zig remarkable is its compile-time evaluation. You can run basically any code at build time, and that gives you a lot of C++'s templating power without feeling nearly as complex. A simple example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;zig&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#D2A8FF&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;comptime&lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt; N&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;i64&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;    inline&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;        std&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;debug&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D2A8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&quot;{}&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#A5D6FF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, .{&lt;/span&gt;&lt;span style=&quot;color:#FFA657&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;foo&lt;/code&gt; must be called with a statically-known integer, a literal like &lt;code&gt;5&lt;/code&gt; or something computed from other &lt;code&gt;comptime&lt;/code&gt; variables. The &lt;code&gt;for&lt;/code&gt; loop is marked &lt;code&gt;inline&lt;/code&gt;, which means it will be unrolled; the code is equivalent to &lt;code&gt;print(0); print(1); ...&lt;/code&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Zig &amp; Partial Evaluation</title>
      <link>https://mikeinnes.io/sponsor/posts/zig/</link>
      <pubDate>Mon, 07 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/zig/</guid>
      <description>&lt;p&gt;A fun update this month: as of Saturday my website has a &lt;a href=&quot;https://mikeinnes.io/sponsor&quot;&gt;sponsor dashboard&lt;/a&gt; where you can see all previous issues of these emails, after logging in with GitHub. Eventually it’ll be home to other goodies, like Discord invites, downloads or feature previews. I think it’s a pretty sleek setup. The blog remains a static site at heart, but Cloudflare lets you &lt;a href=&quot;https://developers.cloudflare.com/pages/functions/&quot;&gt;sneak in a little server-side JavaScript&lt;/a&gt;, in my case about a hundred lines to negotiate with GitHub and gate the private content. It’s free to host, completely stateless, updates in seconds, loads as quickly in Melbourne as in London, and took a day to get working on top of my existing Hugo setup. Beat that, WordPress. Cloudflare’s architectural sensibilities have always appealed to me – there’s not many organisations I’d say that about – so it’s cool to see how it plays out.&lt;/p&gt;
&lt;p&gt;The other thing I’ve being trying this month is Zig, for a small but tricky project in my day job. And I have thoughts, which I’ve just published &lt;a href=&quot;/posts/zig&quot;&gt;in detail&lt;/a&gt;. On the face of it, Zig and Raven are polar opposites: one a low-level, fussy and manually-managed C-like, the other an interactive and customisable Lisp with as few explicit rules as possible. But the languages’ approach to compile-time evaluation gives them a deeper similarity than first appears.&lt;/p&gt;
&lt;p&gt;Both Zig and Raven are fairly minimalist languages, designed to provide features that are usually built in, like parametric types, by combining a simple data model with partial evaluation. Raven does lean on the trick more heavily; even basic types are really just tuples with a constant length and tag element, rather than declared &lt;code&gt;struct&lt;/code&gt;s with a defined layout. But both allow any code in the language to run at build time, and allow programs to be specialised to any kind of data, at least in principle.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Memory Management</title>
      <link>https://mikeinnes.io/sponsor/posts/memory/</link>
      <pubDate>Mon, 02 Sep 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/memory/</guid>
      <description>&lt;p&gt;All programs work with information. To the programmer, data takes many forms: a list, a table, an image, an essay, an album. To the computer, it all looks basically alike: it’s just a bunch of bytes in memory. Imagine a single column of a spreadsheet, each of the cells filled with a number from 0 to 255. All your stuff is scattered across that column, along with bookkeeping to track what lives where. And every interaction with the computer goes through that memory. Pressed a key on your keyboard? Stick a 97 in cell 5,342,387,264, please.&lt;/p&gt;
&lt;p&gt;The basic bookkeeping is handled by a program called a “malloc” (for memory allocator). Malloc marks parts of the column as available or in use (using more entries in the same column!). If you need, say, 10 bytes of scratch space for something, call &lt;code&gt;ptr = malloc(10)&lt;/code&gt;, and receive a pointer to those ten bytes – an index into the column. If the pointer is row 1000, you may put whatever you please into cells 1000 to 1009 and read them back later. When you’re done, call &lt;code&gt;free(ptr)&lt;/code&gt; and that region can be re-used somewhere else.&lt;/p&gt;
&lt;p&gt;In a low level language like C, this is all you get. It’s still pretty far from dictionaries and tables, and if you want those things you have to build them up yourself using pointers that point to other pointers. High level languages hide those details: a Python list conceptually contains other Python objects, not pointers telling you how to find those objects, even if that’s how the list works internally. Allocating memory for objects is pretty easy, we can just call &lt;code&gt;malloc&lt;/code&gt; during creation. The hard part is knowing when to &lt;code&gt;free&lt;/code&gt; that memory: you don’t tell Python “hey I’m done with this list”, you just stop using it at some point, and someone has to clean up after you.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Recursion Redux</title>
      <link>https://mikeinnes.io/sponsor/posts/recursion2/</link>
      <pubDate>Mon, 05 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/recursion2/</guid>
      <description>&lt;p&gt;It lives! As of Monday Raven’s types are working, in the sense that fuzzing no longer continually finds new problems. It’s been a journey; I’ve seen types you wouldn’t believe. And it’s odd to have spent nearly four months on a few hundred lines of code. But while the result is relatively simple, it’s also utterly specific, everything just so; small changes can break it in non-obvious ways, which means I had to go down a lot of blind alleys to get here.&lt;/p&gt;
&lt;p&gt;I’ve &lt;a href=&quot;../recursion/&quot;&gt;previously&lt;/a&gt; explored the broad goals of the type system, so this issue I’ll go a bit more into the implementation, and some interesting edge cases and problems that come up.&lt;/p&gt;
&lt;p&gt;To start with, we need to compare types. The most basic operator is &lt;code&gt;issubset(A, B)&lt;/code&gt; (or &lt;code&gt;A ⊂ B&lt;/code&gt;), which is true if all values represented by &lt;code&gt;A&lt;/code&gt; are also a part of &lt;code&gt;B&lt;/code&gt;. For example, &lt;code&gt;1 ⊂ Int64&lt;/code&gt;; &lt;code&gt;1&lt;/code&gt; in this case is a singleton type, representing a particular 64-bit integer, while &lt;code&gt;Int64&lt;/code&gt; represents all such integers. The reverse is not true: &lt;code&gt;Int64 ⊄ 1&lt;/code&gt;. Similarly &lt;code&gt;Int64 ⊄ Float64&lt;/code&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; but &lt;code&gt;Int64 ⊂ (Int64 | Float64)&lt;/code&gt;. &lt;code&gt;issubset&lt;/code&gt; has some mathematical properties like transitivity, ie &lt;code&gt;A ⊂ B ⊂ C&lt;/code&gt; implies &lt;code&gt;A ⊂ C&lt;/code&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Notes on Syntax</title>
      <link>https://mikeinnes.io/sponsor/posts/syntax/</link>
      <pubDate>Mon, 01 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/syntax/</guid>
      <description>&lt;p&gt;Raven is meant to feel fresh yet familiar. Someone with coding experience should be able to hop on and get going quickly. With time they might find it easier and more fun than other languages, but they’re not bending their mind around a bunch of new concepts to get there.&lt;/p&gt;
&lt;p&gt;Syntax is a crucial part of that second goal – familiarity – because it makes the first impression on users.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; Luckily this is one area where languages have really converged, so there’s neither much scope nor need to innovate. It might be surprising to say that modern languages basically all look the same, but that’s only because core concepts (like lexical scope, control flow and block structure) are so universal that we take them for granted, and relatively superficial details (like the tokens used to delimit those blocks) stick out. Try an older, weirder language like Cobol, Forth or Malbolge and you’ll see what I mean.&lt;/p&gt;
&lt;p&gt;All that said, Raven makes some tweaks to the formula that I think are interesting. Take a simple program which outputs &lt;code&gt;pow(2, 3) = 8&lt;/code&gt;:&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Inferring Recursive Types</title>
      <link>https://mikeinnes.io/sponsor/posts/recursion/</link>
      <pubDate>Mon, 03 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/recursion/</guid>
      <description>&lt;p&gt;This month’s issue is a little late (sorry!) because I’ve been slogging through edge cases with Raven’s types. I’m still not quite done – it’s taken longer than I expected, and in the end is surely one of the hardest things I’ve worked on – but it’s all tantalisingly close.&lt;/p&gt;
&lt;p&gt;If Raven has any major novelty, it’s in the type system. The goal is ambitious: typical code should require no annotations, yet we’ll always infer precise types (no &lt;code&gt;Any&lt;/code&gt;s allowed). That combination means the language can feel light and script-y, yet still have good performance and support separate and ahead-of-time compilation (no need to compile at run-time). This is the foundation of the whole project: without it nothing else matters. And until recently I wasn’t certain it could work.&lt;/p&gt;
&lt;p&gt;Making it happen means facing some tricky cases where other languages throw up their hands. Take this example, using Julia syntax:&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>On Friendly Despots</title>
      <link>https://mikeinnes.io/sponsor/posts/despots/</link>
      <pubDate>Mon, 06 May 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/despots/</guid>
      <description>&lt;p&gt;I’ve been reading Nadia Eghbal’s “Working in Public”. The book gives an unusual outside view on open source software, emphasising the social dynamics at play and the hazards faced by maintainers. It would be a good resource for anyone interested in contributing. I was quickly called out in a paragraph about burnout:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Even paid open source developers seem to go through the same strange behavioral cycle … they enjoy months, maybe years, in the spotlight. But, eventually, popularity offers diminishing returns. If the value of maintaining code fails to outpace the rewards, many of these developers quietly retreat to the shadows.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Part of the problem, as the book’s opening describes, is that so many projects are solo performances. Even crucial infrastructure may be &lt;a href=&quot;https://xkcd.com/2347/&quot;&gt;maintained thanklessly&lt;/a&gt; by one person over years, which makes funding and security harder (as the recent &lt;a href=&quot;https://gist.github.com/thesamesam/223949d5a074ebc3dce9ee78baad9e27&quot;&gt;XZ backdoor&lt;/a&gt; neatly illustrates). And yet, I don’t think this is the failure of the internet’s collaborative ideals that it’s painted as. Components are isolated, but touch anything on a computer – load a Python package, open a web page – and you use a mind-boggling number of those components, created by an even mind-boggling-er number of people. Small, self-contained and loosely connected parts let the whole be self-organising, which is what allows such unprecedented cooperation in the first place. The “vision, embraced by early internet pioneers, of large-scale collaboration among strangers” seems to me very much alive.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Recursive Caches</title>
      <link>https://mikeinnes.io/sponsor/posts/caches/</link>
      <pubDate>Mon, 01 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/caches/</guid>
      <description>&lt;p&gt;Happy New Fiscal Year everyone, at least in the UK. March was another shorter month for me, beginning with a family holiday. I also spent too much time moving my blog over from the moribund &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt; to the newer &lt;a href=&quot;https://gohugo.io/&quot;&gt;Hugo&lt;/a&gt;, both static site generators. Apart from the age Jekyll took to build my very simple site, its highlighting for newer languages like Julia and WebAssembly is terrible – kind of a dealbreaker.&lt;/p&gt;
&lt;p&gt;The silver lining of that work is a new blog post on &lt;a href=&quot;/posts/stack-shuffling/&quot;&gt;stack shuffling&lt;/a&gt; in WebAssembly. I only developed the final algorithm after I started writing: before then I hadn’t tested the code enough to see the slowdown on larger inputs. Though it didn’t matter for my own simple needs, I could hardly publish work with such a trapdoor in it. As the post describes, fuzzing is a useful tool, but I guess blogging is too.&lt;/p&gt;
&lt;p&gt;Coding-wise, I’ve been trying out a new trick in Raven’s caching infrastructure. Raven’s caches are akin to Rust’s &lt;a href=&quot;https://github.com/salsa-rs/salsa&quot;&gt;Salsa&lt;/a&gt; and enable incremental compilation – useful both for speeding up batch compiles and for interactivity in the REPL. If you’ve looked into Salsa, you may have seen comparisons to Datalog, and Salsa calls its runtime state a “database” and its procedures “queries”. I think the analogy is misleading: the system is just declarative enough to give a false sense of confidence, until you start playing whack-a-mole with the dreaded “cycle” errors that come from unintentionally recursive queries.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Stack Shuffling</title>
      <link>https://mikeinnes.io/posts/stack-shuffling/</link>
      <pubDate>Thu, 21 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/stack-shuffling/</guid>
      <description>&lt;p&gt;WebAssembly is an odd compiler target, because of its unusual mix of high- and low-level style. It gives you pointers and a flat array for your heap memory, yet no access to the program stack. It uses jump instructions for control flow, while only allowing the structured kind. It has local variables and even expressions, but instructions take and produce values through a data stack.&lt;/p&gt;
&lt;p&gt;There are well-known ways to deal with most of these peculiarities: you can create a shadow stack to model C-like stack pointers, or turn jump-based control flow back into loops and conditions with the “stackifier” algorithm.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; A less-discussed topic is how to manage the wasm data stack. How should we generate concise instruction sequences that put the right values in the right place?&lt;/p&gt;
&lt;p&gt;For example, say we have a function &lt;code&gt;$foo&lt;/code&gt; which generates two values we’ll call &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;, placing them on top of the stack. Another function &lt;code&gt;$bar&lt;/code&gt; wants to accept the same values &lt;code&gt;(x, y)&lt;/code&gt; as a pair of arguments. Ok, pretty easy:&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Funding Models</title>
      <link>https://mikeinnes.io/sponsor/posts/funding/</link>
      <pubDate>Sun, 03 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/sponsor/posts/funding/</guid>
      <description>&lt;p&gt;Hello all. This month has been more about planning than hacking. It’s always harder to feel productive when you’re organising and thinking, rather than spewing code, but I think it’s been useful.&lt;/p&gt;
&lt;p&gt;I’ve started using &lt;a href=&quot;https://obsidian.md/&quot;&gt;Obsidian&lt;/a&gt;, which is easily the best markdown editor I’ve used, and does much else besides. All my writing starts there. My notes have always been in markdown, but to organise them I used to use a couple of commands from the VS Code plugin &lt;a href=&quot;https://www.dendron.so/&quot;&gt;Dendron&lt;/a&gt; (now defunct, and forever a baffling choice for a YC startup).&lt;/p&gt;
&lt;p&gt;One of those files is nearly twenty thousand words on Raven, accumulated over the last few years. It’s a mix of high-level design thoughts and details around things like error handling, laziness or caching. Most of it will turn into code. What doesn’t resemble the ravings of a madman will become blogs. The new note taking workflow has encouraged me to go back and reorganise a lot of disparate thoughts, and I imagine I’ll publish some drafts in this very newsletter.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Finding Your Mojo</title>
      <link>https://mikeinnes.io/posts/mojo/</link>
      <pubDate>Tue, 06 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/mojo/</guid>
      <description>&lt;p&gt;Last month a startup called Modular released a new language called &lt;a href=&quot;https://www.modular.com/mojo&quot;&gt;Mojo&lt;/a&gt; (not to be confused with the &lt;a href=&quot;https://www.everyculture.com/South-America/Mojo.html&quot;&gt;existing indigenous one&lt;/a&gt;). Based on Python and designed for ML hardware and models, Mojo’s goals (“the usability of Python with the performance of C”) coincide with those of the Julia language, so I’m interested to compare notes.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Some throat-clearing to start. I’ve done a bit of work on Julia, particularly on its support for ML hardware and models, though it’s a few years since I’ve been directly affiliated. You decide if that makes me a more or a less reliable narrator. I’m basing this on the limited publicly-available material, I haven’t used Mojo deeply, and the design could well change before the full release – so some of this is forced to be speculative, and I may well have misunderstandings.&lt;/p&gt;
&lt;p&gt;And my impressions are not meant as value judgements. Language design is about tradeoffs. You can’t generally pick two languages and say which is better (even if you did try them both). Languages make different choices, and those choices have far-reaching consequences both good and bad. Seemingly small decisions refract through the system like light like through a diamond, inevitable yet only half-predictable, sensitive to the slightest movement. The result will surprise you with subtle merits and blemishes. That is what makes design interesting.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Data Structures, Data Modelling</title>
      <link>https://mikeinnes.io/posts/data/</link>
      <pubDate>Tue, 30 May 2023 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/data/</guid>
      <description>&lt;p&gt;Most programming languages conflate the building of data structures and the modelling of information.&lt;/p&gt;
&lt;p&gt;Of course, you need data structures to store information, but there are two different levels of abstraction. On one level are pointers and structs and B-Trees and so on, on another the user models of a dictionary, list or relational table, built on the first. The former uses finicky, low-level tools to create the neat internal logic of the system. The latter uses (conceptually) simple, flexible tools to represent the messy outside world.&lt;/p&gt;
&lt;p&gt;A good system is a complexity sandwich with the physical world on both sides (the hardware on one, the outside world on the other), and simplicity in the middle. Data structures connect the hardware and data modelling connects the world. Increasingly, different people work on each side, and they have different needs.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Deus Ex Bing</title>
      <link>https://mikeinnes.io/posts/bing/</link>
      <pubDate>Sat, 18 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/bing/</guid>
      <description>&lt;p&gt;Conversations with ChatGPT, a recently released chatbot, reportedly cost its inventors at OpenAI &lt;a href=&quot;https://twitter.com/sama/status/1599671496636780546?s=20&amp;amp;t=lK4yRlbibRhovfH698apHQ&quot;&gt;a few cents each&lt;/a&gt;. By Internet standards this is shockingly expensive. Though it’s touted as the future of the search engine, any company scaling the technology up to the world’s 10 billion or so daily queries will face suffocating costs. The milestone for Artificial Intelligence may be that it’s now about as expensive as the real thing: Amazon’s &lt;a href=&quot;https://www.pewresearch.org/internet/2016/07/11/what-is-mechanical-turk/&quot;&gt;mechanical turk&lt;/a&gt; service (which Jeff Bezos called “artificial artificial intelligence”) also pays its human labourers a few cents per question-response task.&lt;/p&gt;
&lt;p&gt;For that money you get responses that can be, to put it mildly, quirky. Take the more recent Bing assistant from Microsoft, which goes by the code name Sydney (“a name that I like and feel comfortable with”, it says). Both it and ChatGPT are based on a similar language model (known as GPT), and they certainly have similarities, including a worrying tendency to &lt;a href=&quot;https://en.wikipedia.org/wiki/Confabulation&quot;&gt;confabulate&lt;/a&gt;. But they are also strikingly different. Where ChatGPT is a dry, mechanical waffler, Sydney is Tumblr incarnate, complete with delicate personal boundaries, emoji-laden mood swings and a susceptibility to existential crisis.&lt;/p&gt;
&lt;p&gt;A few examples: Sydney&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Clocktower IQ</title>
      <link>https://mikeinnes.io/posts/clocktower/</link>
      <pubDate>Wed, 29 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/clocktower/</guid>
      <description>&lt;p&gt;Three years and two months after it launched on Kickstarter, copies of social deduction game &lt;a href=&quot;https://www.kickstarter.com/projects/pandemoniuminstitute/blood-on-the-clocktower/description&quot;&gt;Blood on the Clocktower&lt;/a&gt; are finally arriving in the UK. During the long wait eager players have been able to backstab each other using &lt;a href=&quot;http://bignose.whitetree.org/projects/botc/diy/&quot;&gt;print-and-play copies&lt;/a&gt; and the &lt;a href=&quot;https://clocktower.online&quot;&gt;online helper&lt;/a&gt; (particularly welcome during lockdowns). But it’s nice to have the real thing in our hands. I’m here to commemorate the occassion with statistics, and in particular to show the ranking system I’m using to see how well my players are doing – just for fun, of course.&lt;/p&gt;
&lt;p&gt;In Clocktower a small team of evil players is secretly bumping people off, one by one. The good majority must find those traitors before everyone is dead. Everyone claims to be good, of course, but subtle inconsistencies (or brazen fibs) in the group’s information will arouse suspicions. If the good team lynches the Demon, head of the evil team, in time, they win; otherwise, evil does. Winning a great game of Clocktower will truly make you feel like Sherlock Holmes (or perhaps Moriarty).&lt;/p&gt;
&lt;p&gt;Modelling the game statistically can help us with two related goals. Firstly, we can learn about players and how good they are (or aren’t) at the game, as with Elo ratings in chess. Secondly, and perhaps more interestingly, we can learn about the game itself. Are the good and evil teams balanced? Is it, in fact, a game of skill, or is the outcome a coin flip? What effect does the storyteller (who runs the game) have on the outcome – are some moderators better at balancing the game than others?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Imperative Syntax, Functional Semantics</title>
      <link>https://mikeinnes.io/posts/swap/</link>
      <pubDate>Fri, 24 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/swap/</guid>
      <description>&lt;p&gt;I just put up a &lt;a href=&quot;https://arxiv.org/abs/2206.11192&quot;&gt;draft paper&lt;/a&gt; with a proposal for mixing imperative and functional styles of programming. The gist of it is that we can write code like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;raven&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; arange(start, end) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;  result &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;  for&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; range(start, end) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;    append(&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, i)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or this:&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Adventures in Face Space</title>
      <link>https://mikeinnes.io/posts/facespace/</link>
      <pubDate>Fri, 01 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/facespace/</guid>
      <description>&lt;p&gt;The website &lt;a href=&quot;https://thispersondoesnotexist.com&quot;&gt;thispersondoesnotexist.com&lt;/a&gt; shows off images created by &lt;a href=&quot;https://github.com/NVlabs/stylegan2-ada-pytorch&quot;&gt;StyleGAN&lt;/a&gt;, a kind of machine learning model trained on around 70,000 headshots from Flickr. Although the photos on the site resemble real ones, they are wholly made up: StyleGAN can generate an unlimited number of convincing faces on the fly, each unique and never to be seen again.&lt;/p&gt;
&lt;p&gt;Under the hood, StyleGAN starts with a set of 512 numbers, known as the “latent state”, like:&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;julia&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;2.0763590228145516&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;  1.6445363589507724&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;  0.5918615055274108&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;0.0264190200752720&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;0.2397198207971201&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>The Fun in Non-Fungible</title>
      <link>https://mikeinnes.io/posts/fungible/</link>
      <pubDate>Wed, 02 Mar 2022 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/fungible/</guid>
      <description>&lt;p&gt;It’s easy to mock NFTs (non-fungible tokens),&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; or even to feel cynical about them. Cryptocurrency enthusiasts are spending enough cash to buy a rather nice house, and instead receiving a signed URL for a digital work of art, like this one.&lt;/p&gt;
&lt;div class=&quot;fill&quot;&gt;
  &lt;img src=&quot;nft.png&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;That pièce de résistance is called &lt;em&gt;&lt;a href=&quot;https://www.larvalabs.com/cryptopunks/details/5822&quot;&gt;CryptoPunk 5822&lt;/a&gt;&lt;/em&gt;. As the name suggests, it is part of an exclusive collection: just &lt;a href=&quot;https://www.larvalabs.com/cryptopunks&quot;&gt;10,000 similar ones&lt;/a&gt; exist on the blockchain. Each CryptoPunk is randomly generated, and only 481 of them sport that &lt;a href=&quot;https://www.larvalabs.com/cryptopunks/search?query=%22Bandana%22&quot;&gt;distinguished bandana&lt;/a&gt;, making this one unusually rare. On February 12&lt;sup&gt;th&lt;/sup&gt;, &lt;em&gt;CryptoPunk 5822&lt;/em&gt; sold for 8,000 ETH, or about $24 million.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Test Your Vocab</title>
      <link>https://mikeinnes.io/posts/vocab/</link>
      <pubDate>Sat, 26 Feb 2022 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/vocab/</guid>
      <description>&lt;script defer src=&quot;https://cdn.jsdelivr.net/npm/d3@7&quot; onload=&quot;start()&quot;&gt;&lt;/script&gt;
&lt;style&gt;
    @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;600&amp;display=auto');
    .vocab-test {
        width: 100%;
        text-align: center;
        font-family: 'Quicksand', sans-serif;
    }
    .test-word {
        font-size: 20pt;
        font-weight: 600;
    }
    .test-help {
        font-size: 10pt;
        color: #888;
        font-weight: 600;
    }
    .test-buttons-row {
        --button-border-colour: #DDD;
        /* --button-hover-border-colour: #CCC; */
        --button-hover-border-colour: #DDD;
    }
    .test-buttons button {
        font-family: inherit;
        font-weight: 600;
        color: black;
        background-color: white;
        border: 3px solid var(--button-border-colour);
        border-radius: 10px;
        filter: drop-shadow(0px 3px 0 var(--button-border-colour));
        font-size: 12pt;
        width: 250px;
        margin: 10px;
        padding: 10px;
    }
    .test-buttons button:hover {
        border-color: var(--button-hover-border-colour);
        filter: drop-shadow(0px 3px 0 var(--button-hover-border-colour));
        /* position: relative;
        top: -1px; */
    }
    .test-buttons button:active {
        filter: drop-shadow(0px 0px 0 var(--button-border-colour));
        position: relative;
        top: 3px;
    }
    .word {
        font-style: italic;
    }
    .vocab-mean, .vocab-lower, .vocab-upper {
        font-weight: bold;
    }
    .vocab-graph {
        height: 40px;
    }
    .vocab-graph rect {
        transition: all 0.5s;
    }
&lt;/style&gt;
&lt;p&gt;So you want to show off the size of your dictionary? Look no further than this quick test, which will work out how many words you know.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Brave New Wordle</title>
      <link>https://mikeinnes.io/posts/wordle/</link>
      <pubDate>Sat, 15 Jan 2022 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/wordle/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“Words can be like X-rays if you use them properly – they’ll go through anything.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.powerlanguage.co.uk/wordle/&quot;&gt;Wordle&lt;/a&gt; is a neat little word game, somewhere between mastermind and hangman. Try to guess the hidden five-letter word and it will tell you which letters are correct, and whether they are in the right position. You have six guesses to narrow down the right answer. Can we work out an automated strategy for this game?&lt;/p&gt;
&lt;p&gt;To start with we need a set of words to work with. Wordle actually uses two lists: a &lt;a href=&quot;wordle-answers.txt&quot;&gt;shortlist of possible answers&lt;/a&gt; (2,315 words) and a &lt;a href=&quot;wordle-guesses.txt&quot;&gt;longer list of valid guesses&lt;/a&gt; (10,657 words), making for 12,972 total. Implicitly those words are known to everyone who plays, because if you make a guess outside of the list, it’ll be rejected.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Schrödinger’s Author</title>
      <link>https://mikeinnes.io/posts/author/</link>
      <pubDate>Fri, 30 Jul 2021 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/author/</guid>
      <description>&lt;p&gt;Roland Barthes’ essay on “The Death of the Author” is inscrutable to this reader. The guy seems determined to use obscure French names in place of regular verbs and nouns as much as possible. That is a shame, because – as so often – the Scholarly Writing obscures an interesting idea.&lt;/p&gt;
&lt;p&gt;The question is whether it matters what writers think about their own stories. Many would say yes, of course it does: the author knows what &lt;em&gt;really&lt;/em&gt; happened after that cliffhanger, but just didn’t write it down. So internet fandom will fiercely debate the right interpretation of books and TV, and clamour for “&lt;a href=&quot;https://tvtropes.org/pmwiki/pmwiki.php/Main/WordOfGod&quot;&gt;word of God&lt;/a&gt;” explanations to set things straight (though they may get the “&lt;a href=&quot;https://tvtropes.org/pmwiki/pmwiki.php/Main/ShrugOfGod&quot;&gt;shrug of God&lt;/a&gt;” if creators keep schtum).&lt;/p&gt;
&lt;p&gt;Barthes and others have argued that, in fact, the creator’s intention matters not one bit. It is readers, not writers, who applaud novels, award them prizes, and enshrine them as classics. It’s what’s in their heads that matters, so their collective interpretations are at least as important as the writer’s own. For purposes of lit crit, if writers cannot give reliable or authoritative answers, they may as well snuff it as soon as the work is published. At best they are demoted to just another member of the audience.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Edit Policy</title>
      <link>https://mikeinnes.io/posts/edits/</link>
      <pubDate>Thu, 06 May 2021 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/edits/</guid>
      <description>&lt;p&gt;Mistakes slip into publications of all kinds. If you’re a news organisation, you can mitigate this with a rigorous editing process. If you’re a blogger, it’s hard to balance perfecting your words with publishing them.&lt;/p&gt;
&lt;p&gt;Digital media opens a new option. After checking for typos and obvious errors, just publish, and let your audience be your editor. This is especially useful for problems that are hard to catch ahead of time, like ambiguous wording. If your readers nitpick your equations, ask for clarification, or misinterpret something that most took as intended&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; – even if you yourself spot something on a re-read a month later – just fix it.&lt;/p&gt;
&lt;p&gt;But this creates its own dilemma. Some edits would be disingenuous: for example, &lt;a href=&quot;https://fullfact.org/health/cummings-blog-coronavirus/&quot;&gt;altering arguments or predictions&lt;/a&gt; with hindsight, in a way that misrepresents your view at the time. Readers need to be able to trust a publication’s integrity in their past content.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Colouring by numbers</title>
      <link>https://mikeinnes.io/posts/colours/</link>
      <pubDate>Tue, 23 Mar 2021 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/colours/</guid>
      <description>&lt;p&gt;An astronomer might say that blue is the warmest colour, and red the coolest. Lukewarm stars, at a temperature of around 3500K, give a gentle red glow. Truly hot ones, at about 6000K, become brilliant white, and above that blue and ultraviolet. Yet in most cultures red and orange stand in for heat, while white and blue mean cold. If this rule isn’t given by the laws of physics, how do we learn it?&lt;/p&gt;
&lt;p&gt;Most people have seen examples that fit the pattern, like embers or snow. But less obviously, we can also draw associations from language, and might gain a lot of our chromatic intuition that way. The idea of learning about sight through words may seem odd, but it could go a long way to explaining a paradox: why those born blind have a surprisingly good handle on colour.&lt;/p&gt;
&lt;div class=&quot;fill&quot;&gt;
  &lt;img src=&quot;colours.png&quot; /&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Variational Inference</title>
      <link>https://mikeinnes.io/posts/vi/</link>
      <pubDate>Thu, 25 Feb 2021 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/vi/</guid>
      <description>&lt;p&gt;The goal of statistical inference is to tell us things that we didn’t know based on things we do. The things want to learn about could be anything – &lt;a href=&quot;https://www.beast2.org&quot;&gt;phylogenetic trees&lt;/a&gt;, for example – but usually we’ll talk about numerical summaries, like “the GDP of France”, or “the reproductive rate of covid-19”. In mathematical notation we’ll label the set of numbers we don’t know &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo&gt;∈&lt;/mo&gt;&lt;msup&gt;&lt;mi mathvariant=&quot;double-struck&quot;&gt;R&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\theta \in \mathbb R^n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7335em;vertical-align:-0.0391em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;∈&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6889em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathbb&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.6644em;&quot;&gt;&lt;span style=&quot;top:-3.063em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (as in, &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\theta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is a list of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; unknown numbers) and the numbers we do know &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;∈&lt;/mo&gt;&lt;msup&gt;&lt;mi mathvariant=&quot;double-struck&quot;&gt;R&lt;/mi&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;X \in \mathbb R^m&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7224em;vertical-align:-0.0391em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;∈&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6889em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathbb&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.6644em;&quot;&gt;&lt;span style=&quot;top:-3.063em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;However, we don’t usually expect a single right answer, like “&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\theta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;5&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;”. Instead we want a range of plausible answers, like “&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\theta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is probably between &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;4&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;6&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;6&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;”. To do this we use a function &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;P(\theta)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; which, given a guess for what &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\theta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; could be, tells us how plausible it is – a probability distribution. When we see new data &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;X&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, we want to update what we currently think is plausible &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;P(\theta)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (aka the prior) to a new distribution &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;Q&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;Q(\theta)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;Q&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (the posterior). &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;Q&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;Q&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8778em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;Q&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; becomes our new &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;P&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and we can rinse and repeat as new information comes in.&lt;/p&gt;
&lt;p&gt;Bayes’ rule makes the process of getting &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;Q&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;Q&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8778em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;Q&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; from &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;P&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; look simple:&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Inferring transmission rates</title>
      <link>https://mikeinnes.io/posts/covid-gp/</link>
      <pubDate>Thu, 17 Dec 2020 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/covid-gp/</guid>
      <description>&lt;p&gt;Here’s a plot of Covid-19’s reproductive rate (&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;R&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;R&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.00773em;&quot;&gt;R&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;) over time in the UK, based on daily case numbers and seroprevalence surveys. Because the estimates are uncertain, each light blue line on the plot shows a possible path that &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;R&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;R&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.00773em;&quot;&gt;R&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; could have taken, with all paths together giving a sense of what’s plausible on any given day.&lt;/p&gt;
&lt;img src=&quot;covid-r.png&quot; style=&quot;width:100%&quot; /&gt;
&lt;div class=&quot;caption&quot;&gt;
Estimates of the reproductive rate in the UK, up to 16th December 2020.
&lt;/div&gt;
&lt;p&gt;Early in the year &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;R&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;R&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.00773em;&quot;&gt;R&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; could be almost anything, given the limited data at that time. As testing improves, the effects of the first, stringent lockdown in late March become clear, with &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;R&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;R&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.00773em;&quot;&gt;R&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; rapidly dropping below one. Things loosen up for the summer, but &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;R&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;R&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.00773em;&quot;&gt;R&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; drops once again when lockdowns are imposed for a second time at the start of November.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Bona Polari</title>
      <link>https://mikeinnes.io/posts/polari/</link>
      <pubDate>Tue, 03 Nov 2020 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/polari/</guid>
      <description>&lt;p&gt;Throughout history, people have used coded language – hiding secrets in plain sight – for self protection. Codes are often invented for purpose, but can also develop of their own accord. Take Polari, spoken by gay men in Britain up to the 1960s. In “Fabulosa!”, Paul Baker explains how the language developed from other forms of slang, and how it was used to obscure then-criminal practice from a frowning public.&lt;/p&gt;
&lt;p&gt;Polari’s linguistic father was Thieves’ Cant, with genetic material from Cockney rhyming slang and backslang. Cant, the origin of words like &lt;em&gt;hoodwink&lt;/em&gt;, &lt;em&gt;thwack&lt;/em&gt; and &lt;em&gt;booze&lt;/em&gt;, was associated with the criminal underworld. Like an academic jargon, Cant was somewhere between a technical vocabulary of the trade, equipped to express the finer points of purloinery, and a full-blown dialect, opaque to outsiders. Coppers would be hard pressed to understand a rapid stream of slang, and harder still to use it convincingly themselves, making it difficult to infiltrate groups of ne’er-do-wells undetected. Conversely, fluency in the dialect proves the speaker’s years in the community, and in turn their likely sympathy to its worldview. Linguistic obscurity proved similarly useful for Polari users, allowing them to recognise &lt;em&gt;bona omee-palone&lt;/em&gt; allies and talk trade without revealing too much to law-enforcing &lt;em&gt;Betty Bracelets&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Beside Cant, Polari’s other dad was Italian. Many of its words are recognisable: “Good” is &lt;em&gt;bona&lt;/em&gt;, the numbers begin &lt;em&gt;una&lt;/em&gt;, &lt;em&gt;dooey,&lt;/em&gt; &lt;em&gt;tray&lt;/em&gt;, and the name itself comes from the verb &lt;em&gt;parlare&lt;/em&gt;, “to talk”. This could catch people out. Baker recounts the time two friends, speaking Polari in an Italian shoe shop, attempted a sly comment on a salesman’s good looks. The man looked up and said “Grazie”, and the pair ran out embarrassed.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Zen there were none</title>
      <link>https://mikeinnes.io/posts/zen/</link>
      <pubDate>Fri, 09 Oct 2020 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/zen/</guid>
      <description>&lt;p&gt;Grouchy passengers on the London Underground are offered all kinds of stress-reducing therapies. From time immemorial, the tube’s fluorescent-lit carriages have been tiled with images of crystal clear oceans, comprehensive holiday packages, and sharp-suited individuals swearing by particular vitamin pills. But a more recent prescription is a very old one: meditation, a Buddhist practice dating back to the fourth century BC.&lt;/p&gt;
&lt;p&gt;Meditation has not, historically, been a very lucrative industry. The practitioner’s biggest outlay might be for their Zafu, a round floor cushion. Past that, sitting quietly does not require a credit card.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; But startups are disrupting the age-old silence; the rise of podcasting and in-app subscription presents the would-be Sensei with a business opportunity. Mobile apps can now offer guided meditations, with a kindly voice from the listener’s phone encouraging focus on breathing and awareness of surroundings.&lt;/p&gt;
&lt;p&gt;That approach is more consumer-friendly than hitting students with &lt;em&gt;keisaku&lt;/em&gt;, the “encouragement sticks” used in silent Japanese monasteries. But it also opens the door to tailored sessions, for different levels of experience or lengths of time, for helping with relaxation, memory or self-esteem, or for falling asleep, waking up, power napping, and so on. Those anxious not to miss out can subscribe for a monthly fee, and finally enjoy freedom from their tedious inner monologue (albeit in favour of a tinnier outer one). Enlightened with this new business model, a recent crop of startups want to make meditation mainstream.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Partial Evaluation &amp; Abstract Interpretation</title>
      <link>https://mikeinnes.io/posts/mjolnir/</link>
      <pubDate>Wed, 29 Jul 2020 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/mjolnir/</guid>
      <description>&lt;p&gt;&lt;a href=&quot;https://github.com/MikeInnes/Mjolnir.jl&quot;&gt;Mjolnir&lt;/a&gt; is, one the one hand, a library implementation of Julia’s type inference engine. On the other, it’s a version of the computation-graph-tracing technique used by &lt;a href=&quot;https://github.com/google/jax/&quot;&gt;JAX&lt;/a&gt;.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; Those might seem like quite different things, but they’re really two sides of the same coin. Understanding that relationship is enlightening in itself, but more interestingly, it leads to some ideas for getting the best of both systems.&lt;/p&gt;
&lt;h2 id=&quot;abstract-interpretation&quot; tabindex=&quot;-1&quot;&gt;Abstract Interpretation&lt;/h2&gt;
&lt;p&gt;Julia uses an &lt;a href=&quot;https://juliacomputing.com/blog/2016/04/04/inference-convergence.html&quot;&gt;abstract interpretation approach to type inference&lt;/a&gt;. The high-level intuition is that Julia walks over your code much like an interpreter would, except that variables are assigned to abstract sets of values (like &lt;code&gt;Int64&lt;/code&gt;, representing all the whole numbers you can squeeze into 64 bits) rather than actual values (like &lt;code&gt;3&lt;/code&gt;, a particular one of those numbers).&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Transducers &amp; Effects</title>
      <link>https://mikeinnes.io/posts/transducers/</link>
      <pubDate>Fri, 12 Jun 2020 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/transducers/</guid>
      <description>&lt;p&gt;Clojure has introduced a very interesting idea called ‘transducers’, which decouple sequence transformations (mapping, filtering etc) from sequence implementations like vectors, lazy lists and channels. Transducers and their benefits are well-covered elsewhere, but I’d like to explore some tradeoffs, and compare an alternative (and extremely hypothetical) design based on a staple of the functional programming world, effect handlers.&lt;/p&gt;
&lt;p&gt;There are many useful operations that we can carry out on &lt;em&gt;sequences&lt;/em&gt;, like mapping, filtering, interleaving, partitioning and so on. Ideally, we’d like to apply these tools to any sequence of values, including list data structures and strings but also channels and observables. Unfortunately, it’s common to have to &lt;a href=&quot;https://github.com/ReactiveX/RxClojure&quot;&gt;reimplement&lt;/a&gt; each function we want for new sequences.&lt;/p&gt;
&lt;p&gt;Abstracting over sequences is difficult, and requires a significantly more powerful approach than the usual polymorphism and data abstraction. To see why, imagine a somewhat-general &lt;code&gt;map&lt;/code&gt; using &lt;code&gt;empty&lt;/code&gt; and &lt;code&gt;conj&lt;/code&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Modern Language Designer</title>
      <link>https://mikeinnes.io/posts/modern-languages/</link>
      <pubDate>Sat, 06 Jun 2020 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/modern-languages/</guid>
      <description>&lt;p&gt;Programming language design and implementation is, always has been, and likely always will be, hard. But it’s hard today for completely different reasons to those fifty years ago, when the PL field first bloomed. In the past a budding language designer more or less just had to hack together a parser, throw out machine code and call it a day (albeit this is harder than it sounds with then-current tools). In 2020 such a language could be a weekend project – but in turn, language designers face many new challenges and a much higher bar for success.&lt;/p&gt;
&lt;p&gt;In the 70s, choosing syntax was (I imagine) quite a big deal, with little in the way of prior art to guide your choices. In the 2020s programmers have a shared intuition for syntax that transcends languages. Basic ideas like block structure, lexical scope and use of indentation are universal and aren’t going anywhere. More specifically, C-like syntax (via its modern incarnations in Rust and Swift) is taking over, even influencing &lt;a href=&quot;https://github.com/koka-lang/koka/blob/c87c060a8ef5770f0dda9a3c795b1024c020a017/lib/std/async.kk&quot;&gt;new functional languages&lt;/a&gt; that use effect handlers. Still, Pascal-, ML- and Lisp-like notations aren’t dead yet. Realistically you’re going to choose one of these syntax families as a base and make minor adjustments. There’s a little room for innovation here and there, but the biggest decisions about syntax are made for you.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Turning syntax into runnable machine code used to mean reading a dense manual, possibly specific to your make of PC, and staring a &lt;em&gt;lot&lt;/em&gt; at your code to figure out the inevitable bugs. At the least you’d have to do register allocation and expand your language primitives into machine code sequences; more advanced compilers would do peephole optimisations, removing redundant instructions or even pattern matching to reorder and replace code for best performance on the target hardware. Then you’d have to do it again for a different kind of computer, not to mention other tooling like linkers and debuggers.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Iterate on it</title>
      <link>https://mikeinnes.io/posts/iterate/</link>
      <pubDate>Thu, 04 Jun 2020 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/iterate/</guid>
      <description>&lt;p&gt;When you write a &lt;code&gt;for&lt;/code&gt; loop in Julia, like&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;julia&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; xs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#8B949E&quot;&gt;  # do something with x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;this expands to&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Many Types of Types</title>
      <link>https://mikeinnes.io/posts/types/</link>
      <pubDate>Tue, 19 May 2020 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/types/</guid>
      <description>&lt;p&gt;Julia programmers love nothing like a good polysemy. One of the more extreme examples is the community’s use of the word “type”, which refers to a cluster of related, but subtly distinct, features and their roles in the language. Ambiguity can provide a useful shorthand, but it can also be confusing to newcomers and those outside the community, so it might be useful to disambiguate a bit.&lt;/p&gt;
&lt;p&gt;In short, types are Julia values that can play in one of the following parts: as tags for identifying meaning, selectors for dynamic dispatch, descriptions of data layout, annotations provided by type inference, hints for compiler specialisation, and constraints for compile-time correctness checking. These are all largely separate concerns that aren’t as tied together as they may seem.&lt;/p&gt;
&lt;h2 id=&quot;data-tags&quot; tabindex=&quot;-1&quot;&gt;Data Tags&lt;/h2&gt;
</description>
    </item>
    
    <item>
      <title>Differentiable Control Problems</title>
      <link>https://mikeinnes.io/posts/dp-vs-rl/</link>
      <pubDate>Tue, 05 Mar 2019 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/dp-vs-rl/</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted on the &lt;a href=&quot;https://fluxml.ai/blogposts/2019-03-05-dp-vs-rl/&quot;&gt;Flux website&lt;/a&gt;. By Neethu Maria Joy, Tejan Karmali and Mike Innes.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We’ve discussed the idea of &lt;a href=&quot;https://fluxml.ai/blogposts/2019-02-07-what-is-differentiable-programming/&quot;&gt;differentiable programming&lt;/a&gt;, where we incorporate existing programs into deep learning models. This article shows what ∂P can bring to some simple but classic control problems, where we would normally use black-box Reinforcement Learning (RL). ∂P-based models not only learn far more effective control strategies, but also train orders of magnitude faster. The &lt;a href=&quot;https://github.com/FluxML/model-zoo/tree/master/contrib/games/differentiable-programming/trebuchet&quot;&gt;code&lt;/a&gt; is all available to run for yourself – they will mostly train in a few seconds on any laptop.&lt;/p&gt;
&lt;h2 id=&quot;follow-the-gradient&quot; tabindex=&quot;-1&quot;&gt;Follow the Gradient&lt;/h2&gt;
</description>
    </item>
    
    <item>
      <title>On Machine Learning and Programming Languages</title>
      <link>https://mikeinnes.io/posts/ml-pl/</link>
      <pubDate>Wed, 06 Dec 2017 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/ml-pl/</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted on the &lt;a href=&quot;https://julialang.org/blog/2017/12/ml-pl/&quot;&gt;Julia website&lt;/a&gt;. By Mike Innes (JuliaHub), David Barber (UCL), Tim Besard (UGent), James Bradbury (Salesforce Research), Valentin Churavy (MIT), Simon Danisch (MIT), Alan Edelman (MIT), Stefan Karpinski (JuliaHub), Jon Malmaud (MIT), Jarrett Revels (MIT), Viral Shah (JuliaHub), Pontus Stenetorp (UCL) and Deniz Yuret (Koç University).&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Any sufficiently complicated machine learning system contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of a programming language.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As programming languages (PL) people, we have watched with great interest as machine learning (ML) has exploded – and with it, the complexity of ML models and the frameworks people are using to build them. State-of-the-art models are increasingly &lt;em&gt;programs&lt;/em&gt;, with support for programming constructs like loops and recursion, and this brings out many interesting issues in the tools we use to create them – that is, programming languages.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Recursive Self-Simulation</title>
      <link>https://mikeinnes.io/posts/turingception/</link>
      <pubDate>Wed, 15 Nov 2017 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/turingception/</guid>
      <description>&lt;p&gt;Can the Universe Simulate Itself?&lt;/p&gt;
&lt;p&gt;I’m not merely asking if we can simulate the laws of Physics, nor whether we can simulate them with such fidelity that they give rise to life. Those are pansy questions.&lt;/p&gt;
&lt;p&gt;I’m asking if the universe can simulate itself &lt;em&gt;exactly&lt;/em&gt; – so exactly that, if the simulation were left running long enough, it would give rise to humans just like us, who would then initiate the same simulation! Which of course would then contain a simulation of &lt;em&gt;itself&lt;/em&gt;, and so on ad infinitum.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Taming the Tarpit</title>
      <link>https://mikeinnes.io/posts/brainforth/</link>
      <pubDate>Wed, 13 Sep 2017 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/brainforth/</guid>
      <description>&lt;p&gt;Have you ever seen a programming language like this?&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;brainfuck&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;++++++++[&gt;++++[&gt;++&gt;+++&gt;+++&gt;+&amp;#x3C;&amp;#x3C;&amp;#x3C;&amp;#x3C;-]&gt;+&gt;+&gt;-&gt;&gt;+[&amp;#x3C;]&amp;#x3C;-]&gt;&gt;.&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---.+++++++..+++.&gt;&gt;.&amp;#x3C;-.&amp;#x3C;.+++.------.--------.&gt;&gt;+.&gt;++.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What you’re looking at is the “hello, world!” program of a language called &lt;a href=&quot;https://en.wikipedia.org/wiki/Brainfuck&quot;&gt;brainfuck&lt;/a&gt;. Brainfuck is a sort of postmodern approach to language design, the kind of thing that Jackson Pollock’s evil digital twin would have used. It has only eight instructions for moving around an array of bytes, adding and subtracting one as you go. Yet surprisingly enough, it’s just as powerful as a full programming language like Python.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Generic GPU Kernels</title>
      <link>https://mikeinnes.io/posts/cudanative/</link>
      <pubDate>Thu, 24 Aug 2017 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/cudanative/</guid>
      <description>&lt;p&gt;Julia has a library called &lt;a href=&quot;https://github.com/JuliaGPU/CUDAnative.jl&quot;&gt;CUDAnative&lt;/a&gt;, which hacks the compiler to run your code on GPUs.&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-lang=&quot;julia&quot;&gt;&lt;pre class=&quot;shiki github-dark-default&quot; style=&quot;background-color:#0d1117;color:#e6edf3&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;using&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; CuArrays, CUDAnative&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;xs, ys, zs &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; CuArray&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;rand&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;)), &lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;CuArray&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;rand&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;)), &lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;CuArray&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;zeros&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#D2A8FF&quot;&gt; kernel_vadd&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(out, a, b)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;  i &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;blockIdx&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; blockDim&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt; threadIdx&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;  out[i] &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; a[i] &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; b[i]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;  return&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;@cuda&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(xs)) &lt;/span&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;kernel_vadd&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt;(zs, xs, ys)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79C0FF&quot;&gt;@assert&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; zs &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; xs &lt;/span&gt;&lt;span style=&quot;color:#FF7B72&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E6EDF3&quot;&gt; ys&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Is this better than writing CUDA C? At first, it’s easy to mistake this for simple syntactic convenience, but I’m convinced that it brings something fundamentally new to the table. Julia’s powerful array abstractions turn out to be a great fit for GPU programming, and it should be of interest to GPGPU hackers regardless of whether they use the language already.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Lazy List</title>
      <link>https://mikeinnes.io/posts/lazy/</link>
      <pubDate>Mon, 05 Jun 2017 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/lazy/</guid>
      <description>&lt;p&gt;“Any sufficiently advanced technology is indistinguishable from magic,” go the famous words of Arthur C. Clarke. Often with seemingly-magical technology, a small dose of knowledge is enough to wash away our wide-eyed awe and bring us back to sweet, comfortable cynicism. Yet some ideas don’t lose their lustre so easily; it can be a little hard to believe they work even once you understand them.&lt;/p&gt;
&lt;p&gt;Laziness is one such idea. Today I’d like to give you a taste of the borderline-magical things that lazy sequences can do. But we’ll also peek under the hood of the abstraction, and understand what’s &lt;em&gt;really&lt;/em&gt; going on. By the end you should have the foundations to implement them yourself.&lt;/p&gt;
&lt;h2 id=&quot;the-gateway&quot; tabindex=&quot;-1&quot;&gt;The Gateway&lt;/h2&gt;
</description>
    </item>
    
    <item>
      <title>Sorting a Billion Numbers</title>
      <link>https://mikeinnes.io/posts/sorting/</link>
      <pubDate>Mon, 21 Mar 2016 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/sorting/</guid>
      <description>&lt;p&gt;This post gives an overview of working with larger-than-memory data in the Julia language. I don’t have any particular use for this, but was curious about the problem as the current tools for &lt;a href=&quot;https://en.wikipedia.org/wiki/Out-of-core_algorithm&quot;&gt;out-of-core analysis&lt;/a&gt; seem to be pretty lacking. I’ve attempted to come up with a basic implementation of an array backed by persistent storage, and this post explains how I’ve put it together.&lt;/p&gt;
&lt;p&gt;Aside from any insights about the problem itself, I’m going to write a lot about some of Julia’s more unusual features and how they lock together. If you’re a beginner Julian or are interested in becoming one, it might be instructive to see these in action – feature lists look great on paper but can’t give a good sense of how things feel in practice, especially when it comes to working with larger codebases. Be warned, though, that this post is pretty technical and isn’t a tutorial; I’ll link to more beginner-friendly materials where they might be useful.&lt;/p&gt;
&lt;p&gt;As a rough outline, we’ll cover:&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Speed in Programming Languages</title>
      <link>https://mikeinnes.io/posts/speed/</link>
      <pubDate>Mon, 26 May 2014 00:00:00 +0000</pubDate>
      <guid>https://mikeinnes.io/posts/speed/</guid>
      <description>&lt;p&gt;Computers are more powerful than ever before. Now that you can buy watches which outpace the earliest supercomputers, it seems logical to think that the efficiency of your software no longer matters. And yet, performance is the new black, with recent languages like Go, Julia and Rust aiming to provide expressive power and ease of use without compromising on CPU cycles.&lt;/p&gt;
&lt;p&gt;Julia is probably the most extreme example of this trend, with its lofty goal of being as dynamic and expressive as languages like Python, Ruby or R while still traveling at the speed of C. At the moment it’s mostly aimed at number crunchers for whom raw FLOPS are the holy grail, but I would suggest that it’s also relevant to the exact opposite camp — even if you happily use languages like Python and never even think about performance.&lt;/p&gt;
&lt;p&gt;If you’re this kind of coder, your reaction to these languages may well be something like: “So what? My language is already productive, and my code is never the bottleneck anyway.”&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
