<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">
<channel>
<title>Patrick Dubroy's blog</title>
<atom:link href="https://dubroy.com/blog/rss.xml" rel="self" type="application/rss+xml"/>
<link>https://dubroy.com/blog</link>
<description>programming, usability &amp; interaction design</description>
<lastBuildDate>Mon, 23 Mar 2026 13:19:06 -0000</lastBuildDate>
<language>en</language>
<item>
  <title>devlog: compatibility packages</title>
  <link>https://dubroy.com/blog/compatibility-packages/</link>
  <comments>https://dubroy.com/blog/compatibility-packages/#comments</comments>
  <pubDate>Fri, 06 Feb 2026 00:00:00 -0000</pubDate>
  <dc:creator>Patrick Dubroy</dc:creator>
  <guid>https://dubroy.com/blog/compatibility-packages/</guid>
  <description>
<![CDATA[<p><em>[this is a <em>devlog</em> post — a quick, lightly-edited post about stuff I&#8217;m working on right now]</em></p>
<p>I&#8217;ll be introducing some breaking changes in the next major version of <a href="https://ohmjs.org">Ohm</a> and I&#8217;d like to make the upgrade path as smooth as possible. So I&#8217;ve been investigating patterns for specific &#8220;migration&#8221; and &#8220;compat&#8221; packages in the JS ecosystem.</p>
<p>I found a few interesting examples. Most of them aim to support incremental upgrades, allowing you to migrate to the new API piece by piece. This isn&#8217;t really a concern for Ohm. Mainly I&#8217;m interested in making it easy for to folks to try the new version behind a feature flag, and easily revert to the stable version if they run into any bugs.</p>
<p>Anyways, here&#8217;s what I found —</p>
<h2><a href="https://www.npmjs.com/package/react-router-dom-v5-compat">react-router-dom-v5-compat</a></h2>
<blockquote>
<p>Instead of upgrading and updating all of your code at once (which is incredibly difficult and prone to bugs), the backwards compatibility package enables you to upgrade one component, one hook, and one route at a time by running both v5 and v6 in parallel. Any code you haven&#8217;t touched is still running the very same code it was before. Once all components are exclusively using the v6 APIs, your app no longer needs the compatibility package and is running on v6.</p>
<p>This package enables React Router web apps to incrementally migrate to the latest API in v6 by running it in parallel with v5. It is a copy of v6 with an extra couple of components to keep the two in sync.</p>
<p>Once you&#8217;ve converted all of your code you can remove the compatibility package and install React Router DOM v6 directly.</p>
</blockquote>
<h2><a href="https://www.npmjs.com/package/@vue/compat">@vue/compat</a></h2>
<p>Looks like a similar approach to <code>react-router-dom-v5-compat</code> — it includes new version, alongside compatibility features:</p>
<blockquote>
<p><code>@vue/compat</code> (aka &#8220;the migration build&#8221;) is a build of Vue 3 that provides configurable Vue 2 compatible behavior.</p>
<p>The migration build runs in Vue 2 mode by default - most public APIs behave exactly like Vue 2, with only a few exceptions. Usage of features that have changed or been deprecated in Vue 3 will emit runtime warnings. A feature&#8217;s compatibility can also be enabled/disabled on a per-component basis.</p>
</blockquote>
<h2><a href="https://github.com/colinhacks/zod/issues/4371">zod</a>&#8216;s subpath versioning</h2>
<p>Zod takes a slightly different approach — rather than a separate package, it includes the new version as a submodule:</p>
<blockquote>
<p>The general approach:</p>
<ul>
<li>Zod 4 will not initially be published as <code>zod@4.0.0</code> on npm. Instead it will be exported at a subpath (<code>"zod/v4"</code>) alongside <code>zod@3.25.0</code>
Despite this, Zod 4 is considered stable and production-ready</li>
<li>Zod 3 will continue to be exported from the package root (<code>"zod"</code>) as well as a new subpath <code>"zod/v3"</code>. It will continue to receive bug fixes &amp; stability improvements.</li>
</ul>
<p>Sometime later:</p>
<ul>
<li>The package root (<code>"zod"</code>) will switch over from exporting Zod 3 to Zod 4</li>
<li>At this point <code>zod@4.0.0</code> will get published to npm</li>
<li>The <code>"zod/v4"</code> subpath will remain available forever</li>
</ul>
</blockquote>
<p class="dinkus"></p>

<p>Another approach is a package intended to be used in <em>conjunction</em> with the new version, with extra functionality that useful during the migration.</p>
<h2><a href="https://github.com/ember-cli/ember-compatibility-helpers">ember-compatibility-helpers</a></h2>
<blockquote>
<p>Provides flags for features in Ember, allowing you to write code that will work with whatever version the consuming application is on. This addon is intended to help addon authors write backwards/forwards compatibility.</p>
<p>The flags are replaced at build time with boolean literals (<code>true</code> or <code>false</code>) by a Babel transform. When ran through a minifier (with dead code elimination) the entire section will be stripped, meaning that the section of code which is not used will not be added to production builds - zero cost compatibility!</p>
</blockquote>
<h2><a href="https://github.com/jquery/jquery-migrate">jQuery migrate</a></h2>
<blockquote>
<p>Upgrading libraries such as jQuery can be a lot of work, when breaking changes have been introduced. jQuery Migrate makes this easier, by restoring the APIs that were removed, and additionally shows warnings in the browser console (development version of jQuery Migrate only) when removed and/or deprecated APIs are used.</p>
</blockquote>
<p class="dinkus"></p>

<p>💬 <em>Any others I should know about? <a href="https://dubroy.com/blog/about/#contact">Send me an email</a> or respond on <a href="https://bsky.app/profile/dubroy.com/post/3me7jxtdo5s2o">Bluesky</a> or <a href="https://hachyderm.io/@dubroy/116025109648450624">Mastodon</a>.</em></p>]]>
  </description>
<slash:comments>0</slash:comments>
</item>
<item>
  <title>Look for what's true</title>
  <link>https://dubroy.com/blog/look-for-whats-true/</link>
  <comments>https://dubroy.com/blog/look-for-whats-true/#comments</comments>
  <pubDate>Wed, 28 Jan 2026 00:00:00 -0000</pubDate>
  <dc:creator>Patrick Dubroy</dc:creator>
  <guid>https://dubroy.com/blog/look-for-whats-true/</guid>
  <description>
<![CDATA[<p>A few times in my career I’ve gotten feedback that really knocked me on my ass.</p>
<p>The first few times it happened, I wasn’t mature enough to learn much from it. But eventually I discovered a little trick — something that helps me set my ego aside and actually listen.</p>
<p>The details aren’t all that important, but to set the scene: a Principal Engineer I worked with had called me out for being overly negative in a meeting. He pointed out that, as a senior IC, I should be mindful of how my actions could affect those around me.</p>
<p>In hindsight, he was spot on; but in the moment, it felt mostly wrong and totally unfair.</p>
<p>I spent the rest of the day in a miserable mood. In the evening, I was still stewing, and considering how to respond. I think I even started drafting a rebuttal email (I know, I know).</p>
<p>At some point I googled “how to respond to negative feedback” or something like that. Honestly, I’m not sure if I expected to find something useful, but I did.</p>
<p>The advice that helped me: <strong>look for what’s true</strong>.</p>
<p>Almost any time you get serious critical feedback, it will feel unfair. There will be things your critic got wrong, or important context that they didn’t mention. Your instinct will be to focus on those aspects, to find as many reasons as possible to dismiss or minimize the feedback.</p>
<p>Instead of focusing on what’s <em>wrong</em> with the feedback, ask yourself what’s <em>right</em>. Sure, your critic is totally off base, but is there a kernel of truth there?</p>
<p>It’s a simple trick, but I find it incredibly useful<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>. By reframing things, I&#8217;m able to diffuse my immediate, emotional reaction. Once I’ve done that, it becomes much easier to see things from an objective perspective.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>And it’s surprisingly helpful in other situations, too. Next time you read an outrageous take on social media, try asking yourself: is there a kernel of truth there? Maybe there isn&#8217;t, but just asking myself that question is often enough to engage my &#8220;upstairs brain&#8221; and tamp down the emotional reaction.&#160;<a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
</ol>
</div>]]>
  </description>
<slash:comments>0</slash:comments>
</item>
<item>
  <title>De-Googling</title>
  <link>https://dubroy.com/blog/de-googling/</link>
  <comments>https://dubroy.com/blog/de-googling/#comments</comments>
  <pubDate>Fri, 16 Jan 2026 00:00:00 -0000</pubDate>
  <dc:creator>Patrick Dubroy</dc:creator>
  <guid>https://dubroy.com/blog/de-googling/</guid>
  <description>
<![CDATA[<p>Since early last year, I’ve been trying to reduce my dependency on the big US tech companies, and US companies in general. Following <a href="https://www.tbray.org/ongoing/When/202x/2025/07/29/DeGoogling">Tim Bray</a>, I’ve been thinking of this as <em>de-Googling</em>.</p>
<p>I don’t really want to get into the reasons, except to say that I’m under no illusion that my support (or lack of it) makes any difference to those companies. For me, it’s much more about reducing risk<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>, and about supporting smaller companies whose interests are more aligned with mine.</p>
<p>Anyways! I wanted write about my progress here, in case it’s useful to anyone else who’s also considering this.</p>
<p><em>(For a more in-depth discussion of the various alternatives, I found <a href="https://european-alternatives.eu">European Alternatives</a> and <a href="https://disconnect.blog/getting-off-us-tech-a-guide/">Getting off US tech: a guide</a> to be quite helpful.)</em></p>
<h2>Web hosting: Hetzner&nbsp;🇩🇪 + Bunny&nbsp;🇸🇮</h2>
<p>This was a pretty easy one. My web site has been hosted on Dreamhost for 20-odd years, and a few years back I started using Cloudflare as a CDN and for SSL termination.</p>
<p>I now have a VPS with <a href="https://www.hetzner.com/">Hetzner</a>, and am using <a href="https://bunny.net">Bunny</a> as my replacement for Cloudflare. I&#8217;m extremely happy with both:</p>
<ul>
<li>The Hetzner VPS gives me a lot more flexibility than I had on my Dreamhost shared hosting plan, and it costs about the same. It&#8217;s also cool that my VPS is just down the road in Nuremberg.</li>
<li>Bunny is a drop-in replacement for most of what Cloudflare can do. Their web UI is also much more pleasant to use than Cloudflare&#8217;s, and <a href="https://bsky.app/profile/dubroy.com/post/3lm65c2qnk22h">their custom support is excellent</a>. I pay them $1/mo (the minimum charge).</li>
</ul>
<h2>Mail &amp; calendar: Fastmail&nbsp;🇦🇺 + iOS Calendar</h2>
<p>I&#8217;ve also been using Gmail and Google Calendar for almost 20 years — since shortly after they announced <a href="https://googlepress.blogspot.com/2006/08/google-launches-hosted-communications_28.html">Google Apps for Your Domain</a>.</p>
<p>This was one of the most difficult decisions. I evaluated <a href="https://soverin.com">Soverin</a> and <a href="https://mailbox.org">mailbox.org</a>, but they both have pretty rudimentary web UIs. Also, I have a huge volume of mail (20 years worth) and use search *a lot*, and I couldn&#8217;t figure out a setup that could really replace Gmail for me.</p>
<p>I considered Proton, but since it&#8217;s end-to-end encrypted, I assumed that search performance would also be a problem.</p>
<p>I ended up choosing Fastmail. Although they&#8217;re an Australian company, <a href="https://www.fastmail.com/blog/fastmails-servers-are-in-the-us-what-this-means-for-you/">their servers are located in the US</a>. Since privacy is not my main concern here, I considered it to be an acceptable tradeoff.</p>
<p>Migrating my email to Fastmail was really easy (they have a migration assistant) and I&#8217;m perfectly happy with their web client and iOS app. There was really nothing that I missed from Gmail.</p>
<p>I did have a few issues migrating my calendar, mostly related to notifications from other Google Calendar users. The problem was two-fold:</p>
<ol>
<li>Fastmail only did a one-time import of all the calendar events.</li>
<li>Since I still had a Google Workspace account, any changes from other Google users would directly update the calendar event, rather than being sent by email.</li>
</ol>
<p>It took me a while to debug this, but I eventually realized I could disable Calendar in my Google Workspace. Everything has been working fine since then.</p>
<p>On my laptop, I use the Fastmail&#8217;s web UI for my calendar, but on my phone, I&#8217;m using the built-in iOS calendar. I used a <a href="https://www.fastmail.com/blog/faster-easier-setup-on-iphones-ipads-and-macs/">configuration profile</a> to do this.</p>
<p>For a single user, Fastmail costs €5/mo.</p>
<h2>Video calls: Whereby&nbsp;🇳🇴</h2>
<p>After I moved off Gmail and Google Calendar, I need to find a replacement Google Meet. This was surprisingly difficult; I find a lot of video chat apps (e.g. Discord, Cal.com) to be significantly worse than Meet.</p>
<p>Finally I tried <a href="https://whereby.com">Whereby</a> and have had nothing but positive experiences. I&#8217;m currently paying for their Pro account (US$7.50/mo).</p>
<h2>Web browser: Vivaldi&nbsp;🇳🇴</h2>
<p>Not much to say here. I got tired of Chrome&#8217;s <a href="https://www.theregister.com/2023/09/06/google_privacy_popup_chrome/">deceptive messaging about ad privacy</a> and about how careful I had to be to stay signed-out.</p>
<p><a href="https://vivaldi.com/">Vivaldi</a> is a Chromium-based browser, and after tweaking a few settings, it&#8217;s basically a like-for-like replacement. I&#8217;ve been happily using it for 6 months now.</p>
<h2>File sync: Self-hosted</h2>
<p>I used to have all my important digital records in Dropbox. Early last year, I replaced it with a self-hosted setup:</p>
<ul>
<li>A Samba share on a Mac Mini (running Debian) in my basement.</li>
<li><a href="https://github.com/bcpierce00/unison">Unison</a> for syncing my laptop to the server.</li>
<li><a href="https://tailscale.com">Tailscale</a> + <a href="https://apps.apple.com/us/app/owlfiles-file-manager/id510282524">Owlfiles</a> for access on the go.</li>
<li>A nightly cronjob that backs up to a Hetzner Storage Box. (See <a href="https://github.com/pdubroy/til/blob/main/sysadmin/2025-04-20-Backups-with-borg-and-borgmatic.md">TIL: Backups with Borg and borgmatic</a> for more details.)</li>
</ul>
<h2>Maps: Organic Maps + Apple Maps</h2>
<p>I&#8217;ve been using Apple Maps for navigation for a few years now; I find the UI to be nicer, and for some reason, Apple seems to be better at knowing about road closures in Germany.</p>
<p>For other things that I used to use Google Maps for (e.g. looking up opening hours of stores), I find <a href="https://organicmaps.app">Organic Maps</a> to be surprisingly good. I&#8217;m not sure I&#8217;ll be able to completely remove Google Maps from my phone though.</p>
<h2>Office: 🤷</h2>
<p>The biggest gap for me so far is that I haven&#8217;t found a good replacement for Google Docs and Google Sheets. Luckily, my needs aren&#8217;t that big; I&#8217;ve been getting by with <a href="https://www.libreoffice.org/discover/calc/">LibreOffice Calc</a> for spreadsheets, and <a href="https://obsidian.md">Obsidian</a> for most of the other stuff.</p>
<h2>What&#8217;s next?</h2>
<p>To address the elephant in the room: yes, I&#8217;m still using iOS and macOS. I did pick up a <a href="https://nothing.tech">Nothing</a> phone last year, and at some point I&#8217;d like to try installing one of the deGoogled Android distros on it. I may also pick up a cheap desktop machine and try running Linux for a while, let&#8217;s see.</p>
<p>I also haven&#8217;t tackled photos yet. I&#8217;m still paying Apple for iCloud photo storage, and also using Google Photos. I&#8217;ve heard good things about <a href="https://immich.app">Immich</a> but haven&#8217;t tried it out yet.</p>
<p class="dinkus"></p>

<p>💬 <em>Questions? <a href="https://dubroy.com/blog/about/#contact">Send me an email</a> or respond on <a href="https://bsky.app/profile/dubroy.com/post/3mckggbu47s2x">Bluesky</a> or <a href="https://hachyderm.io/@dubroy/115905513238816960">Mastodon</a>.</em></p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>Quentin Stafford-Fraser makes a good case in <a href="https://statusq.org/archives/2026/01/07/13491/">Living without America</a>.&#160;<a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
</ol>
</div>]]>
  </description>
<slash:comments>0</slash:comments>
</item>
<item>
  <title>devlog: garbage collection is useful</title>
  <link>https://dubroy.com/blog/garbage-collection-is-useful/</link>
  <comments>https://dubroy.com/blog/garbage-collection-is-useful/#comments</comments>
  <pubDate>Fri, 14 Nov 2025 00:00:00 -0000</pubDate>
  <dc:creator>Patrick Dubroy</dc:creator>
  <guid>https://dubroy.com/blog/garbage-collection-is-useful/</guid>
  <description>
<![CDATA[<p>A long time ago, I spent a few years working on garbage collection in the J9 Java VM.<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup> And even though I&#8217;ve since done mostly done higher-level stuff, having a deeper knowledge of GC has continued to come in useful.</p>
<p>Yesterday, it was an insight from one of my favourite GC papers, <a href="https://web.eecs.umich.edu/~weimerw/2012-4610/reading/bacon-garbage.pdf">A Unified Theory of Garbage Collection</a>, which helped me solve a tricky problem.</p>
<h2>ohm&#8217;s incremental parsing</h2>
<p>I&#8217;m working with a team that&#8217;s using <a href="https://ohmjs.org">Ohm</a> to parse text documents and render a rich text version in <a href="https://prosemirror.net">ProseMirror</a>. The goal is bidirectional updates: changes in ProseMirror should propagate to the text version, and vice versa.</p>
<p>Ohm supports incremental parsing, which means that if you parse some text and then make a small edit, it can quickly reparse by reusing portions of the previous result.</p>
<p>It also supports limited form of incremental transforms. You can define an <em>attribute</em>, which is kind of like a memoized visitor, and the attribute value for a given node will only need to be recalculated if the edit affected one of its subtrees. So you can easily implement a form of persistent data structure, where each new value (e.g., an AST) shares a bunch of structure with the previous one.</p>
<h2>the problem</h2>
<p>Using this machinery, I tried making an <code>pmNodes</code> attribute that produced a ProseMirror document for a given input. When the text document is edited, it produces a new tree which shares a bunch of nodes with the previous one.</p>
<figure style="width: 320px; margin-left: auto; margin-right: auto;">
    <img src="https://dubroy.com/blog/images/prosemirror-gc.png" class="light-bg-protect">
    <figcaption style="text-align: center">The `pmNodes` tree before and after an edit.</figcaption>
</figure>

<p>Then, my plan was to construct a ProseMirror transaction that would turn the old tree into the new one. To do that, it&#8217;s helpful to know which nodes appeared in the old document, but not the new one.</p>
<p>My first implementation of this was equivalent to tracing garbage collection — after each edit, I walked the entire document, and recorded all the nodes in a Set. The difference between the sets told me which nodes had died.</p>
<p>But this kind of defeats the purpose of incrementality — if you have a long document and make a small edit, we should be able to process <em>without</em> visiting every node in the document.</p>
<h2>the solution</h2>
<p>Then I remembered <a href="https://web.eecs.umich.edu/~weimerw/2012-4610/reading/bacon-garbage.pdf">A Unified Theory of Garbage Collection</a>, a 2004 OOPSLA paper by some former colleagues of mine:</p>
<blockquote>
<p>Tracing and reference counting are uniformly viewed as being fundamentally different approaches to garbage collection that possess very distinct performance properties. We have implemented high-performance collectors of both types, and in the process observed that the more we optimized them, the more similarly they behaved — that they seem to share some deep structure.</p>
<p>We present a formulation of the two algorithms that shows that they are in fact duals of each other. Intuitively, the difference is that tracing operates on live objects, or &#8220;matter&#8221;, while reference counting operates on dead objects, or &#8220;anti-matter&#8221;. For every operation performed by the tracing collector, there is a precisely corresponding anti-operation performed by the reference counting collector.</p>
</blockquote>
<p>This was the answer I needed! Rather than visiting all the live objects, I wanted to only visit the dead ones, and reference counting would let me do that.</p>
<p>So I added a way of maintaining a reference count for all the nodes in the doc. When we produce a new document, we decrement the reference count of the old root node (it will always be 0 afterwards). So we recursively decrement the ref count of its children, and so on. This gives me exactly what I wanted — a way to find all the nodes that were <em>not</em> reused, without having to visit most of the nodes in the doc.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>I wrote about some of these experiences in <a href="https://dubroy.com/blog/memories-of-some-fantastic-internships/">Memories of some fantastic internships</a>.&#160;<a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
</ol>
</div>]]>
  </description>
<slash:comments>0</slash:comments>
</item>
<item>
  <title>Reflections on writing a book</title>
  <link>https://dubroy.com/blog/reflections-on-writing-a-book/</link>
  <comments>https://dubroy.com/blog/reflections-on-writing-a-book/#comments</comments>
  <pubDate>Mon, 24 Mar 2025 00:00:00 -0000</pubDate>
  <dc:creator>Patrick Dubroy</dc:creator>
  <guid>https://dubroy.com/blog/reflections-on-writing-a-book/</guid>
  <description>
<![CDATA[<p>I wrote a book! It&#8217;s called <a href="https://wasmgroundup.com">WebAssembly from the Ground Up</a> — it&#8217;s an online book where you learn Wasm by writing a simpler compiler in JavaScript. You can <a href="https://wasmgroundup.com/book/contents-sample/">read a free sample</a> if it tickles your fancy.</p>
<p>Together with  my friend <a href="https://marianoguerra.org/">Mariano</a>, I&#8217;ve been working on the book for just over two and half years. And (big surprise) it was a huge learning experience! While everything is still fresh in my mind, I wanted to capture some of the things we learned here.</p>
<h2>The clichés</h2>
<p>Let&#8217;s start with the obvious stuff — the advice you&#8217;ll find everywhere, the things everyone wants to tell you when they hear you&#8217;re writing a book.</p>
<h3>You won&#8217;t get rich</h3>
<p>Don&#8217;t do it for the money. Or the fame. Or any kind of immediate payoff, really.</p>
<p>I don&#8217;t think I could have pulled of a project like this if I didn&#8217;t find it intrinsically rewarding. The book was something we wanted to exist in the world. Early on, I decided that even if <em>nobody</em> cared about it, I wouldn&#8217;t regret doing it.</p>
<h3>It&#8217;s a marathon</h3>
<p>It will take longer than you expect, and then some. As with running, picking the right pace is important. This is especially true if the book is not a full-time project (as it wasn&#8217;t for us).</p>
<p>It ended up being very seasonal for me. There were times (maybe ~6 months in total) where the book was my main focus; the rest of the time, it was second or third on my priority list.</p>
<p>When it was my main focus, I tried to put in four or five hours of deep work on most weekdays. In the other periods, I tried to keep a regular schedule: sometimes a day a week, or — when I really need the momentum to get a new chapter out — an hour a day.</p>
<p>Some of the techniques I wrote about in <a href="https://dubroy.com/blog/getting-things-done-in-small-increments/">Getting things done (in small increments)</a> came in handy.</p>
<h2>The surprises</h2>
<p>This would be a very long post if I tried to capture <em>everything</em> that we learned while writing the book, but a few things stuck out as being a bit more surprising than the others.</p>
<h3>Feedback is…complicated</h3>
<p>We had both read <a href="https://www.usefulbooks.com/book">Write Useful Books</a> and were determined to take its advice to heart. We had early reader conversations and built up a list of interested beta readers. This was definitely helpful — it confirmed that there <em>are</em> people out there who would be interested in the book. And it definitely gave us a better idea of who our potential readers might be.</p>
<p>But, while we&#8217;re very thankful for the feedback that we got, it wasn&#8217;t quite as clarifying as we&#8217;d imagined. Maybe it&#8217;s because of the subject matter, or maybe we should have done something differently. But I think <em>Write Useful Books</em> underplays how much you still need to rely on your own taste and intuition to guide you.</p>
<h3>Explorable &lt; explanation</h3>
<p>Our original idea was to make the book quite interactive, and include <a href="https://worrydream.com/ExplorableExplanations/">explorable explanations</a>. We did include some interactive elements, but they&#8217;re not really essential to the book. Honestly, we didn&#8217;t put in the time that would have been required to make them really great.</p>
<p>The thing is, we found a much bigger payoff in focusing on the <em>explanation</em>. What&#8217;s the point of this chapter? What is the right order to introduce the concepts? What should we move to another chapter, and what should we cut altogether?</p>
<p>The time we spent improving the core content of the book felt <em>so</em> valuable, and compared to that, it spending time tweaking the interactive parts just didn&#8217;t seem worth it.</p>
<h3>Constraints are helpful</h3>
<p>From the beginning, the book was planned to be (a) self-published, and (b) online-first. This meant that we could do almost anything we wanted — but in retrospect it was maybe <em>too</em> much freedom.</p>
<p>We spent a lot of time thinking about some basic things, like:</p>
<ul>
<li>How should the chapters depend on each other? Are they intended to be read in order?</li>
<li>What structural and typographical elements should we use — e.g. sidenotes, callouts, etc.?</li>
<li>What will readers do with the code? Can they execute it in the browser?</li>
<li>How does the code in each chapter build on the previous one?</li>
</ul>
<p>We ultimately came up with a structure we like, and we might use a similar structure if we write another book. But we spent a lot of time thinking about <strong>things that had nothing to do with WebAssembly</strong>.</p>
<p>When I compared this to previous writing experiences — my master&#8217;s thesis and a handful of academic papers — I realized how much value there is in having a fixed structure. Academic papers have a template and a page limit, along with many conventions that reviewers and readers expect. Within those boundaries, there&#8217;s a bit flexibility, but the overall structure is pretty fixed.</p>
<p>If you&#8217;re thinking of writing a self-published book, my advice would be: pick a book that you like, and use its structure as a template. Focus on the core material that you&#8217;re writing about, and worry about the other stuff later (if at all).</p>
<p class="dinkus"></p>

<p>I could write another thousand words on things that we learned from writing this book. But would it help anyone? I suspect that — like being a parent — you won&#8217;t really understand until you&#8217;ve made the mistakes yourself.</p>
<p>Are you thinking about writing a book? My advice: go for it! You won&#8217;t regret it.</p>]]>
  </description>
<slash:comments>0</slash:comments>
</item>
<item>
  <title>Make it happen</title>
  <link>https://dubroy.com/blog/make-it-happen/</link>
  <comments>https://dubroy.com/blog/make-it-happen/#comments</comments>
  <pubDate>Tue, 11 Feb 2025 00:00:00 -0000</pubDate>
  <dc:creator>Patrick Dubroy</dc:creator>
  <guid>https://dubroy.com/blog/make-it-happen/</guid>
  <description>
<![CDATA[<p>In 2012 I was working at Google on the Chrome team in Munich.</p>
<p>I was writing a lot of JavaScript code and constantly having to wait for code reviews from a team in Los Angeles. On one of my trips to Mountain View, I thought: <em>screw it, I’m going to LA to meet those bastards</em>.</p>
<p>I didn’t ask my manager, didn’t tell the LA team I was coming — just booked a flight, went into the office, and introduced myself.</p>
<p>And you know what? They were incredibly welcoming. They offered me a desk, we had lunch together, and they took me out for drinks that night.</p>
<p>I never had to bug them about code reviews again. One of them (thanks James!) started reviewing my PRs first thing each morning. Not long after that, they added me to the OWNERS file.</p>
<p class="dinkus"></p>

<p>While I was booking that flight, I had a thought: Alan Kay lives in LA.</p>
<p>I&#8217;d always wanted to meet Alan. I was a big fan of Smalltalk and his more recent work on the <a href="https://tinlizzie.org/VPRIPapers/tr2012001_steps.pdf">STEPS project at VPRI</a>. So I sent him an email:</p>
<blockquote>
<p>Hi Dr. Kay,</p>
<p>I&#8217;m a software engineer at Google on the Chrome team. I&#8217;ve been thinking a lot about tools for web development, specifically dynamic development tools that support exploration, experimentation, and immediate feedback. Your work is a big inspiration in this area, and I think it&#8217;s a shame that most environments still can&#8217;t do what Smalltalk could 30 years ago.</p>
<p>I&#8217;m normally based in Munich, but will be in Google&#8217;s Venice Beach office for the next couple of days. I&#8217;d love to chat with you about some of my ideas. I&#8217;m sure you&#8217;re busy, but if you have 30 minutes to spare I&#8217;d really appreciate it. I could meet anywhere in the LA area that would be convenient for you.</p>
</blockquote>
<p>And you know what? He responded the next day and said he&#8217;d be happy to come meet me for lunch. We had a great conversation,  and he later introduced me to Alex Warth, one of his “most brilliant grad students ever” who also worked at Google.</p>
<p>Alex and I stayed in touch, and two years later, he asked me to join him at a new research group Alan had started. It was basically a dream job; I spent three years there working with some amazing people<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>, many that I&#8217;m still friends with today.</p>
<p>Don&#8217;t wait. Sometimes you can just make it happen.</p>
<p>💬 <em>Want to leave feedback? <a href="https://dubroy.com/blog/about/#contact">Send me an email</a> or respond on <a href="https://bsky.app/profile/dubroy.com/post/3lhvt2p2ocj26">Bluesky</a> or <a href="https://hachyderm.io/@dubroy/113985615528793692">Mastodon</a>.</em></p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>I wrote about my time at CDG (later known as HARC) in <a href="https://dubroy.com/blog/sketches-from-cdg/">Sketches from CDG</a>.&#160;<a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
</ol>
</div>]]>
  </description>
<slash:comments>0</slash:comments>
</item>
<item>
  <title>Five coding hats</title>
  <link>https://dubroy.com/blog/five-coding-hats/</link>
  <comments>https://dubroy.com/blog/five-coding-hats/#comments</comments>
  <pubDate>Mon, 03 Feb 2025 00:00:00 -0000</pubDate>
  <dc:creator>Patrick Dubroy</dc:creator>
  <guid>https://dubroy.com/blog/five-coding-hats/</guid>
  <description>
<![CDATA[<p>Early in my career, I was convinced there was &#8220;good code&#8221; and &#8220;bad code&#8221;. That you could look at something and — without knowing anything about the context — pass judgement on it.</p>
<p>These days, my views are much more nuanced. I try to adapt my style to the situation. The code I write, and the process I use, depends a lot more on what the goals are. Am I trying to bang together a quick prototype to learn something? Or am I fixing a bug that might affect hundreds of thousands of users? My approach would be completely different in those two scenarios.</p>
<p>Years ago, I read Edward De Bono&#8217;s <a href="https://en.wikipedia.org/wiki/Six_Thinking_Hats">Six Thinking Hats</a>, which describes a framework for problem solving and creative thinking. The idea is that you can &#8220;put on a hat&#8221; to deliberately adopt a specific mode of thinking. It&#8217;s a bit corny but (imo) there&#8217;s a useful idea there.</p>
<p>Maybe this applies to different styles of programming, too? What &#8220;coding hats&#8221; do I use?</p>
<h2>Captain&#8217;s hat 🧑‍✈️</h2>
<p>The captain&#8217;s hat is about doing things by the book: being careful, moving slowly and deliberately, following the proper procedures. This is attitude I&#8217;d adopt if a mistake could <a href="https://en.wikipedia.org/wiki/2024_CrowdStrike-related_IT_outages">crash 8.5 million systems</a>.</p>
<p>With the captain&#8217;s hat on, I&#8217;d focus on small, focused, independent commits — things that are easy to roll back if a problem occurs. I&#8217;d make sure my PRs include tests. I&#8217;d write descriptive commit messages and make sure the code is reviewed.</p>
<p>This is the closest thing to what I used to think &#8220;the right way&#8221; was. What I missed back and then — and it&#8217;s a big miss — is that this isn&#8217;t the right approach for all situations, not even close.</p>
<h2>Scrappy hat 🐕</h2>
<p>A few months ago, I was sharing a small prototype with a friend. Before I showed him the code, I felt the need to give some disclaimers: &#8220;This is deliberately written in a very minimal style&#8221;, &#8220;I was going for the simplest possible thing that could work&#8221;, stuff like that. Eventually I started thinking: <em>I wrote this with my scrappy hat on</em>.</p>
<p>The scrappy hat is about keeping things lean — taking the straightest possible path to your goal, and skipping the ceremony. No code reviews, minimal tests. Sometimes you just need something concrete to discuss; with the scrappy hat on, you can quickly throw something together and decide later if it&#8217;s worth keeping.</p>
<p>This is pretty close to the default mode that most small startups operate in. It&#8217;s the hat of the &#8220;minimum viable&#8221; and the 80-20.</p>
<h2>MacGyver Hat 🛠️</h2>
<p>The MacGyver hat is all about getting a result. Sometimes you don&#8217;t care what it takes, how messy the code is — you just need to figure out if something is possible, whether it&#8217;s worth spending more time on. It&#8217;s the quick-and-dirty, any-which-way, by-hook-or-by-crook mode.</p>
<p>I&#8217;ve used this hat before when I&#8217;m doing performance work. Maybe I have five different ideas to make something faster. They&#8217;d each take a day or two to implement cleanly, but if I don&#8217;t care what the code looks like, I can hack each one together in an hour. Once I know something has promise, I&#8217;ll put in the work to do it right.</p>
<h2>Chef&#8217;s hat 🧑‍🍳</h2>
<p>The chef&#8217;s hat is all about <em>presentation</em>. You want the code to look beautiful, in addition to serving its purpose. There are few real-world situations that truly call for the chef&#8217;s hat, but  sometimes it&#8217;s just what you want to do.</p>
<p>Sometimes I&#8217;ll use this in a time-boxed way — once I&#8217;ve got the basic functionality working, I might &#8220;put on my chef&#8217;s hat&#8221; for thirty minutes and see if I can clean the code up a bit.</p>
<p>Like the captain&#8217;s hat, this one is sometimes mistaken for The Right Way, and is often overused. It&#8217;s easy to convince yourself that you&#8217;re doing something valuable, making the code more readable and maintainable. But often you&#8217;re just polishing for its own sake.</p>
<h2>Teacher&#8217;s hat 🧑‍🏫</h2>
<p>With the teacher&#8217;s hat on, you&#8217;re concerned about <em>what your code communicates</em>, and not so much on what it actually does. You might want to use this if you&#8217;re writing example code for an open source project, or writing a blog post to explain a concept.</p>
<p>Maybe you skip error checking, because it obscures the main thing you&#8217;re trying to show. Or you use more descriptive variable and function names than you otherwise would. You don&#8217;t pick the most efficient solution, you use the most <em>understandable</em> one.</p>
<p class="dinkus"></p>

<p>Look, I&#8217;m not trying to convince you to adopt my framework. I won&#8217;t be doing corporate training workshops anytime soon. But I do think it&#8217;s worth being deliberate about what mode you&#8217;re operating in, and asking yourself if a different approach might be worth trying.</p>
<p>💬 <em>Want to leave feedback? <a href="https://dubroy.com/blog/about/#contact">Send me an email</a> or respond on <a href="https://bsky.app/profile/dubroy.com/post/3lhbm7722jd2g">Bluesky</a> or <a href="https://hachyderm.io/@dubroy/113940096861433018">Mastodon</a>.</em></p>
<p>Related:</p>
<ul>
<li>Thorsten: <a href="https://registerspill.thorstenball.com/p/surely-not-all-codes-worth-it">Surely not all code&#8217;s worth it</a></li>
<li>Jimmy: <a href="https://jimmyhmiller.github.io/discovery-coding">Discovery coding</a></li>
</ul>]]>
  </description>
<slash:comments>0</slash:comments>
</item>
<item>
  <title>One way to do applied research</title>
  <link>https://dubroy.com/blog/one-way-to-do-applied-research/</link>
  <comments>https://dubroy.com/blog/one-way-to-do-applied-research/#comments</comments>
  <pubDate>Thu, 07 Nov 2024 00:00:00 -0000</pubDate>
  <dc:creator>Patrick Dubroy</dc:creator>
  <guid>https://dubroy.com/blog/one-way-to-do-applied-research/</guid>
  <description>
<![CDATA[<p>In some of the communities I hang around in<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>, there’s a fondness for the kind of industrial research that happened at places like PARC and Bell Labs. Things like Smalltalk, Mesa/Cedar, and Plan 9 not only introduced new ideas but demonstrated them in practical, working systems.</p>
<p>If you want to actually <em>do</em> research like this, how should you go about it?</p>
<p>There are a couple of obvious strategies. One is to look for unsolved problems — say, &#8220;addressing the scale-up problem in visual programming”. Another strategy is to solve an old problem with new techniques: “X, with CRDTs”. Both of these lead to something that is obviously novel, but it might not really be <em>useful</em>.</p>
<h2 class="smaller">Another path</h2>

<p>But there’s another strategy, which Alex and I took with <a href="https://ohmjs.org">Ohm</a>. I don’t think it’s groundbreaking, or even original, but it’s worth talking about because (imo) it’s a less obvious way to do research.</p>
<p>The idea is this: aim for practical utility first, by building something that addresses an actual need that you have. You don’t need an unsolved problem, but there should be something unique about your solution. In a sufficiently complex domain, there’s a good chance that  will lead to publishable research.</p>
<p>The core ideas behind Ohm came from Alex’s experience writing grammars with OMeta (which he also created). The abstract of our first publication gives a good overview of what makes Ohm unique:</p>
<blockquote>
<p>Parser generators give programmers a convenient and declarative way to write parsers and other language-processing applications, but their mechanisms for extension and code reuse often leave something to be desired. We introduce Ohm, a parser generator in which both grammars and their interpretations can be extended in safe and modular ways. Unlike many similar tools, Ohm completely separates grammars and semantic actions, avoiding the problems that arise when these two concerns are mixed.</p>
</blockquote>
<p>Ideally, whatever you build is something that helps advance your broader research agenda. When Ohm was created, I was working in <a href="https://web.archive.org/web/20170327022050/https://harc.ycr.org/flex/">Alex’s research group at CDG/HARC</a>. A lot of our research involved new programming languages and DSLs — so Ohm was valuable to us even if it hadn’t directly led to publishable work.</p>
<h2 class="smaller">What can you publish?</h2>

<p>That first Ohm publication, <a href="https://ohmjs.org/pubs/dls2016/modular-semantic-actions.pdf">Modular Semantic Actions</a>, is an example of the most likely outcome of this sort of research: a <em>systems paper</em>. There are many opinions on what makes a (good) systems paper, but I particularly like this one by Kayvon Fatahalian:</p>
<blockquote>
<p>Good systems papers often put forth an argument of the flavor:</p>
<p><em>&#8220;We are looking to achieve the goals A, B, C, under the constraints X, Y, Z. No system existed to do so when we set out on our efforts (otherwise we probably would have used it!), so from our experiences building systems in this area, we can distill these experiences into a specific set of system requirements. These requirements may not be obvious to readers who have not spent considerable time thinking about or building applications in this space.&#8221;</em></p>
</blockquote>
<p><em>(From <a href="https://graphics.stanford.edu/~kayvonf/notes/systemspaper/">What Makes a (Graphics) Systems Paper Beautiful</a>.)</em></p>
<p>But there&#8217;s another interesting thing that can happen. Once you&#8217;ve built a working system and put it to authentic use — i.e., used it to solve <em>actual</em> problems that you have — you&#8217;ll have a totally different perspective on the problem domain.</p>
<p>You&#8217;ll likely uncover other interesting research questions, things that weren&#8217;t obvious to you before. Those topics will naturally be less crowded, and you&#8217;ll have insight and expertise that other people in the field don&#8217;t have. On top of that, you now have a working system that you&#8217;re an expert in, which you can use for experimentation and validation.</p>
<p>This is what led to our second proper publication, <a href="https://ohmjs.org/pubs/sle2017/incremental-packrat-parsing.pdf">Incremental Packrat Parsing</a>. It&#8217;s unlikely we&#8217;d have written it if we hadn&#8217;t spent two years building Ohm and working on <a href="https://ohmjs.org/pubs/live2016/">live programming environments</a>. Alex had also been using Ohm in a class he was teaching at UCLA, and incremental parsing solved a real problem that he had with the interactive course materials.</p>
<p>And since we had a codebase that we were intimately familiar with, it didn&#8217;t take long to prototype our solution. As I recall, the core technical contribution in that paper was conceived and implemented on a single, two-week trip I made to LA in 2016.</p>
<h2 class="smaller">Indirect impact</h2>

<p>Building something useful is also a great way to have impact in the wider research community. Patrick Rein, from the University of Potsdam, adapted Ohm into a Smalltalk library called Ohm/S, leading to at least <a href="https://www.hirschfeld.org/writings/media/ReinHirschfeldTaeumel_2016_GramadaImmediacyInProgrammingLanguageDevelopment_AuthorsVersion.pdf">one publication</a>. In Daniel Jackson’s group at MIT, a number of projects have used Ohm, including <a href="https://deja-vu-platform.com/">Déjà Vu</a> and Geoffrey Litt&#8217;s <a href="https://www.geoffreylitt.com/wildcard/">Wildcard</a>. Ohm has also played a part of several of Geoffrey’s projects at Ink &amp; Switch, including <a href="https://www.inkandswitch.com/potluck/">Potluck</a> and <a href="https://www.inkandswitch.com/embark/">Embark</a>.</p>
<h2 class="smaller">Some objections</h2>

<p><strong>It won&#8217;t work for me!</strong> Perhaps not. I&#8217;m not saying it&#8217;s easy or that it&#8217;s the best approach to take. My only claim is that it <em>can</em> work.</p>
<p><strong>It&#8217;s obvious!</strong> Maybe it is. It certainly used to be fairly common in traditional research environments, both in industry and academia. It doesn&#8217;t seem as common these days.</p>
<p>I suspect many people outside these environments don&#8217;t even consider it, because it doesn&#8217;t <em>feel</em> like research.</p>
<p><strong>What do you know?</strong> Honestly, I&#8217;m not an expert. I&#8217;ve been following the HCI and PL literature for ~20 years, but I&#8217;ve only published a few &#8220;real&#8221; papers<sup id="fnref:2"><a class="footnote-ref" href="#fn:2" rel="footnote">2</a></sup>. I&#8217;ve had a handful of workshop papers, and have reviewed papers for CHI, Onward!, and LIVE. So, take my advice for what it&#8217;s worth.</p>
<p class="dinkus"></p>

<p>💬 <em>Feedback? <a href="https://dubroy.com/blog/about/#contact">Send me an email</a> or respond on <a href="https://bsky.app/profile/dubroy.com/post/3laeghu4xz22q">Bluesky</a>, <a href="https://hachyderm.io/@dubroy/113442052436015858">Mastodon</a>, or <a href="https://x.com/dubroy/status/1854524213195133048">Twitter</a>.</em></p>
<p><small><i>Thanks to Alex Warth for helpful feedback on this post, and for being a fantastic collaborator and co-author.</i></small></p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://futureofcoding.org/">Future of Coding</a>, the wider <a href="https://www.inkandswitch.com/">Ink &amp; Switch</a> community, frequent attendees of <a href="https://2020.splashcon.org/series/live">LIVE</a> &amp; <a href="https://sigplan.org/Conferences/Onward/">Onward!</a>, etc.&#160;<a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
<li id="fn:2">
<p>At <a href="https://en.wikipedia.org/wiki/Conference_on_Human_Factors_in_Computing_Systems">CHI</a>, <a href="https://dynamic-languages-symposium.org/">DLS</a>, and <a href="https://www.sleconf.org/">SLE</a>.&#160;<a class="footnote-backref" href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text">&#8617;</a></p>
</li>
</ol>
</div>]]>
  </description>
<slash:comments>0</slash:comments>
</item>
<item>
  <title>Memories of some fantastic internships</title>
  <link>https://dubroy.com/blog/memories-of-some-fantastic-internships/</link>
  <comments>https://dubroy.com/blog/memories-of-some-fantastic-internships/#comments</comments>
  <pubDate>Wed, 31 Jul 2024 00:00:00 -0000</pubDate>
  <dc:creator>Patrick Dubroy</dc:creator>
  <guid>https://dubroy.com/blog/memories-of-some-fantastic-internships/</guid>
  <description>
<![CDATA[<p>During my CS undergrad at <a href="https://carleton.ca/">Carleton University</a>, I had the opportunity to do a bunch of internships.<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup> Looking back, I can’t help but think how lucky I was! I got to work on some great teams, learned a ton, and had a lot of fun.</p>
<h2>Corel</h2>
<p>My first real internship was on the Linux team at <a href="https://en.wikipedia.org/wiki/Alludo">Corel</a> in the summer of 2000. I was super excited about this, for a couple of reasons:</p>
<ul>
<li>I had grown up using CorelDRAW.</li>
<li>I was super into Linux and open source at the time. (As in, I read Slashdot religiously and stayed home on Friday nights to recompile my kernel.) So an internship where I got <em>paid</em> to work on open source code was a dream!</li>
</ul>
<p>I spent the first summer working on <a href="https://www.winehq.org/">Wine</a>, which Corel used for the Linux versions of their products (CorelDRAW, WordPerfect, etc). Not only did I learn lots about doing serious development on Linux, but I also learned a ton about the Win32 API.</p>
<p>One of the highlights of the summer was getting to attend the <a href="https://en.wikipedia.org/wiki/Linux_Symposium">Ottawa Linux Symposium</a>. For those that don’t know, OLS was a pretty amazing conference. Here’s how <a href="https://linux.slashdot.org/story/00/07/31/1633205/ottawa-linux-symposium-2000-tech-rocks">Slashdot described it</a>:</p>
<blockquote>
<p>If you&#8217;ve got some kick-ass new code to add to Enlightenment, go talk to Rasterman. He&#8217;s right over there. Want to discuss something you need added to the kernel, and want to show off your source to Alan Cox? He&#8217;s sitting down hacking 2.4 while discussing Scooby-Doo. One of the great things about the Linux community is the ability to contact developers first-hand, especially though E-mail. Ottawa Linux Symposium is a testament to the fact that it works just as well in real life, too.</p>
</blockquote>
<p>After my internship was over, I stayed on as a part time employee during the school year, working on the <a href="https://en.wikipedia.org/wiki/Corel_Linux">Corel Linux</a> desktop team. I was a full-time intern again the next summer, but things were…different. Most of the Linux team had moved to another company (<a href="https://web.archive.org/web/20050205175507/https://www.xandros.com/news/press/release1.html">Xandros</a>), and those of us that were left ended up working on the FreeBSD port of the .NET CLR.<sup id="fnref:2"><a class="footnote-ref" href="#fn:2" rel="footnote">2</a></sup></p>
<h2>Eclipse &amp; SWT</h2>
<p>In the fall of 2001, I joined a company called <a href="https://en.wikipedia.org/wiki/Object_Technology_International">Object Technology International (OTI)</a> for an internship on the <a href="https://www.eclipse.org/">Eclipse</a> team. OTI was a subsidiary of IBM that was best known for producing VisualAge Smalltalk. They&#8217;d also created Eclipse, and at that time, they were just gearing up for the first public release.</p>
<p>Interestingly, many people on the team didn’t have any experience with open source. I remember explaining the basic development process to someone on my team: “So you run <code>diff</code>, generate a patch, and then send your patch to the mailing list…”</p>
<p>The team I worked on was responsible for <a href="https://www.eclipse.org/swt/">SWT</a>, the widget toolkit used by Eclipse. This gave me my first exposure to a few different native toolkits: MFC, Motif, and GTK. The main thing I worked on was the CoolBar widget, which earned me the nickname “Coolio” from the team&#8217;s TL.</p>
<p>Compared to Corel, the environment at OTI was much more like the stereotypical tech company. While we didn&#8217;t have free lunch, we did have a well-stocked kitchen with great breakfast cereals (I was a Corn Pops man), and a pool table and game consoles in the basement. I also remember how at the start of my internship, they apologized that I wouldn&#8217;t get my own office — I&#8217;d have to share with another intern.</p>
<h2>J9 VM Team</h2>
<p>The following summer, I returned to OTI to work on the J9 VM team. This was the same team who&#8217;d built the Smalltalk VM for VisualAge Smalltalk, and J9 was (at the time) a Java VM mostly designed for embedded applications.</p>
<p>One of the most memorable parts of this internship was how much Smalltalk code I wrote! Large parts of the VM were written in a kind of portable assembly language, implemented as a Smalltalk DSL. For each supported platform, there was a &#8220;backend&#8221; that would translate the portable assembly to native assembly for that platform.</p>
<p>One of the projects I worked on that summer was getting J9 running again on HP-UX (for PowerPC I think, not PA-RISC). The first step was getting the code generation working.  As I recall, the HP-UX/PPC backend was only partially implemented.</p>
<p>After I got the code generation working, it was a weeks-long process of fixing crash after crash. The first goal was just to get <code>j9 -version</code> working, and then to run a simple hello world program, and eventually to get a bigger benchmark like SPECjvm running.</p>
<p>Another project I worked on was for PalmOS. As I recall, J9 supported a kind of static linking on PalmOS, where the app bytecode was bundled together with the virtual machine into a native PalmOS app. When done naively, that resulted in some pretty big executables. So my task was to figure out how to make them smaller.</p>
<h2>J9 again: memory management</h2>
<p>In winter 2003 I did another internship on the J9 team, this time working on memory management.</p>
<p>As I mentioned, J9 was originally designed for embedded applications, but there was a push to make it work better for server applications. A big thing that needed to change was the garbage collector. So my colleague had taken on the task of writing a brand new memory management framework for J9 and a high-performance, parallel garbage collector. My job was to help him out any way that I could.</p>
<p>At the time, I had zero experience with garbage collection, but I picked things up pretty quickly. One of the first things I learned: since the GC needs to traverse every live object and a good portion of the internal VM data structures, any kind of memory corruption (like a dangling pointer) is likely to manifest as a crash in the GC. As we joked: “Always blame the garbage collector.”</p>
<p>So one of my first big tasks was to work on a heap verifier, aka &#8220;GC check&#8221;. The idea was to have a command line option (<code>-Xcheck:gc</code>) that would verify the state of the heap, and other GC-relevant VM structures, before and after every garbage collection. That way, when a crash got sent our way, we could pretty easily tell whether it was something <em>caused</em> by the GC or not. It was basically a perfect starter project.</p>
<p>It was an 8-month placement, but it worked out so well that I ended up spending the next four years there — working part time while I finished my degree, and then accepting a permanent job in 2004. I stayed there until 2006, when I got the urge to go back to school and do my master&#8217;s in human-computer interaction.</p>
<p>I learned an incredible amount of things from my time on the J9 team. Not only about memory management and systems programming, but about good engineering practices. I remember being struck by the size and scale of the build and test lab: 25m² or so, packed with all kinds of different hardware — from beefy rack-mount servers to <a href="https://en.wikipedia.org/wiki/Pocket_PC">Pocket PCs</a> and <a href="https://en.wikipedia.org/wiki/PalmPilot">Palm Pilots</a>. You&#8217;d arrive in the morning to find out you&#8217;d broken the build on some architecture you&#8217;d never heard of until then.</p>
<p>Looking back, I really can&#8217;t believe my luck in getting to work on something so technically challenging, but also high impact. Getting to help build a brand-new parallel GC framework from the ground up — as an intern! With one other person!<sup id="fnref:2"><a class="footnote-ref" href="#fn:2" rel="footnote">2</a></sup> Pretty amazing.</p>
<p class="dinkus"></p>

<p>One of the things I really miss from this period of my career was how frequently I got thrown into the deep end. I joined teams that I was not at all qualified for, and was handed projects that required expertise that I didn&#8217;t (yet) have. And this was totally expected!</p>
<p class="dinkus" style="visibility: hidden"></p>

<p>💬 <em>Feedback? You can <a href="https://dubroy.com/blog/about/#contact">send me an email</a> or <a href="https://x.com/dubroy/status/1818633209191547229">respond on Twitter</a>.</em></p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>I&#8217;m using the term <em>internship</em> here but in Canada we call them <a href="https://carleton.ca/co-op/what-is-co-op/the-carleton-co-op-advantage/">co-op work terms</a>.&#160;<a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
<li id="fn:2">
<p>I don&#8217;t remember the exact timeline, but the team did eventually grow bigger, I guess once it became clear that the project was going to succeed.&#160;<a class="footnote-backref" href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text">&#8617;</a></p>
</li>
</ol>
</div>]]>
  </description>
<slash:comments>0</slash:comments>
</item>
<item>
  <title>Playing like a kid again</title>
  <link>https://dubroy.com/blog/playing-like-a-kid-again/</link>
  <comments>https://dubroy.com/blog/playing-like-a-kid-again/#comments</comments>
  <pubDate>Sun, 30 Jun 2024 00:00:00 -0000</pubDate>
  <dc:creator>Patrick Dubroy</dc:creator>
  <guid>https://dubroy.com/blog/playing-like-a-kid-again/</guid>
  <description>
<![CDATA[<p>For the last 13 years, I’ve done the same thing almost every Monday night. At 9pm, I head out to a small sports club on the outskirts of Munich to play 5-a-side soccer. Many players have left, and new people have joined, but there’s a core group of us who’ve stayed the same.</p>
<p>When you’ve been doing the same thing, with the same guys, for more than 13 years, it’s easy to get a little attached to that structure. So, a few weeks ago, I was a little annoyed when only four of us showed up.</p>
<p>If you’re not familiar with 5-a-side: the game is pretty flexible. Ten players is obviously ideal, but up to 14 is ok — one or two players on each side can take a short break to catch their breath. 4-on-4 works, and even 3-on-3 is alright in a pinch. But 2-on-2? Nah.</p>
<p>At least, that was my first reaction. The four of us bummed around for five or ten minutes while we discussed what we should do. Maybe just head home, and go to bed early?</p>
<p>In the end, we decided to set up a small playing field with some water bottles marking the goals. Then somebody suggested that we should make it a bit more challenging: instead of shooting the ball between the bottles, what if the goal was to knock the bottles over? Another idea: “…and maybe you get two points if you knock them both over.”</p>
<p>The four of us played this game for over an hour, until our legs gave out. And, you know what? It was the most fun I’ve had playing soccer in a long time. I was convinced that anything other than proper 5-a-side, the way I was used to, just wouldn’t be worth it. And I was totally wrong.</p>
<p class="dinkus"></p>

<p>Sometime last year, I noticed that I was hardly doing any work on side projects anymore. And when I thought about why that I was, I realized it was because all my side projects felt like work.</p>
<p>I wrote about this in my last post, <a href="https://dubroy.com/blog/taking-learning-seriously/">Taking Learning Seriously</a>:</p>
<blockquote>
<p>One of the best decisions I&#8217;ve made in the past few years is to stop treating side projects like work projects.</p>
<p>Previously, I tended to work on things that were either useful, novel, or valuable (i.e., could possibly be turned into some kind of business). It’s almost as if I was trying to satisfy a hypothetical Hacker News commenter.</p>
</blockquote>
<p>I also felt compelled to make defensible engineering choices on my projects. Like using the appropriate language for the problem, and reusing existing code whenever I could, rather than reinventing the wheel.</p>
<p>It was another instance of unconsciously adopting a restrictive set of assumptions, telling myself that if I wasn’t done “right”, it wasn’t worth doing at all.</p>
<p>And guess what — when I decided to let go of those assumptions, I started having fun on my side projects again.</p>
<p>💬 <em>Feedback? You can <a href="https://dubroy.com/blog/about/#contact">send me an email</a> or <a href="https://x.com/dubroy/status/1807761076307534150">respond on Twitter</a>.</em></p>]]>
  </description>
<slash:comments>0</slash:comments>
</item>
</channel>
</rss>