<?xml version="1.0" encoding="utf-8"?>
    <feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://aaronfranks.com/">
      
  <title>Aaron Franks</title>
  <subtitle>Area man rambles about programming</subtitle>
  <link href="https://aaronfranks.com//atom.xml" rel="self"/>
  <link href="https://aaronfranks.com/"/>
  <updated>2021-01-24T08:00:00Z</updated>
  <id>https://aaronfranks.com/</id>
  <author>
  <name>Aaron Franks</name>
  <email/>
  </author>

      
    <entry>
      <title>2025 Review</title>
      <link href="/posts/2025-review" />
      <updated>Sat, 31 Jan 2026 00:00:00 GMT</updated>
      <id>/posts/2025-review</id>
      <content type="html"><![CDATA[<p>While browsing a local bookshop for Christmas gifts last month, I happened upon a cover that encapsulated my 2025 perfectly:</p>
<p><img src="/img/posts/shit_sandwiches.png" alt="lazy susan of shit sandwiches"></p>
<p>That is to say, it was not a great year. A confluence of uncontrollable factors made 2025 a year that I am eager to forget.</p>
<p>In that sense, the ol' yearly reflection ritual is a welcome opportunity to mine the last 12 months for nuggets of positivity, and then mentally turn the page.</p>
<h2>Learning</h2>
<p>Nothing shakes you out of your comfort zone and gives you a fresh perspective like learning a new skill. It's something I don't do nearly enough, but this year I dabbled in learning Japanese and chess while leeching off my generous neighbour's Duolingo family plan. I continue to be terrible at both, but it's fun to rediscover the "beginner's mind" and eagerly receive the teachings of repeated failure.</p>
<p>A decade after my first failed attempts, I also tried my hand at baking sourdough again. This time I found more regularity and success, thanks to <a href="https://alexandracooks.com/2017/10/24/artisan-sourdough-made-simple-sourdough-bread-demystified-a-beginners-guide-to-sourdough-baking/">a significantly more forgiving recipe</a>. Since I hate wasting
anything, these <a href="https://alexandracooks.com/2022/09/11/easy-sourdough-discard-crackers-5-ingredients/">crackers</a> are a welcome way to use the discard.</p>
<p>Tactility and experimentation make bread baking a deeply satisfying activity. It doesn't hurt that you end up with something that tastes far better, and costs $5 less, than a commercial loaf.</p>
<h2>Reading</h2>
<p>Readers of this blog will know that my chief vanity metric is the number of books read for the year. With only a little cheating (due to partially completed slogs), I landed at 50, with the following highlights:</p>
<ul>
<li><strong>Brave New Words</strong> by Sal Khan</li>
<li><strong>Nexus</strong> by Yuval Noah Harari</li>
<li><strong>The Future is Analog</strong> by David Sax</li>
<li><strong>Corpse Talk</strong> - Queens and Kings, Scientists, Women (delightful educational graphic novels recommended by my kid)</li>
<li><strong>Refactoring UI</strong> (re-read for the third time, but it's so good)</li>
<li><strong>The Notebook: A History of Thinking on Paper</strong> by Roland Allen</li>
<li><strong>Norwegian Wood</strong> by Haruki Murakami</li>
<li><strong>Empire of AI</strong> by Karen Hao</li>
<li><strong>Careless People</strong> by Sarah Wynn-Williams</li>
<li><strong>The Price of Time</strong> by Edward Chancellor</li>
<li><strong>Chip War</strong> by Chris Miller</li>
<li><strong>Showa: A History of Japan</strong> (1944-1953, and 1953-1989)</li>
<li><strong>Enshittification</strong> by Cory Doctorow</li>
</ul>
<p>Challenging myself to take a full page of notes for almost every book paid dividends. While typing the preceding list, I referred back to notes on several books and it helped refresh my understanding. After years of forgetting what I read almost immediately, this might be the start of a solution.</p>
<h2>Watching</h2>
<p>I'm no cinephile, but several movies I watched this year were outstanding:</p>
<ul>
<li>Everything Everywhere All at Once</li>
<li>Parasite</li>
<li>If I Had Legs I'd Kick You</li>
</ul>
<p>Also, S2E3 of The Rehearsal ("Pilot's Code") may be my all-time favorite episode of television.
I have not laughed that hard in a very long time, and Nathan Fielder is a treasure. I'm proud to
live not far from the top business school where he earned really good grades.</p>
<h2>Listening</h2>
<p>Losing Sly Stone and D'Angelo, two of the all-time greats, was a gut punch. Sly's mental deterioration since the 70s was well-documented, but I thought D'Angelo had at least one more great album in him. I'll leave you with this <a href="https://www.youtube.com/watch?v=_RLP0xAjdJU">achingly beautiful version of Africa</a>.</p>
<h2>Gaming</h2>
<p>I started rediscovering my childhood love of video games after a multi-decade hiatus. Playing through Ocarina of Time was a highlight, and convinced me to get a Switch 2. I'm astounded by how compelling game storytelling and user interfaces are now, and it's a treat to explore them with my kids. Mario Kart World and Moving Out have both been big hits for couch co-op in our household.</p>
<h2>Computering</h2>
<p>2025 was a year of massive change for the field of software engineering, as generative AI has
turned the economics of building software inside out. I tried to summarize the changes in my
<a href="/posts/a-year-of-wrestling-with-ai-coding">previous post</a>, but things are shifting so quickly that
I struggle to put into words either the current state of play, or the last year of changes.</p>
<p>I have been cured of the comfortable delusion that the status quo of fully "hand-crafted" software
will be the way I work forever. The following quote <a href="https://simonwillison.net/2026/Jan/8/llm-predictions-for-2026/">from Simon Willison</a> perfectly summarizes the uncertainty I feel:</p>
<blockquote>
<p>We will find out if the Jevons paradox saves our careers or not. This is a big question that anyone who’s a software engineer has right now: we are driving the cost of actually producing working code down to a fraction of what it used to cost. Does that mean that our careers are completely devalued and we all have to learn to live on a tenth of our incomes, or does it mean that the demand for software, for custom software goes up by a factor of 10 and now our skills are even more valuable because you can hire me and I can build you 10 times the software I used to be able to? I think by three years we will know for sure which way that one went.</p>
</blockquote>
<p>Elsewhere, I think people are sleeping on how rapidly HTML &#x26; CSS are improving. Recent standardization of
popovers, anchor positioning, invoker commands, view transitions, and more, will make so much repetitive and needlessly complex JavaScript unnecessary. With the React ecosystem trending toward the unrestrained accumulation of accidental complexity (<em>cough</em> Server Components <em>cough</em>), my money's on a new, leaner, shape of web applications emerging in the not-too-distant future.</p>
<h2>Coda</h2>
<p>Anyways, thank you for reading my annual ramble. The backdrop of world events makes it hard to remember, but 2026 could be a whole lot better.</p>
]]></content>
    </entry>
  

    <entry>
      <title>A year of wrestling with AI-assisted coding</title>
      <link href="/posts/a-year-of-wrestling-with-ai-coding" />
      <updated>Sat, 24 Jan 2026 00:00:00 GMT</updated>
      <id>/posts/a-year-of-wrestling-with-ai-coding</id>
      <content type="html"><![CDATA[<p>As I slowly prepare the usual year-in-review post, I find a lot of my reflections pertain to
the aggressively debated topic of generative AI reshaping the profession of software engineering.</p>
<p>For most of the year, I found the discourse on this topic aggravating. It was mostly two groups shouting past each other, without engaging with the opposing view in good faith. On one hand, you had the AI hype bros, proclaiming the near-term inevitability of AGI and the impending obsolescence of all knowledge workers. On the other, there were the doomers who regularly dunk on a technology that is still in its infancy.</p>
<p>Thankfully, there are practitioners out there who have taken a more pragmatic and incisive view of the topic. Along with regular updates from <a href="https://simonwillison.net/">Simon Willison's blog</a>, the following posts helped cut through the noise and evolve my thinking as the state of the art has changed dramatically over the year.</p>
<h2>On vibe coding</h2>
<p>It's hard to believe the term "vibe coding" was coined in Feb 2025, less than a year ago. Many
words were spilled as we all wrestled with its emergence, and its fundamental limitations.</p>
<ul>
<li><a href="https://dylanbeattie.net/2025/04/11/the-problem-with-vibe-coding.html">The problem with "vibe coding"</a></li>
<li><a href="https://tidyfirst.substack.com/p/augmented-coding-beyond-the-vibes?r=m7vsc&#x26;triedRedirect=true">Augmented Coding: Beyond the Vibes</a></li>
<li><a href="https://blog.nilenso.com/blog/2025/05/29/ai-assisted-coding/">AI-assisted coding for teams that can't get away with vibes</a></li>
<li><a href="https://blog.val.town/vibe-code">Vibe code is legacy code</a></li>
</ul>
<h2>On building better tools</h2>
<p>I also cannot believe that Claude Code was released in Feb 2025. It's become my default AI assistant. And while the UX is pretty decent, I think we still have a long way to go to reach an optimal harness for human-machine collaboration.</p>
<ul>
<li><a href="https://sketch.dev/blog/agent-loop">The Unreasonable Effectiveness of an LLM Agent Loop with Tool Use</a></li>
<li><a href="https://www.youtube.com/watch?v=nfOVgz_omlU">Agentic Coding: The Future of Software Development with Agents (video)</a></li>
<li><a href="https://www.geoffreylitt.com/2025/07/27/enough-ai-copilots-we-need-ai-huds">Enough AI copilots! We need AI HUDs</a></li>
</ul>
<h2>On where programmers fit</h2>
<p>At the start of 2025, it was defensible to think that AI-assisted coding was an over-hyped fad
that would fail to affect the day-to-day work of most software engineers. That argument has been smashed to
bits after a year of feverish progress. As someone who still wants to be actively involved in making software, the central question I'm left with is: where do I fit, over the long term? And how should I relate to
these new magical sidekicks, without abdicating my responsibility and understanding?</p>
<ul>
<li><a href="https://chrisloy.dev/post/2025/09/28/the-ai-coding-trap">The AI Coding Trap</a></li>
<li><a href="https://hojberg.xyz/the-programmer-identity-crisis/">The Programmer Identity Crisis</a></li>
<li><a href="https://rgoldfinger.com/blog/2025-07-26-claude-code-is-a-slot-machine/">Claude Code is a Slot Machine</a></li>
<li><a href="https://frankchimero.com/blog/2025/beyond-the-machine/">Beyond the Machine</a></li>
<li><a href="https://davegriffith.substack.com/p/software-development-in-the-time">Software development in the Time of Strange New Angels</a></li>
<li><a href="https://simonwillison.net/2025/Dec/18/code-proven-to-work/">Your job is to deliver code you have proven to work</a></li>
<li><a href="https://chrisloy.dev/post/2025/12/30/the-rise-of-industrial-software">The Rise of Industrial Software</a></li>
</ul>
<p>I'm looking forward to revisiting all these posts in a few years' time, to see how baroque and janky the
tools we are using in 2025 seem by then. Or perhaps to pine with nostalgia for a time when despite
the presence of agents, we still had our agency.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Short and punchy</title>
      <link href="/posts/short-and-punchy" />
      <updated>Fri, 04 Apr 2025 00:00:00 GMT</updated>
      <id>/posts/short-and-punchy</id>
      <content type="html"><![CDATA[<p>An unfortunate pattern pervades the world of nonfiction books. Every chapter begins with
a drawn-out story, before the author eventually circles back to reveal its central lesson.</p>
<p>This formula pads a dozen pages of useful information into a 200+ page slog. Instead of reading the
book in an afternoon, it might take you weeks to work through (if you finish it at all).</p>
<p>I don't know if the root cause is the author's <a href="https://borretti.me/article/non-fiction-has-bad-incentives">quest for status</a>,
the publisher enforcing their prescribed formula, or something else. Either way, the reader loses.</p>
<p>We should celebrate the books that eschew this blueprint, delivering a clear and forceful message
while staying concise and considerate of the reader's time.</p>
<p>Below are some of my favourite “short and punchy” authors and books.</p>
<p>Derek Sivers:</p>
<ul>
<li><a href="https://sive.rs/u">Useful Not True</a></li>
<li><a href="https://sive.rs/n">Hell Yeah or No</a></li>
<li><a href="https://sive.rs/a">Anything You Want</a></li>
<li><a href="https://sive.rs/m">Your Music and People</a></li>
<li><a href="https://sive.rs/h">How to Live</a></li>
</ul>
<p>37signals:</p>
<ul>
<li><a href="https://basecamp.com/shapeup/shape-up.pdf">Shape Up</a></li>
<li><a href="https://basecamp.com/gettingreal/getting-real.pdf">Getting Real</a></li>
<li><strong>Remote</strong></li>
<li><strong>Rework</strong></li>
</ul>
<p>Steven Pressfield:</p>
<ul>
<li><strong>The War of Art</strong></li>
<li><strong>Turning Pro</strong></li>
</ul>
<p>By others:</p>
<ul>
<li><a href="https://www.refactoringui.com/">Refactoring UI</a></li>
<li><a href="https://archive.org/details/epictetus-the-enchiridion">The Handbook</a> by Epictetus</li>
<li><strong>The Psychology of Money</strong> by Morgan Housel</li>
<li><strong>The Bed of Procrustes</strong> by Nassim Nicholas Taleb</li>
<li><strong>Excellent Advice for Living</strong> by Kevin Kelly</li>
<li><strong>Zen Mind, Beginner's Mind</strong> by Shunryu Suzuki</li>
<li><strong>Several Short Sentences About Writing</strong> by Verlyn Klinkenborg</li>
<li><strong>Man's Search for Meaning</strong> by Viktor Frankl</li>
</ul>
<p>(I'll add more as I discover or remember them)</p>
]]></content>
    </entry>
  

    <entry>
      <title>2024 Review</title>
      <link href="/posts/2024-review" />
      <updated>Fri, 24 Jan 2025 00:00:00 GMT</updated>
      <id>/posts/2024-review</id>
      <content type="html"><![CDATA[<p>I've finally cleared away the bitrot and gotten this new yearly review post out. It's weirdly satisfying to tend to my little personal online space, even if only for this annual post.</p>
<h2>Blogs I liked in 2024</h2>
<p>Unlike this blog, there are many independent sites that publish high quality work at a regular cadence. I'm always on the lookout for more of them, but here are a few that I learned a lot from in 2024:</p>
<ul>
<li><a href="https://www.afterbabel.com/">After Babel</a> - on parenting, technology, mental health, and their intersections</li>
<li><a href="https://simonwillison.net/">Simon Willison</a> - Still doing phenomenal work distilling the latest on LLMs</li>
<li><a href="https://borretti.me">Fernando Borretti</a>, <a href="https://mxb.dev">Max Böck</a> - A few new-to-me programmer blogs I added to my feed list</li>
<li><a href="https://frontendfront.com">Front-end Front</a> and <a href="https://sidebar.io">Sidebar.io</a> - high signal/noise link aggregators</li>
</ul>
<h2>Frontend tooling is good actually</h2>
<p>In late 2023 I started toying with <a href="https://bun.sh/">Bun</a>, and in 2024 it became the default for every project I work on. Its speed and simplicity are wonderful compared to all of the moving parts you'd traditionally need to cobble together with Node/ts-node/Yarn/Webpack/Babel/etc.</p>
<p>I also replaced ESLint with <a href="https://biomejs.dev/">Biome</a>, and moved several projects to <a href="https://vite.dev/">Vite</a>. These tools may not have all the bells and whistles of their legacy equivalents, but they're simpler, faster, and meet all of my needs very well.</p>
<h2>Neovim is still fun</h2>
<p>Late in the year I rediscovered my preferred outlet for <a href="https://structuredprocrastination.com/">structured procrastination</a> - tweaking my neovim config. I discovered <a href="https://github.com/echasnovski/mini.nvim">mini.nvim</a> and it is glorious. In evolving my setup from several old plugins to mini's modules, so far I've removed 12 plugins and several hundred lines of manual configuration, and even started my own colorscheme (I really didn't anticipate that last part). Looking forward to exploring mini and writing more Lua in 2025.</p>
<h2>Coding in the Age of AI</h2>
<p>Don't worry, that subhead is tounge-in-cheek. Everyone in software development wote a similarly grandiose think piece this year, so here's my take: despite egregiously overdone hype, AI-assisted coding is already very useful, and it's going to be fascinating to see how the human-to-code interface evolves over the next few years.</p>
<p>I started out as a pretty big skeptic. Early versions of Copilot had latency bad enough to negate the benefits of AI
completions, and they were only useful about 15% of the time anyways.</p>
<p>But after switching to <a href="https://supermaven.com/">Supermaven</a> this year I've appreciated that some
kind of AI developer augmentation is not just inevitable, but kind of great. Unfortunately,
Supermaven's now been acquired, so its developent seems to be over. I'd love to stay in Neovim, so
I'm curious what the next wave of editor-independent AI coding tools looks like.</p>
<p>This is all not to trivialize the degree of social and economic upheaval likely to be wrought by these
tools. I don't think it's going to be as bad as the doomers think, and for a curious and ambitious
generalist, I think the future looks very bright. We'll see how that view holds up in 5 years.</p>
<p>A few reads I've enjoyed on this topic:</p>
<ul>
<li><a href="https://dustinewers.com/ignore-the-grifters/">Ignore the grifters - AI Isn't Going to Kill the Software Industry</a></li>
<li><a href="https://sourcegraph.com/blog/cheating-is-all-you-need">Cheating is All You Need</a></li>
</ul>
<h2>Gadgetry</h2>
<p>I'd resisted the "wearable" category of devices until 2024, but finally succumbed to a new Apple Watch in October. Purchased to help train for a half-marathon (mission accomplished), I've enjoyed its various health-tracking functions. I was apprehensive about bringing yet another <a href="https://theonion.com/report-90-of-waking-hours-spent-staring-at-glowing-re-1819570829/">glowing rectangle</a> into my life, but in a surprising twist, moving a subset of notifications to my wrist has reduced the frequency and overall duration of my phone use. The bulkiness and battery life of the watch are not great, but overall it's been a net-positive.</p>
<p>Continuing on the theme of gadgets-that-stop-me-from-using-other-gadgets, I'm now into year 5 with my reMarkable 2 and it's still going strong. Carving out the first 30 minutes after waking to journal and plan on it with my morning coffee has been a great way to start the day. I try to do as much digital reading on the rM2 as possible and it's been great to continue to spend less time on my laptop.</p>
<h2>Books</h2>
<p>As mentioned <a href="/posts/2023-review">last year</a>, my reading goal was to take notes and retain more, even if it meant I read less. And in fact that's exactly what happened– while I finished less than a book per week, I recorded a page of notes for 20 of them. Reviewing the notes was surprisingly helpful! I plan to keep up this practice and am now using a new template to write them up on my reMarkable. Some of my favourite reads for the year were:</p>
<ul>
<li><strong>The Anxious Generation</strong> by Jonathan Haidt</li>
<li><strong>Useful Not True</strong> by Derek Sivers</li>
<li><strong>Slow Productivity</strong> by Cal Newport</li>
<li><strong>Good Inside</strong> by Becky Kennedy</li>
<li><strong>Not the End of the World</strong> by Hannah Ritchie</li>
<li><strong>Several Short Sentences About Writing</strong> by Verlyn Klinkenborg</li>
<li><strong>The Infinite Game</strong> by Simon Sinek</li>
<li><strong>Burn Book</strong> by Kara Swisher</li>
<li><strong>How to Know a Person</strong> by David Brooks</li>
<li><strong>Outlive</strong> by Peter Attia</li>
<li><strong>Excellent Advice for Living</strong> by Kevin Kelly</li>
</ul>
<h2>Gratitude</h2>
<p>On a personal note, 2024 was split into 2 parts– the first of stress and anxiety, and the second of
reflection and gratitude. In an increasingly uncertain world, I feel truly blessed to be healthy, safe, and most importantly, able to spend lots
of time with the people I love.</p>
]]></content>
    </entry>
  

    <entry>
      <title>2023 Review</title>
      <link href="/posts/2023-review" />
      <updated>Sat, 27 Jan 2024 00:00:00 GMT</updated>
      <id>/posts/2023-review</id>
      <content type="html"><![CDATA[<p>Hard to believe I have been doing these annual posts for over a decade now. Revisiting some of the
old entries triggered a strange mix of nostalgia and cringiness. But I am compelled, against all reason, to keep going! And thus, this post exists.</p>
<h2>New Tech</h2>
<p>Dunking on the Rube Goldberg-esque complexity of the JavaScript ecosystem has been a well-trodden trope for
years. So it has been very refreshing to spend some time playing with <a href="https://bun.sh/">Bun</a> in
late 2023. It's oversold as a "drop-in Node replacement", as many compatibility issues remain, but the speed and simplicity is a breath of fresh air. Bun's pace of development is truly impressive, too, and despite the lack of a sustainable funding model, it's been so fun to use that I'm considering moving a few projects from Node to Bun this year.</p>
<p>Of course LLMs were a fascinating topic in 2023. <a href="https://simonwillison.com/">Simon Willison's blog</a> was, and continues to be, an engineering generalist's essential reading on the topic. ML is very far from my circle of competence but it's been fun to learn about a new field that is deep and fascinating.</p>
<h2>Reading</h2>
<p>Regular readers of the blog (are there any?) will be familiar with my annual vanity metric– number
of books read in the year. Even as I smashed my previous record this year, I realized how pointless
and counter-productive this number is, given I retain very little of what I read. For 2024 my goal is to take a full page of notes for <strong>20</strong> high-quality books. I did this for only 9 books last year.</p>
<p>Retention issues aside, I enjoyed quite a few reads this year. Favourites were:</p>
<ul>
<li><strong>Rusty Brown</strong> Chris Ware</li>
<li><strong>Same as Ever</strong> Morgan Housel</li>
<li><strong>Drive</strong> Dan Pink</li>
<li><strong>Outlive</strong> Peter Attia</li>
<li><strong>Competing against Luck</strong> Christensen et al</li>
<li><strong>Building a Second Brain</strong> Tiago Forte</li>
<li><strong>From Strength to Strength</strong> Arthur Brooks</li>
<li><strong>Clear Thinking</strong> Shane Parrish</li>
<li><strong>Exhalation</strong> Ted Chiang</li>
<li><strong>Just Keep Buying</strong> Nick Maggiuli</li>
<li><strong>The Remains of the Day</strong> Kazuo Ishiguro</li>
<li><strong>You are Here</strong> Thich Nhat Hanh</li>
<li><strong>Invisible Boy</strong> Harrison Mooney</li>
<li><strong>Dilla Time</strong> Dan Charnas</li>
<li><strong>Hark! A Vagrant</strong> and <strong>Ducks</strong> Kate Beaton</li>
<li><strong>Lost and Founder</strong> Rand Fishkin</li>
<li><strong>Refactoring UI</strong> Wathan &#x26; Schoger</li>
<li><strong>Turning Pro</strong> Steven Pressfield</li>
<li><strong>Mind MGMT – Omnibus 1</strong> Matt Kindt</li>
<li><strong>Be Useful</strong> Schwarzenegger</li>
</ul>
<h2>Blogging and such</h2>
<p>Last year I wrote down some nifty indieweb tech that I thought would be cool to explore on this
site, and predictably, none of those things came to fruition. One day, maybe. As usual
I didn't really write anything here, though I did do a little blogging <a href="https://hyperpaper.me/blog">elsewhere</a>. A few people even told me those posts were useful, which, if true, is probably a first for me.</p>
]]></content>
    </entry>
  

    <entry>
      <title>2022 Review</title>
      <link href="/posts/2022-review" />
      <updated>Mon, 02 Jan 2023 00:00:00 GMT</updated>
      <id>/posts/2022-review</id>
      <content type="html"><![CDATA[<p>It must be the start of a new year, because I feel the familiar twinge of guilt about not
having written anything here, and an accompanying compulsion to rush out a "year in review" blog
post. So here it is!</p>
<h2>Side project</h2>
<p>Last year I built a customizable <a href="https://hyperpaper.me">pdf planner and calendar</a> for my reMarkable 2 with a Google Form, TypeScript, and considerable
duct tape and spit polish. This year I kept plugging away at it, and the response
certainly exceeded my expectations. Scott Hanselman <a href="https://twitter.com/shanselman/status/1605735923441811458">gave me an early Christmas present</a> and the project <a href="https://news.ycombinator.com/item?id=34100752">made the top 10 of HN</a> the next day. More improvents and some related projects are in the hopper for 2023!</p>
<h2>New Tech</h2>
<p>Tried out some new technologies this year and rather enjoyed them. Each of these should probably
get their own post at some point, but for now I'll just say that I award my coveted seal of approval
to:</p>
<ul>
<li><a href="https://remix.run">Remix</a> – love the runtime agnosticism, so it works well with both Node
and...</li>
<li><a href="https://workers.cloudflare.com/">Cloudflare Workers</a> – turns out "serverless" isn't just an
empty fad after all</li>
<li><a href="https://fly.io">fly.io</a> as a modern Heroku replacement</li>
<li><a href="https://github.com/gajus/slonik">Slonik</a> for typed SQL without an ORM</li>
</ul>
<h2>Reading</h2>
<p>Chewed through an even 50 books this year. Less than one per week; I must be slipping. Favourites
were:</p>
<ul>
<li><strong>The Righteous Mind</strong> Jonathan Haidt</li>
<li><strong>Software Design X-Rays</strong></li>
<li><strong>Breath</strong> James Nestor</li>
<li><strong>The Happiness Hypothesis</strong> Jonathan Haidt (again)</li>
<li><strong>Project Hail Mary</strong> Andy Weir</li>
<li><strong>The Lords of Easy Money</strong> Christopher Leonard (very topical!)</li>
<li><strong>The Shallows</strong> Nicholas Carr</li>
<li><strong>Die With Zero</strong> Bill Perkins</li>
<li><strong>A Man for all Markets</strong> Edward O. Thorpe</li>
<li><strong>The Cuckoo's Egg</strong> Cliff Stoll</li>
<li><strong>Four Thousand Weeks</strong> Oliver Burkeman</li>
<li><strong>Anything You Want</strong> Derek Sivers</li>
<li><strong>The Psychology of Money</strong> Morgan Housel</li>
<li><strong>The Lazy Dungeon Master's Guide</strong> (family d&#x26;d was a new thing this year)</li>
<li><strong>The E-Myth Revisited</strong> Michael Gerber</li>
<li><strong>The Emperor of all Maladies</strong> Siddhartha Mukherjee</li>
</ul>
<h2>Music</h2>
<p>Somehow I had never listened to <a href="https://www.youtube.com/@Vulf">Vulfpeck</a> before this
year. They're a fun band; I enjoyed going through their back catalogue and associated acts like The Fearless Flyers.</p>
<h2>This website</h2>
<p>Did pretty much nothing with the ol' personal website this year. With the surge in interest in
federated web tech (thanks to Twitter's implosion), I'm regaining interest in sprucing up this site
with Webmentions and other "indieweb" tech. To that end, I'm liberating an old list of links that
have laid dormant in my Gmail tasks sidebar for eons, in case they're useful:</p>
<ul>
<li><a href="https://mxb.dev/blog/using-webmentions-on-static-sites/">Using Webmentions on Eleventy</a></li>
<li><a href="https://vincentp.me/articles/2018/11/14/20-00/">Implementing the Indieweb on a static site</a></li>
<li><a href="https://indieweb.org/Category:building-blocks">Indieweb building blocks</a></li>
<li><a href="https://matthiasott.com/articles/into-the-personal-website-verse">Into the Personal Website-verse</a></li>
<li><a href="https://alistapart.com/article/webmentions-enabling-better-communication-on-the-internet/">Webmentions: Enabling Better Communication on the Internet</a></li>
</ul>
<p>I resisted the impulse to rewrite this content-free site again, so that's a positive for the year at least. NextJS
is still definitely a good fit for the low-maintenance static deploy that I favor, but if I ever
dabble in the indieweb tech above, I might give Remix a spin here as well.</p>
]]></content>
    </entry>
  

    <entry>
      <title>2021 Review</title>
      <link href="/posts/2021-review" />
      <updated>Fri, 31 Dec 2021 00:00:00 GMT</updated>
      <id>/posts/2021-review</id>
      <content type="html"><![CDATA[<p>For the first time since 2013, I have completed my year-end post before the calendar turns over.
I think the key is skimping out on the intro paragraph.</p>
<h2>Building stuff</h2>
<p>I remain enamored with <a href="/posts/remarkable-2">my reMarkable 2</a> after 14 months of daily use. The
large-eInk-screen-with-low-latency-pen-input device really feels like a new medium with a ton of untapped
potential. My recreational coding time this year was dedicated to enhancing my reMarkable’s utility. I built:</p>
<ul>
<li>A service that sends a twice-a-day pdf “newspaper” from RSS/reddit/twitter feeds straight to my
device. I’ve been using this for 9 months and still look forward to the paper every time.</li>
<li>A fully hyperlinked day planner for consolidating several of my rM notebooks into one pdf (more
on this in the next section)</li>
<li>several custom template files for my specific note-taking workflows</li>
</ul>
<h2>A "real" side project</h2>
<p>That <a href="https://hyperpaper.me/">reMarkable day-planner</a> took on a life of its own after sharing it on
reddit, and for the first time I made a little income from a side project. Not enough to pay even a
single month’s rent, mind you, but it’s still been enormously satisfying to receive the positive
feedback and email from satisfied customers. You can, and should, order your own custom planner at
<a href="https://hyperpaper.me">hyperpaper.me</a>. I hope to write up a post at some point with "lessons learned"
from putting this out there.</p>
<h2>Reading</h2>
<p>I read 57 books this year (gotta keep sharing my personal vanity metric). Favourites were:</p>
<ul>
<li>Masters of Doom</li>
<li>The Art of Postgres</li>
<li>The Psychology of Money</li>
<li>Lives of the Stoics</li>
<li>Burke’s Law</li>
<li>Shape Up</li>
<li>Carrying the Fire</li>
<li>Bullshit Jobs</li>
<li>Strong Towns</li>
<li>How to Avoid a Climate Disaster</li>
<li>The Vignelli Canon</li>
<li>A Wealth of Common Sense</li>
</ul>
<h2>Links</h2>
<p>My favourite links on Pinboard over the year:</p>
<ul>
<li><a href="https://next.github.com/projects/repo-visualization">Visualizing a codebase</a></li>
<li><a href="https://aantron.github.io/dream/">Dream - tidy web framework for OCaml</a></li>
<li><a href="https://www.fontshare.com/">Fontshare</a> (I love me some pretty free fonts)</li>
<li><a href="https://thetyee.ca/Analysis/2020/12/14/Vancouver-Missing-Middle-Housing-Mystery/">This Video Perfectly Explains Vancouver’s ‘Missing Middle’ Housing Mystery</a></li>
<li><a href="https://www.capitaldaily.ca/news/blanket-zoning-pre-zoning-city-initiated-rezoning-victoria">How to make space</a></li>
<li><a href="https://newsletter.pragmaticengineer.com/p/project-management-in-tech">How Big Tech Runs Tech Projects and the Curious Absence of Scrum</a></li>
<li><a href="https://simonhearne.com/2021/layout-shifts-webfonts/">How to avoid layout shifts caused by webfonts</a></li>
</ul>
<h2>Music</h2>
<p>I am an old man, so it’s rare for a new album to trigger both intense anticipation and thorough
enjoyment. But <a href="https://www.youtube.com/watch?v=xA5hlB6bScc&#x26;list=PL9wpmMBKluP5LdNQDubgQvTDAgPtghZtC">An Evening with Silk Sonic</a>
absolutely knocked it out of the park for me. It was easily my favourite new album in years, and if
you enjoy vintage R&#x26;B/funk/soul you need to check it out.</p>
<h2>Goings on with this personal website</h2>
<p>I inexplicably re-built this site for a second straight year. For those keeping track at home, the
technology arc has been <code>Jekyll on GitHub Pages</code> -> <code>11ty on Netlify</code> -> <code>NextJS on Cloudflare Pages</code>. NextJS was a project I wanted to explore, and I really enjoy how it abstracts away the usual
webpack/babel/typescript config shenanigans for you. Would recommend, so far.</p>
<p>I wrote <a href="/posts/vim-plugins-revisited">a single post</a>, which is actually enough to exceed
my average throughput over the past 5 years (!). Hope to see you again in 2022.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Vim Plugins Revisited – Neovim 0.5 Edition</title>
      <link href="/posts/vim-plugins-revisited" />
      <updated>Mon, 12 Jul 2021 00:00:00 GMT</updated>
      <id>/posts/vim-plugins-revisited</id>
      <content type="html"><![CDATA[<p>Over 6 years ago (!) I wrote a <a href="./vim-plugin-essentials">little post</a> here about the vim plugins I
found most useful. In honor of <a href="https://neovim.io/news/2021/07">the Neovim 0.5 release last week</a>, I thought it would be worth revisiting
my plugins of choice, and reflect on how they've changed over the years.</p>
<p>Neovim 0.5 is really a game changer in a lot of ways, and its impact on my setup has been significant.
Native <a href="https://microsoft.github.io/language-server-protocol/">LSP</a>
support and treesitter integration are two of the exciting headline features, but in my mind, the
biggest game-changer is the first-class support for scripting <em>everything</em> in Lua. Many of the plugins
I've migrated below are fully implemented in Lua, and it's amazing to think that the community is just getting
started in harnessing a "proper", and much faster, built-in scripting language.</p>
<h2>Version control integration</h2>
<p><strong>Then:</strong> gitgutter<br>
<strong>Now:</strong> <a href="https://github.com/lewis6991/gitsigns.nvim">gitsigns</a></p>
<p>Gitgutter served me well for a very long time! However, with gitsigns the VCS feedback appears much,
much faster, and that was reason enough for me to switch. I also prefer its more understated use of
the sign column.</p>
<h2>Diagnostics</h2>
<p><strong>Then:</strong> Syntastic<br>
<strong>Now:</strong> <a href="https://github.com/neovim/nvim-lspconfig">nvim-lspconfig</a></p>
<p>I have to give a shout out to <a href="https://github.com/dense-analysis/ale">ALE</a> and <a href="https://github.com/neoclide/coc.nvim">coc-nvim</a>, two great
projects that I used for long stretches over the last five years. But as far as I'm concerned,
Neovim's built-in LSP integration is absolutely the future in this space.
I'd been cautiously kicking its tires before it was stable in 0.5, and ended up switching earlier
than I'd anticipated thanks to the phenomenal performance increase over coc.nvim.</p>
<h2>Syntax Highlighting</h2>
<p><strong>Then:</strong> vim-polyglot<br>
<strong>Now:</strong> <a href="https://github.com/nvim-treesitter/nvim-treesitter">nvim-treesitter</a></p>
<p>Another performance-related switch here, based on a new feature in Neovim 0.5. I have only
scratched the surface of what the treesitter integration has to offer, but am also excited about
features like <a href="https://github.com/nvim-treesitter/nvim-treesitter-textobjects">language-aware text
objects</a>. Again, the future in
Neovim is really bright now that these tools are in the hands of an active development community.</p>
<h2>Autocomplete</h2>
<p><strong>Then:</strong> ???<br>
<strong>Now:</strong> <a href="https://github.com/hrsh7th/nvim-compe">nvim-compe</a></p>
<p>Hard to believe I used vim for years without decent autocomplete. Sorry, vim curmudgeons, but modern
editors have raised the stakes here, and the built-in <a href="https://vim.fandom.com/wiki/Omni_completion">Omnicomplete</a>
just doesn't measure up anymore. nvim-compe is snappy (thanks in part to Lua) and has a configurable
list of sources (including, most notably, neovim's LSP client). I don't quite
have the snippet support set up to my liking yet, but in every other respect it's been a great
experience so far.</p>
<h2>File finder</h2>
<p><strong>Then:</strong> Ctrlp.vim<br>
<strong>Now:</strong> <a href="https://github.com/junegunn/fzf.vim">fzf.vim</a></p>
<p>Looking at the list of file finders in the original post was quite a trip down memory lane. Again,
I switched to fzf eons ago, and I think the killer feature for me, besides the speed, was having the
same file searching available in the shell. There are fancier new options available like
<a href="https://github.com/nvim-telescope/telescope.nvim">telescope.nvim</a>, but after a cursory exploration
I've decided I'm quite happy with my trusty FZF setup.</p>
<h2>Grep frontend</h2>
<p><strong>Then:</strong> Ags.vim<br>
<strong>Now:</strong> <a href="https://github.com/dyng/ctrlsf.vim">CtrlSF</a></p>
<p>I've been using CtrlSF for ages as well, as a UI for grepping across a project (via the spectacularly
fast <a href="https://github.com/BurntSushi/ripgrep">ripgrep</a>). It's modeled on Sublime Text's
project search, supports editing multiple files via search results, and is fairly customizable.</p>
<h2>Wrap up</h2>
<p>My full <a href="https://github.com/af/dotfiles/blob/master/vim/init.vim">init.vim</a> is up on GitHub,
with a few other miscellaneous plugins and supporting config. Notably, I've started moving some of
my more involved keybindings and supporting functions to lua modules. I'm still far from a Lua
ninja, but compared to vimscript, making these kinds of customizations is significantly easier.</p>
<p>To some readers, spending years customizing a text editor probably seems frivolous, an extravagant
waste of time. Why not just use VS Code? I can understand that perspective, but also derive a deep
satisfaction every time I'm able to sculpt the digital environment where I spend hours each day in
a way that fits my brain better. I'm very much looking forward to further exploring the new sculpting
tools in Neovim 0.5.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Surviving 2020</title>
      <link href="/posts/surviving-2020" />
      <updated>Sun, 24 Jan 2021 00:00:00 GMT</updated>
      <id>/posts/surviving-2020</id>
      <content type="html"><![CDATA[<p>Well, that was... a year. Like most people, for me 2020 was somewhat less than ideal.
But at the end of the day the upheaval and restrictions have made me very thankful to live with
people I love deeply, to have a livelihood that was only briefly interrupted by the pandemic, and to
have a clean bill of health. With those I escaped 2020 more fortunate than most.</p>
<p>I'm not going to spend too much time re-immersing myself in that dumpster-fire-of-a-year, but what
follows is the usual listicle of the books, tech, and miscellaneous stuff that helped me get through
it.</p>
<h2>Reading</h2>
<p>For most of 2020, there wasn't a lot to do but hunker down and read. Fortunately for me, this is how
I spend most of my free time already. Some of the books I most enjoyed:</p>
<ul>
<li>Hillbilly Elegy</li>
<li>Moonwalking with Einstein</li>
<li>Programming with Types</li>
<li>The Road</li>
<li>Programming Rust</li>
<li>The Soul of a New Machine</li>
<li>Bowling Alone</li>
<li>The Information</li>
<li><a href="https://sive.rs/n">Hell Yeah or No</a></li>
<li>How to Live- a Life of Montaigne</li>
<li>The Nurture Assumption</li>
<li>Reinventing Comics</li>
</ul>
<h2>Programming/Technology</h2>
<p>You may have noticed above that like every other programmer and their dog, I spent a little time
with Rust recently. While the language is too low-level for my current needs and
tastes, I was impressed and inspired by its tooling and the deep integration of typed functional
programming idioms in the language. Dipping my toes in was a great learning experience and I expect
that I'll return to it at some point. Maybe lifetimes and the borrow checker will "click" for me
next time.</p>
<p>Most of my other programming endeavors have been in TypeScript for the last 18 months. The language is
still adding interesting features and I still feel like there is more to learn. For UI work,
I'm quite satisfied with TypeScript/React/Apollo.</p>
<h2>Links</h2>
<p>From time to time I add a <code>top</code> tag on Pinboard to items that I particularly like (they show up as
bigger circles on my homepage's beeswarm chart). The ones I tagged in 2020 were:</p>
<ul>
<li><a href="https://wattenberger.com/blog/d3-force">Use the D3 Force</a></li>
<li><a href="https://twobithistory.org/2020/06/28/rest.html">Roy Fielding's Misappropriated REST Dissertation</a></li>
<li><a href="https://josebrowne.com/on-coding-ego-and-attention/">On Coding, Ego and Attention</a></li>
<li><a href="https://martinrue.com/my-engineering-axioms/">My Engineering Axioms</a></li>
</ul>
<h2>Board games</h2>
<p>Have I ever mentioned here that I'm a big ol' board game nerd? Before the current restrictions on
social gatherings were in place, I had a lot of fun gathering with friends and family for the odd
game night. I don't record new games or plays, so some of these are probably from 2019, but below
are some of the "new" games I've most enjoyed recently:</p>
<ul>
<li><a href="https://boardgamegeek.com/boardgame/237182/root">Root</a></li>
<li><a href="https://boardgamegeek.com/boardgame/284083/crew-quest-planet-nine">The Crew</a></li>
<li><a href="https://boardgamegeek.com/boardgame/224517/brass-birmingham">Brass: Birmingham</a></li>
<li><a href="https://boardgamegeek.com/boardgame/217372/quest-el-dorado">The Quest for El Dorado</a></li>
<li><a href="https://boardgamegeek.com/boardgame/98778/hanabi">Hanabi</a></li>
</ul>
<h2>This site</h2>
<p>I moved this site from Jekyll to Eleventy this year, but that was pretty much the extent of the
effort I put into it. I certainly appreciate the dramatic improvement in build speed, but otherwise
it was a mostly lateral move. After playing around with NextJS a few months ago (and being quite
impressed), I'm already considering another migration. These technology changes are pointless,
low-impact projects, but they're also decent ways to kick the tires on new technology and learn a
few things.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Review– reMarkable 2</title>
      <link href="/posts/remarkable-2" />
      <updated>Sun, 20 Dec 2020 00:00:00 GMT</updated>
      <id>/posts/remarkable-2</id>
      <content type="html"><![CDATA[<p>For a programmer, I'm not too big on gadgets. I've never owned wearable or "smart speaker"
devices, and view my phone more as a necessary evil than anything. There is one category of gadgetry that I've eyed
longingly for many years though– large-format EInk reading devices with stylus/touch and reasonable page refresh
rates. This year I finally gave in and purchased a <a href="https://remarkable.com/">reMarkable 2</a>,
hoping it would be a productivity boon and lessen my regrettable dependence on <a href="https://www.theonion.com/report-90-of-waking-hours-spent-staring-at-glowing-re-1819570829">glowing rectangles</a>. This post is a review of
how I'm finding it after about two months of use.</p>
<p>If you look solely at the spec sheet, the reMarkable 2 (aka RM2) is a pretty underwhelming product. Monochromatic screen.
Meagre feature set. Underpowered CPU. No third-party apps, audio, backlight, or Bluetooth. As a distraction-free
reading/writing/organization niche device, some of those are anti-features, but others would
improve the product, depending on what your primary use case is. I would be remiss if I didn't mention
another important downside– the RM2 is freaking expensive! I preordered the RM2, which knocked a few
hundred bucks off the current list price, but if I was considering the purchase today, I would have
a hard time justifying it.</p>
<p>I've been using the RM2 primarily as an notetaking device (its raison d'étre) and e-reader. Anyone
who's worked with me in an office can probably remember messy piles of post-it notes on my desk;
I've always found notetaking and sketching to be extremely helpful as thinking aids, and being able to mix
digital organization with analog-style tactile immediacy with the RM2 has been a big win. The
writing experience on the device is very good, and that's undoubtedly what most people are going to
be purchasing it for.</p>
<p>As an e-reader, the RM2 is more of a mixed bag. The e-ink screen is gentle on the eyes, and the
10.3” screen is a near-perfect size for the technical books (nicely formatted PDFs) that I've been
accumulating over the years. The refresh rate is good enough, though noticeable, and it's great to
have all of the same annotation tools for books that are available for notetaking. The flip side is
that the reading software is inexcusably limited. There's no way to see a list of pages with annotations,
bookmark a page for later (!), or follow pdf links. It's mindboggling
that after several years of developing the reMarkable software, these features are absent, but they
update the software semi-regularly so I hold out hopes that they might get added later.</p>
<p>The hardware design of the reMarkable2 is undoubtedly it's strongest point. Not only is the RM2
svelte and solid, both the tablet and the pen have wonderful physical textures, which make handling and using
the device a really pleasing tactile experience. The magnets that keep the pen and folio connected
to the tablet are strong and give a satisfying "click" as the pieces snap together.</p>
<p>For the technically inclined, the RM2 is also surprisingly open. It runs Linux and you can
ssh in as root to modify files and install (not officially supported) software and
<a href="https://github.com/ddvk/remarkable-hacks">hacks</a>. I have yet to try the "hacks" but it appears to
paper over some of the more frustrating limitations of the stock UI.</p>
<p>Overall, I haven't been this smitten with a piece of hardware since the iPhone 3G (my first smartphone, over
a decade ago). Despite its warts, the reMarkable 2 is now an essential part of my workflow and
I would dearly miss it if something happened to it.</p>
<h2>Misc thoughts</h2>
<ul>
<li>
<p>A lot of reviews directly compare the RM2 to an iPad, but the experience with each device is
markedly different. To me placing them in the same category is almost nonsensical, though they're
both nominally "tablets".</p>
</li>
<li>
<p>My kids really enjoy the RM2 as well. It's been a great motivator to practice their writing, but
it physically pains me to see (and hear!) how much pressure they apply with the stylus (see nib
wear, below)</p>
</li>
<li>
<p>Nib wear was a concern of mine before getting the RM2, as it looked like regularly replacing
the nibs had the potential to add a significant recurring cost. As I was writing this post,
I just replaced my first nib, after 6 weeks with the device. It seems the amount of pressure you apply
when writing is a major factor in how quickly you'll go through nibs, and if not for my kids’
aggressive use, I think the nibs would each likely last over two months.</p>
</li>
<li>
<p>reMarkable also has a Chrome extension that lets you send articles to the device via their cloud
service. It's pretty limited (images don't make the journey to the tablet if you use the default
epub document export), but reading long form content is <em>so much better</em> on the RM2 vs a laptop
that I find myself using it frequently.</p>
</li>
<li>
<p>If you're interested in the reMarkable, you really need to check out the <a href="https://www.youtube.com/playlist?list=PLsSI9-gaSSmiXwb7Vjk5Vb-nB41UTnrXd">reviews from
My Deep Guide</a> on Youtube.
They're probably the most in-depth and unbiased reviews of a product I've ever seen, and will go
a long way to help understand if the RM2 would be a good fit for you.</p>
</li>
</ul>
]]></content>
    </entry>
  

    <entry>
      <title>2019 Review</title>
      <link href="/posts/2019-review" />
      <updated>Wed, 01 Jan 2020 00:00:00 GMT</updated>
      <id>/posts/2019-review</id>
      <content type="html"><![CDATA[<p>Another year, another review post. I'm keeping this one extra simple so I can actually get it out
on time for once.</p>
<h2>Learnings in Technology</h2>
<p>I jumped on the TypeScript hype train in 2019 and have been pretty impressed with it so far. After
spending the better parts of 2 years using Flow, it was increasingly feeling like a dead end. By
comparison, TypeScript has a massive (and growing) community, fantastic developer tooling, and
decent documentation.</p>
<p>After tinking with OCaml/Reason for the last few years, I definitely miss <a href="https://v1.realworldocaml.org/v1/en/html/variants.html">variants</a> (TS enums are a pale substitute) and pattern matching. But TS seems to be the most pragmatic typed frontend language around
right now– 80% of the type safety with 20% of the effort required to get up and running with the more ironclad but obscure
alternatives. It's also infinitely more employable, which is a <em>little bit</em> of a bonus.</p>
<p>Another language I spent a little bit of time with in 2019 is Lua. I'd previously messed with it
a bit for use with Hammerspoon, but this year Neovim got first-class Lua support so I've been
playing with it a lot more. Being able to script Vim without VimScript (ugh) or remote plugins is
a treat!</p>
<h2>Reading</h2>
<p>At the start of the year I set out a list of 12 books that had been lingering on my shelves
(physical or virtual) for years. Because I impulsively check out a lot of books from the library, it
came down to the last week, but I managed to read them all. In decreasing order of my enjoyment, they were:</p>
<ul>
<li>The Enchiridion</li>
<li>Drawing on the Right Side of the Brain</li>
<li>High Performance Browser Networking</li>
<li>Domain Modelling Made Functional</li>
<li>The Elements of Graphing Data</li>
<li>Badass: Making Users Awesome</li>
<li>Getting to Yes</li>
<li>The C Programming Language</li>
<li>The Psychology of Computer Programming</li>
<li>Universal Principles of Design</li>
<li>Domain Driven Design</li>
<li>Clean Code</li>
</ul>
<p>In total I read 59 books, which is pretty solid. Actually, it might be the most I've ever read in a calendar year.
Other standouts read in 2019 included:</p>
<ul>
<li>Atomic Habits</li>
<li>Factfulness</li>
<li>Why We Sleep</li>
<li>Digital Minimalism</li>
<li>The Coddling of the American Mind</li>
<li>The Attention Merchants</li>
<li>Siddhartha</li>
<li>Creative Selection</li>
<li>The Handmaid's Tale</li>
<li>Super Pumped: The Battle for Uber</li>
</ul>
<h2>Music</h2>
<p>As I age, I find it progressively more challenging to find new music that resonates with me. So
I was really excited to find <a href="https://www.youtube.com/playlist?list=PL1B627337ED6F55F0">Tiny Desk Concerts</a> this year.
The videos cover a wide set of genres, and the artists and sound quality are consistently awesome.
My favourite video so far is <a href="https://www.youtube.com/watch?v=_NIFz8wRvMs&#x26;feature=share">the one featuring Joey Alexander</a>,
and I had the good fortune to see him in concert this year. It was the best show I've seen in
years– he melted my face off!</p>
<h2>This site</h2>
<p>This personal site got a fresh coat of paint late in the year, and I <em>almost</em> got a real blog post out,
but not quite. With my flagging enthusiasm for posting here and the visceral cringe I get when
reading my old posts, I periodically wonder if keeping this site up is worthwhile. But independent blogs
are a somewhat imperiled medium, and one that I get a lot of value from. I want to do my part, however
tiny, at contributing to the ecosystem. Here's to renewing it for another year!</p>
]]></content>
    </entry>
  

    <entry>
      <title>2018 Review</title>
      <link href="/posts/2018-review" />
      <updated>Sun, 06 Jan 2019 00:00:00 GMT</updated>
      <id>/posts/2018-review</id>
      <content type="html"><![CDATA[<p>Just like last time around, my "year in review" post is comically late. This time it was so bad
I artificially back-dated this post. My blog, my rules!</p>
<h2>New Year, New City</h2>
<p>I will keep this post brief as at this point I forget most of the details of 2018. However the big theme
was moving cities for the first time in my adult life. After many years in Vancouver, we picked up
and moved to Victoria in August.</p>
<p>The “Why I'm leaving Vancouver” blogpost is a well-worn trope by now, but I will continue to resist
the urge to indulge. I was hesitant about the move myself, but with several months of hindsight it
has been a great change. Victoria is extremely bikeable, there's less rain, and the laid-back vibe
suits my disposition well.</p>
<p>After considered it for many years, the move gave me the opportunity to dive into remote work.
Once I worked out the kinks in my workspace and daily routine (perhaps fodder for a future post), I'm
pleased to say that I've really enjoy it. I was already spoiled with a short walking commute in
Vancouver, but the flexibility of schedule and proximity to family is hard to beat.</p>
<h2>Tech things</h2>
<p>Open source and on-the-side coding took a backseat to “real life” priorities this year. I continued
to monitor the ReasonML ecosystem, hoping its community would take off and I could justify pitching it
seriously at work (hasn't happened yet). Work kept me busy and I was able to focus on helping build
a large frontend app (React/Redux/etc).</p>
<h2>Books</h2>
<p>I still managed to read a fair bit this year (56 books!). Here were my favourites:</p>
<ul>
<li><a href="https://www.amazon.ca/Code-Language-Computer-Hardware-Software/dp/0735611319">Code</a></li>
<li><a href="https://www.amazon.ca/Mans-Search-Meaning-Viktor-Frankl/dp/080701429X">Man's Search For Meaning</a></li>
<li><a href="https://www.amazon.ca/When-Breath-Becomes-Paul-Kalanithi/dp/081298840X">When Breath Becomes Air</a></li>
<li><a href="https://www.amazon.ca/Homo-Deus-Brief-History-Tomorrow/dp/0771038704">Homo Deus</a></li>
<li><a href="https://www.amazon.ca/Dune-Frank-Herbert/dp/0441172717">Dune</a></li>
<li><a href="https://www.amazon.ca/Bandini-Quartet-Spring-Angeles-2004-06-21/dp/B0182POW08">Wait Until Spring, Bandini / The Road to Los Angeles / Dreams From Bunker Hill</a></li>
<li><a href="https://www.amazon.ca/Change-Your-Mind-Consciousness-Transcendence/dp/1594204225">How to Change Your Mind</a></li>
<li><a href="https://www.amazon.ca/Building-Stories-Chris-Ware/dp/0375424334">Building Stories</a></li>
<li><a href="https://refactoringui.com">Refactoring UI</a></li>
</ul>
<h2>A New Habit</h2>
<p>I started doing some light journalling. It's been helpful at times to get thoughts out of my
head and onto the page. Clearly it hasn't translated to increased blog output yet though!</p>
]]></content>
    </entry>
  

    <entry>
      <title>2017 Review</title>
      <link href="/posts/2017-review" />
      <updated>Sun, 01 Apr 2018 00:00:00 GMT</updated>
      <id>/posts/2017-review</id>
      <content type="html"><![CDATA[<p>Are you allowed to do a "year in review" blog post when it's already well into ~~February~~ ~~March~~
April? Despite the temptation to sit on this work in progress until August for maximum comedic
effect, here it is, warts and all.</p>
<h2>Most Exciting New Technology</h2>
<p>It was <a href="http://facebook.github.io/reason">ReasonML</a>, hands down. Last year I kept close tabs on
this fledgling "language" (it's really just a toolset around the venerable OCaml), and was richly
rewarded. The community is incredibly friendly, and there is so much neat stuff to learn by diving into
a typed functional language. I wrote a <a href="https://github.com/af/shmup.re">canvas-based game</a>, started
working on some (very incomplete) <a href="https://github.com/af/bs-d3">d3 bindings</a>, and am kicking around
a few more small projects for fun. I will definitely be spending a lot more time with Reason this year!</p>
<h2>Best Return on Investment</h2>
<p>I previously wrote up <a href="/posts/learnui-design-review/">my review</a> of the UI design course that
I took early in 2017. While I don't do any design day-to-day, I'm really enjoyed continuing to pick
at this hobby, and dipping back into the course videos and homework from time to time. If you are
an analytically inclined person looking to gain some design skills, I still highly endorse it!</p>
<h2>Best Books</h2>
<p>After chewing through 45 books last year, I think might have hit a new personal high score. Looking
through the list, only of few of them were truly exceptional:</p>
<ul>
<li><a href="https://www.amazon.com/Deep-Work-Focused-Success-Distracted/dp/1455586692/">Deep Work</a></li>
<li><a href="https://www.amazon.com/Flour-Water-Salt-Yeast-Fundamentals/dp/160774273X">Flour Water Salt Yeast</a></li>
<li><a href="https://www.amazon.com/War-Art-Through-Creative-Battles/dp/1936891026">The War of Art</a></li>
<li><a href="https://www.amazon.com/Ask-Dust-John-Fante/dp/0060822554">Ask The Dust</a></li>
<li><a href="https://www.amazon.com/Brothers-Karamazov-Fyodor-Dostoevsky/dp/0374528373">The Brothers Karamazov</a></li>
</ul>
<h2>Best New Hobby</h2>
<p>I started taking to baking bread. <em>Flour Water Salt Yeast</em> was inspiring, and breadmaking is
a wonderfully tactile counterpoint to my usual computer-based hobbies. After a half dozen mildly
successful attempts at sourdough, I'm now working on mastering a more basic white bread. The plan is to
work up through pre-ferments and then back to regularly baking sourdough.</p>
<p>Also in the kitchen, I joined the cult of the Instant Pot. I'm only a few months in, but it does
seem like a really useful gadget.</p>
<h2>Best Music</h2>
<p>Still going through a bit of a dry spell as far as discovering new music goes. But while going through
Stevie Wonder's <a href="https://slate.com/cover_story/2016/12/the-greatest-creative-run-in-the-history-of-pop-music.html">classic period</a>,
albums, I finally found <em>Fulfillingness's First Finale</em>, which is now one of my all-time favourite
records.</p>
]]></content>
    </entry>
  

    <entry>
      <title>“Learn UI Design” Video Course– My Review</title>
      <link href="/posts/learnui-design-review" />
      <updated>Wed, 13 Sep 2017 00:00:00 GMT</updated>
      <id>/posts/learnui-design-review</id>
      <content type="html"><![CDATA[<blockquote>
<p>The following is my take of the <a href="http://learnui.design/">Learn UI Design</a> video course. I paid for access to the course when it was in alpha last year. As the course is accepting new students soon, and I haven't seen too many longer-form reviews online, I thought this post might be helpful to anyone who's considering the course, but not sure if it's right for them.</p>
</blockquote>
<h2>My Background</h2>
<p>As a programmer, I've always been drawn to the visual side of my field. I vividly remember making my first game (pong in Python!) and how amazing it was to watch things move crudely around the screen. Later on I worked at a small startup that didn't have a full-time designer, and acutely felt the pain of trying to put together styles and imagery that didn't look awful. As easy as some people make it look, designing user interfaces is a full-time craft, and unraveling its secrets is a challenge for most of us.</p>
<p>Despite chewing through countless articles and books over the years, passable design skills remained elusive for me. While some of these resources were excellent, at best they only gave me familiarity with concepts and terminology. Whenever I tried to actually build something visual, I got the same uninspired (or just plain ugly) results.</p>
<p>I subscribed to Erik Kennedy's email list after reading one of his excellent <a href="https://medium.com/@erikdkennedy">Medium posts</a>, as he communicated design concepts in a way that made things "click" a bit easier for me. So naturally when he announced his <a href="http://learnui.design">online design course</a> I was very interested. I signed up for Learn UI Design about a year ago, near the end of the first batch of students.</p>
<h2>The Course</h2>
<p>Learn UI Design is a hands-on video course, with an accompanying Slack channel for discussion and feedback. I won't rehash the syllabus here– you can a clear overview from <a href="http://learnui.design">the website</a>. The videos are extensive (18+ hours in total), well produced, and easy to follow. Each topic is dealt with thoroughly, and I can't remember finishing a video and feeling like anything had been skipped over. My only (minor) complaint is that I'd love to see a few more subjects added, like animation basics, and maybe some UX topics. Erik is still adding new content over time, so it's possible the scope could widen a bit in the future.</p>
<p>If you like Erik's teaching style from his Medium posts, you'll find it translates well to the videos. Maybe it's the cynical programmer in me, but a lot of design instruction out there comes across as overly artsy or "hand wavey". Erik's style is the opposite– very direct and pragmatic.</p>
<p>The Slack channel is a really helpful component of the course as well. When I signed up I thought it was kind of a "throw in", but being active there is pretty integral to getting the most value out of the course. Besides the general banter and tips, posting homework solutions there for feedback has been really helpful. I'm a perfectionist and I hate putting my work "out there" when I'm not confident in it (every blog post here is a struggle), so this was tough for me at first. But the other students have been really friendly and helpful, and Erik's direct feedback has been invaluable. The level of feedback and mentorship he provides each student is really commendable.</p>
<h2>Key Takeaways</h2>
<p>Remember how I said the course has two main components? There is also a third part that I think is perhaps the most important of all: the homework. Looking back at my previous attempts at learning design, my biggest mistake was not getting enough reps in with the concepts I was reading about. Most videos in the course come with one or more related homework assignments, so you can apply your new knowledge right away. Maybe the idea of homework makes you recoil in horror, but if you're serious about levelling up your skills, you need to do the work to get there.</p>
<p>My personal favourite course section is the one on colour– an area that has historically been my achilles heel. Erik does a great job of explaining why HSB is vastly more useful than RGB for design work, and presents lots of useful tricks and heuristics. Other highlights for me are the videos on grids, imagery, spacing, and alignment.</p>
<p>One "meta" takeaway from the course is the importance of iterating on your work. Erik specifically talks about the importance of iteration early in the videos, and applying this lesson pays dividends as you complete the rest of the coursework. Trying to find multiple solutions to problems and tweaking as you go not only makes your designs better, it's also applicable to many other creative disciplines.</p>
<h2>Conclusion</h2>
<p>Is Learn UI Design the <em>best</em> way possible to learn UI design? I don't know; I haven't tried every course or method, and the answer probably depends on your background and personality. But I can confidently say that nothing I've watched or read has been remotely as helpful for me personally, so I highly recommend it. My recommendation comes with the caveat that you should plan to spend at least 3 hours weekly (ideally 5+) working on the course to get the best results. There's a lot of material and I found it's important to immerse yourself and keep your momentum going.</p>
<p>A year after joining, I still get a lot of value out of the Slack channel, and I have referred back to the videos numerous times (the course gives you lifetime access). There were a few new videos added last week that I still need to catch up on. Anyways, I hope this review has been helpful and gives you a feel for the course. I'm <strong>@af</strong> on the Slack channel and hope to see your work there soon!</p>
]]></content>
    </entry>
  

    <entry>
      <title>envalid v4</title>
      <link href="/posts/envalid-v4" />
      <updated>Mon, 04 Sep 2017 00:00:00 GMT</updated>
      <id>/posts/envalid-v4</id>
      <content type="html"><![CDATA[<p>Last week I tagged version 4.0.0 of envalid, a Node library for environment variable validation
that helps you avoid <a href="http://aaronfranks.com/posts/env-vars/">several environment variable antipatterns</a>.
For those who have been using it (and may be wary of a major version bump) I wanted to do a quick
write-up of the notable additions. The backwards-compatible changes are small, but there is some
great stuff in the latest version!</p>
<p>Calling envalid "my" library is no longer accurate, as the last few months have brought contributions from several others. In particular <a href="https://github.com/simenb">@SimenB</a> contributed most of the new code that culminated in this latest major release 👏.</p>
<h2>What's not new</h2>
<p>I've never really described envalid's features in detail here, but briefly, here are some of the things it handles for you out of the box:</p>
<ul>
<li>Allows you to declaratively describe the environment your app expects to run in</li>
<li>Provides several useful env var validators (number, json, email, etc) so that the plain strings you
get from <code>process.env</code> are converted to a useful format centrally, rather than all across your
app</li>
<li>It's super easy to define custom validators if the built-in ones don't cover all the shapes of your data</li>
<li>Wraps the awesome <code>dotenv</code> package, so you can drop your development/testing default values in
a <code>.env</code> file instead of hardcoding them somewhere.</li>
<li>Handy shorthands <code>env.isDev</code>, <code>env.isProduction</code>, and <code>env.isTest</code> to replace the <code>if (process.env.NODE_ENV === 'production')</code> checks that tend to get strewn about.</li>
</ul>
<h2>New in v4</h2>
<p>Two nice little additions are the use of <code>prettier</code> for code formatting and new <code>host</code> and <code>port</code>
validators. In my experience, hosts and ports are extremely common env vars so it's nice to have
some extra validation baked in for these.</p>
<p>The major (and only breaking) change is to envalid's "strict mode", which gives you some extra guarantees about your validated environment object. In v4, strict mode will throw if you try to set,
or even access, an invalid property on your environment object. If the mistake was a simple typo,
envalid will helpfully suggest a related property that you may have meant.</p>
<p>The following (contrived) example shows how this helps in practice. Note how well it works when
destructuring your env imports– the errors happen at startup time, rather than later on during the
execution of your server route.</p>
<pre><code>// Oops! I forgot a 'T' in there.
// But in v4.x envalid will throw instead of returning `undefined`
const { STRIPE_SECRE_KEY } = require('path/to/my/env/object')

app.get('/customer/info', (req, res) => {
    const stripe = require('stripe')(STRIPE_SECRE_KEY)

    stripe.customers.retrieve(req.user.customerId)
        .then(customer => res.json(customer))
})
</code></pre>
<h2>The future</h2>
<p>It feels like envalid is "mostly done", but I probably would have said the same thing three months ago, before all of the features above landed. It's exciting to see adoption pick up (currently just a shade under 10k monthly downloads) and lots of great community feedback and contributions. Here are a few random ideas I've thought of that might be useful in the future:</p>
<ul>
<li>A custom eslint rule to warn when accessing process.env directly – this would in effect force you to access the cleaned env object that you get from envalid.</li>
<li>Built-in support for designating env vars that are used client-side, and returning a separate
validated object that you can import from your webpack config.</li>
<li>Bindings for <a href="https://reasonml.github.io/">Reason</a></li>
</ul>
<p>If you have any other ideas, please drop by the envalid <a href="https://github.com/af/envalid/issues">issue tracker</a>!</p>
]]></content>
    </entry>
  

    <entry>
      <title>2016 Review</title>
      <link href="/posts/2016-review" />
      <updated>Sat, 07 Jan 2017 00:00:00 GMT</updated>
      <id>/posts/2016-review</id>
      <content type="html"><![CDATA[<p>It's another year-in-review post! I'm not really sure why I keep doing these, but I guess everyone
does so why not?</p>
<h2>Best New Technology Learned</h2>
<p>I wrote a rambling post about how I was <a href="/posts/rethinking-another-best-practice/">cautiously optimistic</a>
about GraphQL shortly after it was released. This year I finally took it for a spin on a project at
work, and so far I've been very impressed. We are using <a href="http://dev.apollodata.com/">Apollo</a> as our
GraphQL client, and it too has been a real treat. I hope to dive into this a bit more in a future
post, but these two technologies have taken a lot of the pain out of writing network APIs
and building isomorphic/universal web apps.</p>
<p>In other news, I spent some time learning the basics of Haskell, which was certainly a mind-bending
experience. Rather than becoming a proficient Haskell programmer, I wanted to become more
conversant about higher-level functional programming concepts. This year I might try dipping into
OCaml or its new variant <a href="http://facebook.github.io/reason">Reason</a> to further my journey.</p>
<h2>Open Source</h2>
<p>I didn't make many open source contributions this year, but two projects of mine did get some
love. <a href="https://github.com/af/envalid">Envalid</a>, my environment variable validation library, got
a complete rewrite to a much saner API. <a href="https://github.com/af/apollo-local-query">apollo-local-query</a>
is a new, tiny library to make server rendering with the aforementioned Apollo a bit easier.</p>
<p>I don't have any specific goals for open source this year, but I do have a <a href="https://github.com/af/slashpile">skunkworks project</a> that I revisit every couple of months. Maybe this year I'll sharpen it into a more "serious" project.</p>
<h2>Best Books</h2>
<p>Of the ~40 books I read this year there were five standouts. I don't generally read new
non-programming books so I was surprised that three of them were actually released in 2016.</p>
<ul>
<li><a href="https://www.amazon.com/Martian-Andy-Weir/dp/0553418025/">The Martian</a></li>
<li><a href="https://www.amazon.com/Disrupted-My-Misadventure-Start-Up-Bubble/dp/0316306088">Disrupted</a></li>
<li><a href="https://www.amazon.com/Food-Lab-Cooking-Through-Science/dp/0393081087">The Food Lab</a></li>
<li><a href="https://www.amazon.com/Inner-Game-Tennis-Classic-Performance/dp/0679778314">The Inner Game of Tennis</a></li>
<li><a href="https://www.amazon.com/Subtle-Art-Not-Giving-Counterintuitive/dp/0062457713">The Subtle Art of Not Giving a Fuck</a></li>
</ul>
<h2>This Blog</h2>
<p>My investment in this blog was basically non-existent in 2016, and I'm ok with that. Till next
time!</p>
]]></content>
    </entry>
  

    <entry>
      <title>Environment Variable Antipatterns</title>
      <link href="/posts/env-vars" />
      <updated>Sun, 06 Nov 2016 00:00:00 GMT</updated>
      <id>/posts/env-vars</id>
      <content type="html"><![CDATA[<p>Environment variables are an important part of today's web applications. According to
Heroku's influential <a href="https://12factor.net/">Twelve Factor</a> philosophy, env vars are the <a href="https://12factor.net/config">preferred
tool</a> for managing configuration that changes across deployments.</p>
<p>Useful as they may be, without discipline env vars can turn into a liability - acting as chunks of
mutable global state sprinkled throughout your program. Here we'll look at three env var usage
antipatterns that are commonly seen in web apps.</p>
<h2>1) Lack of Validation</h2>
<p>Environment variables are a type of input to your program, and as such should be treated with
suspicion and care. While malicious inputs are generally unlikely in this case, if you expect a
number or an email address and that expectation is not met, it's best to throw an error as soon as
possible, ideally at deploy time. This makes the runtime behavior of your app much more predictable
and eliminates some of the guesswork of configuring your app for others.</p>
<h2>2) Multiple Points of Access</h2>
<p>While validating inputs from the environment is an essential first step, as always it's important
to keep things <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>. This means your logic
for accessing and validating an env var should be contained in a single place, and not duplicated
wherever the variable is accessed. Ideally all direct contact with, and validation of, env vars
should happen in a single place in your program. This also makes it easier to see at a glance what
your program's configuration dependencies are.</p>
<h2>3) Mutation</h2>
<p>From the program's perspective, environment variables are a form of global state. Global state is
not inherently bad if it remains static, but once it changes it becomes a rich
breeding ground for bugs and unexpected behavior. By wrapping env var access in a read-only data
structure, you can side-step these pitfalls and increase the predictability of your code.</p>
<h2>A Helpful Approach</h2>
<p>The antipatterns above are applicable to any language or framework. A pattern I've found useful for
sidestepping these issues is to centralize all environment accesses through a single module that
does nothing else. When written in a declarative way, this module also serves as a form of
executable documentation for anyone deploying the app. The rest of your code can import this
module and use it as an immutable map of verified environment attributes.</p>
<p>For nodejs programs, I maintain and use <a href="https://github.com/af/envalid">envalid</a>, which provides an
implementation of this approach, and should effectively mitigate the env vars footguns
described above.</p>
]]></content>
    </entry>
  

    <entry>
      <title>2015 Review</title>
      <link href="/posts/2015-review" />
      <updated>Fri, 15 Jan 2016 00:00:00 GMT</updated>
      <id>/posts/2015-review</id>
      <content type="html"><![CDATA[<p>It’s that time of year again, so here's another self-indulgent reflection on the
last 12 months. I promise to keep it mostly tech-focused this time.</p>
<h2>New Technology for 2015</h2>
<p>I can't think of a year in recent memory where I learned so many new technologies.
It’s no exaggeration that my tools of choice are now completely different
than they were just 3 years ago. Of course the rate of churn in the front-end
world has been a frequent topic of lamentation this year, but generally I welcome
all of the great new ideas and libraries that we have to choose from. Here are my
top picks from 2015:</p>
<h3>Redux</h3>
<p>Finally, a variant of <a href="https://facebook.github.io/flux/">Flux</a> that just <em>feels
right</em>. I love how beautifully simple the APIs are, and there’s a really great
community and ecosystem sprouting up around Redux. Watch the <a href="https://www.youtube.com/watch?v=xsSnOQynTHs">conference
talk</a> on how it came to be, and the
really excellent <a href="https://egghead.io/series/getting-started-with-redux">tutorial videos</a>.</p>
<h3>ESLint</h3>
<p>It seems a lot of people are moving from JSHint to <a href="http://eslint.org">ESLint</a>,
and it’s easy to see why: style checking, pluggable rules, and a really active
ecosystem make it by far the best JavaScript linter going forward.</p>
<h3>Webpack</h3>
<p><a href="https://github.com/webpack/webpack/">Webpack</a> takes a lot of heat (often deserved)
for being a beast to configure, but there really isn’t anything comparable for
transforming and bundling web assets. And once you experience <a href="https://webpack.github.io/docs/hot-module-replacement.html">HMR</a> for JavaScript and CSS, writing a web app any
other way feels painfully archaic.</p>
<h3>Flexbox</h3>
<p>I was definitely playing catch-up on this one, but 2015 was finally the year that
browser support for CSS's Flexbox made its widespread use feasible.
If you write CSS and haven’t jumped in yet, check out <a href="https://philipwalton.github.io/solved-by-flexbox/">how much easier</a> it’ll make your life.</p>
<h3>Neovim</h3>
<p>I moved from Vim to <a href="https://github.com/neovim/neovim">Neovim</a> this year as my main
editor, and it has been remarkably stable for such an ambitious young project.
If you use Vim and aren‘t on an Amiga, I definitely recommend switching, if only
for the async command support (check out <a href="https://github.com/benekastah/neomake">Neomake</a>).</p>
<h3>React-Native</h3>
<p>Since November, I have been spending a lot of time with <a href="https://facebook.github.io/react-native/">react-native</a>. While it is still raw in a lot of ways (particularly the docs),
it is already an incredibly powerful platform for building mobile apps. I am constantly
stunned by</p>
<h2>Books</h2>
<p>Looking back on the 39 books I read, there were surprisingly few technical ones
last year. Of the half dozen tech books, <a href="http://shop.oreilly.com/product/0636920031123.do">CSS Secrets</a> was <em>by far</em> the best. If you have some experience with CSS, I very
highly recommend it. There were a few non-technical standouts as well:</p>
<ul>
<li><em>The Idiot</em> (Dostoevsky) - Not nearly as good as <em>Crime &#x26; Punishment</em>, but still worthwhile</li>
<li><em>Zero to Five</em> - The best parenting book I’ve read so far</li>
<li><em>The Sandman</em> (the full graphic novel series) - A really impressive piece of work</li>
<li><em>Zen to Done</em> - Another take on <em>Getting Things Done</em>. Still trying to put some
of its ideas into practice.</li>
</ul>
<h2>This Blog</h2>
<p>One of my goals for the year was to write a few more things on this blog. While
I missed the goal of one entry per month, I eked out <a href="/posts">8</a>, still far above
my usual rate. Though I'm not particularly proud of anything I wrote, I am glad
that I managed to force some pieces out, just to get the practice. There are no
blog-related goals for 2016, so we’ll see what happens.</p>
]]></content>
    </entry>
  

    <entry>
      <title>BYOB</title>
      <link href="/posts/byob" />
      <updated>Sun, 27 Dec 2015 00:00:00 GMT</updated>
      <id>/posts/byob</id>
      <content type="html"><![CDATA[<p>Christopher Chedeau posted <a href="http://blog.vjeux.com/2015/javascript/challenge-best-javascript-setup-for-quick-prototyping.html">an interesting challenge</a> yesterday. A few
<a href="https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4">insightul</a>
<a href="https://medium.com/@Connorelsea/the-react-curve-3d3b16a54290">follow-ups</a> have
since made the rounds. The crux of the discussion is that for all of the
increasing sophistication and modularity of web app tooling
these days, it's become increasingly cumbersome to get started with a simple
prototyping project.</p>
<p>I've personally felt this pain on more than one occasion. Excited to try out a new
idea, I bring up my text editor only to realize that I can't remember how to configure
webpack. Or Babel 6 changed a bunch of things that I haven't learned yet, but a library
I want to use depends on it. And on and on. These tooling-related roadblocks can
quickly kill the enthusiasm for an idea.</p>
<p>The <a href="https://twitter.com/floydophone/status/680226147213426688">discussion</a> around
this issue started by considering the experience of beginners, but soon many
more experienced developers voiced their frustrations with the current state
of webapp tooling. Clearly, both groups of developers are struggling with this,
but their needs are dramatically different.</p>
<h2>Beginners</h2>
<p>For those new to web development, we really need to keep the number of suggested
tools and technologies to a minimum. That means no Babel, no JSX, no Webpack, no
Flux/Redux. Before you use these tools you need to understand them. And before
you can understand them, you have to experience the pain points they exist to solve.</p>
<p>A single html file with inline CSS and JS is a great starting point for a beginner.
They can save it locally, instantly use any text editor or environment that they
are comfortable with, and easily publish with something like <a href="https://surge.sh/">Surge</a>.</p>
<p>Of course, using a single html file goes against several web development best
practices, but that is <em>completely irrelevant</em> for a beginner. The emphasis should
be on facilitating learning, not conforming to every best practice out of the gate.</p>
<h2>Advanced</h2>
<p>For more seasoned developers, part of the problem is the tooling we use
(webpack, babel, etc), once experienced, provide ergonomics that are hard to do without.
I never want to start a project without hot reloading again. It's also increasingly
annoying to eschew ES6 features or write CSS without a preprocessor. If you use
JSX, there's another thing that imposes a build step on your project. These luxuries
trap us in increasingly intricate tooling setups, yet for all but the most trivial
prototypes, I think they provide a net benefit over the lifetime of a project.</p>
<p>It seems people often suggest boilerplates as a solution to the problem. If
someone has already gone to the trouble of setting up all these components together,
why not just pull that in and build on top? Indeed, boilerplates seem to be growing
in popularity and (even more so) in number. However, once you need to deviate from
the boilerplate's built-in conventions, you need to descend into its constituent
tools, sometimes learning them from scratch.</p>
<p>If you're a web developer by trade, I think a <em>build-your-own-boilerplate</em> approach
makes the most sense. Instead of cargo-culting someone else's boilerplate project,
take the time to learn your tools thoroughly, set up a boilerplate that you can
quickly clone and extend, and use that for your projects.</p>
<p>With one command your boilerplate should ideally:</p>
<ul>
<li>Create a git/hg/whatever repository with an initial commit</li>
<li>Create a Readme with your project name</li>
<li>Setup a <code>package.json</code> (or the equivalent for your ecosystem of choice)</li>
<li>Install all of your dependencies</li>
<li>Start a development server, if applicable</li>
<li>Open the browser so you can see some <code>Hello world</code> output right away</li>
</ul>
<p>In theory, setting this up should be a one-time cost, paying interest every time you start
a new project. In practice, however, our tools change rapidly and there will always
be temptations to add new libraries and upgrade to the latest and greatest. Resist!
You should really only need to update your boilerplate a few times a year.</p>
]]></content>
    </entry>
  

    <entry>
      <title>The Om Inflection Point</title>
      <link href="/posts/inflection" />
      <updated>Thu, 17 Dec 2015 00:00:00 GMT</updated>
      <id>/posts/inflection</id>
      <content type="html"><![CDATA[<p>I saw <a href="https://twitter.com/swannodette/status/677528129418719232">on the twitters</a>
today that the <a href="https://swannodette.github.io/2013/12/17/the-future-of-javascript-mvcs/">classic blog post</a> where David Nolen introduced <a href="https://github.com/omcljs/om">Om</a> is
two years old today. Even though I’ve never written a single
line of Om or ClojureScript, this post (and Om itself) was extremely enlightening
for me. Furthermore I think it’s had a profound effect on the JavaScript ecosystem at large.</p>
<h2>React</h2>
<p>It’s hard to imagine now, but the frontend community’s initial response to
<a href="https://facebook.github.io/react/">React</a> was pretty lukewarm (at least from
where I was sitting). David’s post made a lot of people sit up and take notice.
I don’t think it’s coincidence that <a href="https://www.google.ca/trends/explore#q=reactjs">interest in React</a> began to really take off shortly thereafter. React’s benefits are pretty
well documented by now, but its widespread adoption was never a given.</p>
<h2>Immutable Data</h2>
<p>While certainly not a new idea, immutable data structures only seemed to "catch
on" in the front-end world since Om’s release. Now popular libraries like
<a href="https://facebook.github.io/immutable-js/">Immutable.js</a>
give them a more familiar JavaScript API, and they’re even <a href="https://github.com/sebmarkbage/ecmascript-immutable-data-structures">being
proposed</a>
for inclusion in a future version of EcmaScript.</p>
<h2>Single State Atom</h2>
<p>Another technique popularized by Om is placing all application state in a single
object. Easy undo/redo and backup/restore are its most commonly cited benefits,
but I'm curious to see what else it makes possible as more people explore this idea.
<a href="https://github.com/omniscientjs/omniscient">Omniscient</a> and
<a href="https://github.com/rackt/redux">Redux</a> (among others) have brought it to
JavaScript, and the latter is currently seeing an explosion in popularity.</p>
<h2>Diversity in Frontend Architecture</h2>
<p>In late 2013 it seemed like most people were pretty happy writing MVC*-ish* apps
in JavaScript. The Om blog post was one of the first pieces I saw that not only
gave a cogent argument against it, but also presented a reasonable alternative.
A few months later, Flux was released. The breaking of the MVC monoculture has
allowed a lot of diverse ideas to flourish, which has been both fascinating and
illuminating. Let’s hope it continues for a while yet.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Let’s Spoon</title>
      <link href="/posts/lets-spoon" />
      <updated>Sat, 12 Dec 2015 00:00:00 GMT</updated>
      <id>/posts/lets-spoon</id>
      <content type="html"><![CDATA[<p>Programmers talk a lot about automation. Once you get infected by the desire to
automate, everything you’ll need to do more than twice in your life must be scripted.
Because hey, you’d probably rather be wasting all that time on a social news
site or something.</p>
<p>There’s one area of our work that we often don’t think to automate, but which
can yield immense time savings: the way we interact with the GUI on our desktops.
Even if you spend the majority of your time in one terminal window, I’m willing to bet
you frequently switch over to your web browser and/or music app.</p>
<p>If you’re on a Mac, this is where <a href="http://www.hammerspoon.org/">Hammerspoon</a> comes in.
This <a href="https://groups.google.com/forum/#!topic/mjolnir-io/4X9f8A2UdHQ">strangely named</a>
app gives you a Lua API for a boatload of common desktop and application operations.
Here’s a quick list of what I use it for:</p>
<h3>Launching and switching apps</h3>
<p><em>Global hotkeys for most commonly used applications, to avoid the <code>Cmd-Tab</code>,
<code>Cmd-Tab</code>, <code>Cmd-Tab</code>, <code>Cmd-Tab</code> dance to get to a certain app. Getting
to iTerm is always <code>Ctrl-2</code>, regardless of when it was last in focus.</em></p>
<h3>Moving and re-sizing windows</h3>
<p><em>Basically, this is a simple substitute for a window manager. With one global
keystroke, you can resize a window however you like, send it to a different screen,
or snap it to a grid that you have predefined.</em></p>
<h3>System audio control</h3>
<p><em>Volume/muting, in a way that is more customizable than the default OS controls.</em></p>
<h3>Transport controls for iTunes</h3>
<p><em>Having global hotkeys for music is a godsend. No app (or mental context) switching
is necessary when you're deeply concentrating on something else.</em></p>
<p>Hammerspoon’s <a href="http://www.hammerspoon.org/docs/index.html">API docs</a> have a full list of
everything that’s available. Even after using it for several months, there’s a
lot there that I wasn’t aware of­ new features are being added constantly. My
dotfiles are a pretty simple <a href="https://github.com/af/dotfiles/blob/master/hammerspoon/init.lua%3CPaste%3E">starting point</a> if you’re not sure how to jump in.</p>
<p>I highly recommend checking out Hammerspoon. It’s a robust and extremely powerful
automation tool for areas that you didn’t know you wanted to automate. Using it
has also been a great introduction to Lua, which seems like a nice little language.
If you come across novel applications for Hammerspoon, please let me know. I’m
always looking to expand the ways I use it.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Does "Vote Splitting" Have a Large Impact on Canadian Elections?</title>
      <link href="/posts/votesplit" />
      <updated>Thu, 24 Sep 2015 00:00:00 GMT</updated>
      <id>/posts/votesplit</id>
      <content type="html"><![CDATA[<p><em>TL;DR: I made <a href="http://aaronfranks.com/votesplit2011">this visualization</a> about
vote splitting in the 2011 Canadian election.</em></p>
<p>If you're a Canadian and haven't been hiding under a rock, you're probably aware
there's an election coming up. When we're not hearing about
candidates <a href="http://www.cbc.ca/news/trending/canada-election-2015-peegate-jerry-bance-1.3218157">peeing in mugs</a> or <a href="http://www.cbc.ca/news/canada/british-columbia/holy-tweets-b-c-mp-compares-conservative-party-to-jesus-1.3152178">how Bill C-51 reflects the teachings of Jesus</a>,
we're knee-deep in speculation over who's going to be in power later this fall.</p>
<p>Unless you support the Conservative party <em>(full disclosure: I do not)</em>, there's
a good chance you've lamented the "vote splitting" of the left, and the
<a href="https://en.wikipedia.org/wiki/First-past-the-post_voting#Criticisms">tactical/strategic</a>
voting that seems necessary to prevent Conservative (CPC) rule.</p>
<p>The spectre of vote splitting is invoked countless times in the run-up to each
election, but we rarely get a chance to see how it actually impacts the results.
Meanwhile, the poll numbers we see in the press are almost always the
nation-wide popular vote, which <a href="http://thetyee.ca/Mediacheck/2015/09/16/Stop-Sharing-Nationwide-Election-Polls/">give no
insight</a>
into what's happening at the riding level.
Since our <a href="https://en.wikipedia.org/wiki/First-past-the-post_voting">first-past-the-post</a>
voting system means our elections are really
hundreds of separate contests, it's complicated and counterintuitive to see how
changes in popular vote translate to movement in seats.</p>
<p>I took an interest in this topic and built a <a href="http://aaronfranks.com/votesplit2011">data
visualization</a> that allows you to modify the
popular vote in the 2011 election and see how it would have affected the results.
You can also zoom in and click on ridings to see how each of them would have
played out with your changes, or look at the <a href="http://aaronfranks.com/votesplit2011/#split=NDP,LPC,GPC-100-Strategic">absolute best
case of strategic voting</a>
in 2011.</p>
<p>Some pointers on using the visualization:</p>
<ul>
<li>The purple dropdowns let you move a chunk of the national popular vote from
one party to another. Each riding, and the national seat totals, will be
recalculated for each change you make.</li>
<li>For every redistribution of votes, it's assumed that the same percentage of votes
will be transferred in every riding. This is clearly pretty simplistic, but it
would be very complicated to configure and read the results otherwise.</li>
<li>There's an extra option in the last dropdown called "Strategic". What this does
is distribute votes to whichever party that had the best chance to defeat the Conservatives
<em>in each indidual riding</em>. It assumes each strategic voter would know which non-CPC
candidate had the best shot heading into the election.</li>
<li>You can zoom in, pan around, and select specific ridings to see their vote totals</li>
<li>Each riding is colour-coded with the winner, and the strength of the colouring
indicates which percentage of the vote the winner had. Translation: the lighter
ridings are more hotly contested.</li>
<li>"Battleground" ridings show up with a hatched pattern. These are ridings where the
difference between the Conservatives and the top progressive party was less than
5% of the riding's total votes.</li>
<li>Things will kinda/sorta work on mobile/tablet, but a desktop browser is recommended
if you have one.</li>
</ul>
<h2>Warnings and Caveats</h2>
<p>Before drawing any conclusions, it's important to stress
that its data is limited to the 2011 election. This year's election has 30 new
ridings to consider, many existing boundary lines redrawn, and
<a href="http://www.cbc.ca/news2/interactives/poll-tracker/2015/index.html">polls</a> that
look very different than they did four years ago. In summary, you
really can't extrapolate too confidently from the 2011 results to today. However,
many of the trends and party strongholds remain the same in 2015, and gaining
a better understanding of past results is still useful in revealing the dynamics
of our democracy.</p>
<h2>The Greens</h2>
<p>The Green party is the party most frequently
<a href="https://en.wikipedia.org/wiki/First-past-the-post_voting">accused</a> of siphoning
off votes that could be used to defeat the Conservatives. With the visualization
we can see that even if all 2011 Green voters voted <a href="http://aaronfranks.com/votesplit2011/#split=GPC-100-NDP">for the second-place
NDP</a>, or <a href="http://aaronfranks.com/votesplit2011/#split=GPC-100-Strategic">voted perfectly
strategically</a>, we
would have still ended up with a Conservative government, and still a majority in
the first case. This lends some credence to Elizabeth May's <a href="http://thetyee.ca/Opinion/2015/06/27/May-Green-Party-Does-Not-Split-Vote/">rebuttal</a> that the Greens did not split the vote
appreciably. But could it be different this year with the top three parties closer
in the polls?</p>
<h2>The Liberals and NDP</h2>
<p>If you played around with some of the Green vote scenarios above, you may have noticed
that transfering their votes <a href="http://aaronfranks.com/votesplit2011/#split=GPC-100-LPC">to the
Liberals instead</a> would
have cost the CPC an extra five seats. This highlights a pattern: even though
the NDP finished second in seats in 2011, the Liberals were actually in more
close contests with the Conservatives and may stand to steal more seats from them.
This may partially explain why most of the CPC's attack ads to date have focused
on Trudeau and not Mulcair, despite the NDP's strength in the polls for much of
the campaign.</p>
<p>There were actually only a handful of ridings where the Conservatives and NDP
were in close competition with each other in 2011. That's why if you are looking to vote
strategically, choosing the top non-CPC party in the popular vote numbers may
be counterproductive; you're much better off looking at
<a href="http://www.threehundredeight.com/p/canada.html">riding-by-riding polls</a> and
supporting whoever has the best chance of knocking off the Conservatives in your district.</p>
<h2>The Conservatives</h2>
<p>One thing that's clear from running through different scenarios is that if the
Conservatives <a href="http://aaronfranks.com/votesplit2011/#split=CPC-10-LPC">lost support to the
Liberals</a> as current polls
indicate may be happening, they'd be in trouble in many swing ridings across the country.</p>
<p>At the same time, their strongholds in the prairies appear to be very safe­ in some
ridings they collected upwards of 80% of the vote in 2011. There has been speculation that
the NDP's victory in the Alberta provincial election may presage a shift in the federal
election, but it seems unlikely and the <a href="http://www.threehundredeight.com/p/canada.html">current polls</a> don't support that theory either.</p>
<h2>Takeaways for Progressive Voters</h2>
<p>From trying out various scenarios, it seems there are three major classes of ridings
for the would-be strategic voter to consider:</p>
<ul>
<li>A: The Conservative stronghold (see all of the dark-blue in Alberta). Polls indicate
there's a good chance many of these ridings will go CPC once again.</li>
<li>B: The safe progressive riding. 2+ progressive parties are projected to have a
higher vote count than the Conservatives, so vote-splitting is less of a factor.</li>
<li>C: The battlegrounds. The Conservatives and one or more progressive parties have
a tight race. This is where strategic voting could really make a difference.</li>
</ul>
<p>If you were to go back in time to re-cast your ballot in 2011, it seems clear that
the majority of ridings are of type A or B. If you lived in one of them, you wouldn't
need to worry about vote splitting at all,
and should vote for the party that best aligns with your values. However, in the
ridings that are <a href="http://www.votetogether.ca/riding/list/">shaping up to be battlegrounds</a>, you may want to vote
strategically, with the help of <a href="http://www.votetogether.ca/">VoteTogether</a> and
the <a href="http://www.threehundredeight.com/p/canada.html">current polls in your riding</a>.</p>
<p>A few more things that deserve attention for October 2015:</p>
<ul>
<li>All major parties beside the CPC have
<a href="https://www.thestar.com/news/canada/2015/06/16/trudeau-would-end-first-past-the-post-electoral-system.html">pledged</a> to end first-past-the-post if
elected. So hopefully this is the last election where we even have to think
about splitting and strategic voting!</li>
<li>Improving 2011's poor voter turnout numbers (61%) could also have a dramatic effect
on the results, particularly if <a href="https://en.wikipedia.org/wiki/Young_voter_turnout_in_Canada">more young people
voted</a></li>
<li>Once again, if you want to vote strategically against the Conservatives, <em>know your riding</em>
and don't let the popular vote influence your decision.</li>
</ul>
<p>On a final note, the <a href="https://github.com/af/votesplit2011">source code</a> for the
visualization is available. Please file an issue on Github if you have any suggestions
for improvement.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Rethinking Another Best Practice</title>
      <link href="/posts/rethinking-another-best-practice" />
      <updated>Thu, 30 Jul 2015 00:00:00 GMT</updated>
      <id>/posts/rethinking-another-best-practice</id>
      <content type="html"><![CDATA[<p>Just over two years ago, Facebook released React. At the time, I joined an
apparent majority of commenters in declaring that it looked weird and clunky.
Inline XML, onclick handlers, markup and logic together... yuck! To say React
has taken off and captured developer mindshare since then is a huge understatement.
Today it feels like every second company is migrating their existing MVC codebase
to React and/or <a href="https://facebook.github.io/flux/">Flux</a>.</p>
<p>Web developers are a fickle bunch, and the massive churn in the world of web
frameworks is well documented. So what's far more interesting than React's popularity
is the way it's changed how we think about front-end web applications. React's key
features are great encapsulation through components, and declarative UI, rather than
directly manipulating global state (ie. the DOM). React's virtual DOM is generally
considered to be its key feature, but in reality it's an implementation detail
that powers these two breakthroughs.</p>
<p>A few weeks ago, Facebook released the initial <a href="https://github.com/facebook/graphql">spec</a>
and <a href="https://github.com/graphql/graphql-js">reference implementation</a>
for GraphQL, a new way to do data transfer between servers and app/web clients. Just as
React and Flux challenged our assumptions that MVC was the preferred (only?) way
to write clean frontend applications, GraphQL now puts REST in the crosshairs.</p>
<p>REST has turned into a bit of a sacred cow among web developers.
It's generally considered "the right way" to do data exchange between servers and
web UIs, and what we've lost with this uncritical attitude is a more nuanced understanding
of REST's tradeoffs for the systems we're building. Furthermore, most of us are
pretty low on the <a href="http://martinfowler.com/articles/richardsonMaturityModel.html">Richardson Maturity
Model</a>,
so you can argue that often we're not even doing REST correctly. How many REST
APIs have you written that actually use hypermedia to link and expose affordances
between your resources?</p>
<p>I highly recommend reading <a href="https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html">Facebook's GraphQL
introduction</a>,
as it does a fantastic job of enumerating the problems with REST for the increasingly
complex and performance-sensitive systems we're building today. It also lists
issues with the "Ad Hoc Endpoints" that many of us build and erroneously call
"REST APIs".</p>
<p>One of the promising things about GraphQL is that it's not tied to HTTP at all–
this is great for two reasons. First, it means you should also be able to use it
with other transports like Websockets or TCP. Secondly, HTTP has always been
pretty awkward for representing application semantics. If you've ever agonized
over the <em>correct</em> response code for an error condition in a REST API,
you've experienced this first-hand. It shouldn't be surprising that a protocol
designed for document delivery is not an ideal fit for the wide variety of things
we do with APIs and web applications today.</p>
<p>GraphQL is still extremely young as a public project, so it's hard to tell if
it will live up to its promise. Like any technology, it will have its pain
points, but at the moment only people inside of Facebook are intimately aware
of them. It's also clearly still at the "technical preview" stage, and some critical
things like mutations (ie. writes to your data) are still not fully fleshed out
in the documentation. Things should really ramp up when Facebook releases
<a href="https://gist.github.com/wincent/598fa75e22bdfa44cf47">Relay</a>, a client-side JavaScript
framework they've been teasing that's designed to integrate tightly with GraphQL.
It's projected to drop some time in the next month and I'm really looking forward
to digging in, so we can get a wider look into GraphQL's potential.</p>
<h3>More links</h3>
<ul>
<li><a href="https://medium.com/@clayallsopp/your-first-graphql-server-3c766ab4f0a2">GraphQL Tuturial with the reference
implementation</a></li>
<li><a href="https://facebook.github.io/react/blog/2015/02/20/introducing-relay-and-graphql.html">Relay Introduction</a>,</li>
<li><a href="https://facebook.github.io/react/blog/2015/03/19/building-the-facebook-news-feed-with-relay.html">Building the Facebook News Feed with Relay</a></li>
<li><a href="https://speakerdeck.com/laneyk/mutations-in-relay">Mutations in Relay</a></li>
</ul>
]]></content>
    </entry>
  

    <entry>
      <title>You Don't Need Trailing Semicolons</title>
      <link href="/posts/you-dont-need-semicolons" />
      <updated>Tue, 12 May 2015 00:00:00 GMT</updated>
      <id>/posts/you-dont-need-semicolons</id>
      <content type="html"><![CDATA[<p>I was discussing semicolons with a coworker recently, when I (rather inelegantly) made
a case for omitting semicolons from a new JavaScript project. I'm rephrasing it here
because I don't often see this perspective in the endless public debate
about semicolons in JS.</p>
<p>The JavaScript community has a history of piling on those who advocate
semicolon-free code (although the tide does seem to be turning of late).
For a long time, I was in the pro-; camp. While semicolon-free code has always
looked easier to read and “cleaner” to my eyes, why would you seemingly invite bugs into your
software for such a small aesthetic benefit? Also, Douglas Crockford forbade them
(his views are apparently still a primary factor in the style choices of many
JavaScript developers).</p>
<p>Before getting into the crux of my argument, I must concede that if you write your
JavaScript without trailing semicolons, you need to make a habit of adding them to
the start of the line in
<a href="https://gist.github.com/ryanflorence/61935031ff729f072d9b">two specific cases</a>
– when you begin your line with a <code>[</code> or a <code>(</code>. Otherwise in some cases JavaScript
will interpret those characters as the start of array indexing or function invocation,
respectively.</p>
<p>Anyways, I was experimenting with semicolon-free JS on a side project a few
months ago when I tripped up and forgot the two edge cases above. What I saw
caused me to swear off trailing semicolons for all future projects. It looked
something like this:</p>
<p><img src="/img/posts/semicolon_enlightenment.png" alt="Semicolon enlightenment"></p>
<p>The screenshot above shows <a href="http://jshint.com/docs/">JSHint</a> catching the two
aforementioned cases where omitting trailing semicolons could cause a bug in
JavaScript. The beauty in this example is that this feedback happened
instantly in my editor (via <a href="https://github.com/scrooloose/syntastic">syntastic</a>
in Neovim).</p>
<p>If you don't have a linter making these (and other) automated checks for you
before you check in, a) you're missing out, and b)
please refrain from lecturing others on programming style and code quality.
If you do have linting checks in place, you can skip trailing semicolons.
It's up to you, but with today's tooling support for JavaScript, code "quality"
and robustness should not factor into your decision.</p>
<p><a href="http://inimino.org/~inimino/blog/javascript_semicolons">Further</a> /
<a href="http://mislav.uniqpath.com/2010/05/semicolons/">reading</a> /
<a href="http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding">on</a> /
<a href="https://medium.com/@goatslacker/no-you-dont-need-semicolons-148d936b9cf2">semicolons.</a>
Also, for a good time, read <a href="https://github.com/twbs/bootstrap/issues/3057">this entire thread</a></p>
<p><em>Postscript:</em> There are a few more contrived cases where ASI can bite you, but in my
experience they're not worth worrying about:</p>
<pre><code>function thisIsTerrible() {
    return              // ASI would strike here; returns `undefined`
    {
        foo: 'bar'
    }
}
</code></pre>
<p>Seriously, who writes code like this? Oh yeah, and JSHint will catch this too.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Vim Plugin Essentials</title>
      <link href="/posts/vim-plugin-essentials" />
      <updated>Sun, 22 Mar 2015 00:00:00 GMT</updated>
      <id>/posts/vim-plugin-essentials</id>
      <content type="html"><![CDATA[<p>In my 7+ years of using Vim, I've tried a lot of different plugins in attempts
to improve my workflow. This post is a look into what I've found to be
the <em>crème de la crème</em> in the Vim plugin world. If you're lazy, or just
allergic to bad writing, you can <a href="https://github.com/af/dotfiles/tree/master/vim/vimrc">skip to my
vimrc</a> to see how it all
comes together.</p>
<p>It would be irresponsible to discuss Vim plugins without first imploring
the reader to spend a lot of time with plain Vim first. You will get far more
out of plugins once you have a firm grasp on Vim's fundamental actions, motions,
and overall editing philosophy. <em>By far</em> the best resource I've found so far is
<a href="https://pragprog.com/book/dnvim/practical-vim">Practical Vim</a>, by Drew Neil. It
is well worth your money and time if you're serious about Vim. His
<a href="http://vimcasts.org">Vimcasts</a> video series is also excellent.</p>
<h2>Installing Plugins</h2>
<p>Before you start messing around with plugins, it is imperative that you choose
and install a Vim plugin manager. Dealing with installing, upgrading, and deleting
Vim plugins by hand will leave you in a world of pain. It's one of the things
about Vim that is really terrible out of the box. Fortunately, there are quite
a few good plugin managers out there, and I use and strongly recommend
<strong><a href="https://github.com/Shougo/neobundle.vim">NeoBundle</a></strong>. Its
killer feature is the ability to pin each of your plugin dependencies to a
specific Git commit– as far as I know, none of the alternatives do this. Pinning
to a commit keeps your plugin installs repeatable, and also gives you more
flexibility since you aren't limited to in pinning only to tagged versions.</p>
<p>See also: <a href="https://github.com/tpope/vim-pathogen">pathogen</a>,
<a href="https://github.com/gmarik/Vundle.vim">vundle</a>,
<a href="https://github.com/junegunn/vim-plug">vim-plug</a></p>
<h2>Navigating between files</h2>
<p>After using vanilla Vim for a while, navigating between and launching files can
still be a pain point. Probably the most popular plugin for addressing this is
the mighty <strong><a href="https://github.com/kien/ctrlp.vim">ctrlp.vim</a></strong>. It does the
project-wide fuzzy file matching you may have come to expect from Textmate or
Sublime, as well as fast MRU and buffer switching. I use all 3 modes dozens of
times daily, and ctrlp is probably my most indispensible plugin. If there's a
downside, it's that ctrlp hasn't seen an update in almost two years, but there
is an <a href="https://github.com/ctrlpvim/ctrlp.vim">actively developed fork</a> that might
be worth checking out.</p>
<p>Another common use case is searching file contents within your project. I've just
started using <strong><a href="https://github.com/gabesoft/vim-ags">Ags.vim</a></strong> for this, which
uses the excellent <a href="https://github.com/ggreer/the_silver_searcher">silver
searcher</a> tool under the covers.
It's really fast and makes navigating the results easy. I've used a few other
plugins for this, but Ags seems to hit the sweet spot for me.</p>
<p>See also: <a href="https://github.com/mileszs/ack.vim">Ack.vim</a>, <a href="https://github.com/wincent/Command-T">Command-T</a>, <a href="http://www.vim.org/scripts/script.php?script_id=1984">FuzzyFinder</a>, <a href="https://github.com/Shougo/unite.vim">Unite.vim</a></p>
<h2>Syntax/Error Highlighting</h2>
<p>Comprehensive, up-to-date syntax highlighting is a must
for any programmer. <strong><a href="https://github.com/sheerun/vim-polyglot">vim-polyglot</a></strong>
gives you great syntax highlighting for a ton of different languages, while
minimizing the increased startup time from having them all installed.</p>
<p>Also, getting quick feedback on errors as you type saves a ton of debugging time,
especially if you're writing in a dynamic programming language.
<strong><a href="https://github.com/scrooloose/syntastic">Syntastic</a></strong> runs linters and other
checkers as you save your code for quick feedback. It does cause some lag with
slower linters (looking at you, JSHint), but that's a limitation of Vim's purely
synchronous APIs, and despite this it's still more than worth your time.</p>
<h2>Version Control Integration</h2>
<p><strong><a href="https://github.com/tpope/vim-fugitive">Fugitive</a></strong> is the ultimate plugin for
git integration. I've had it installed for years and have still barely scratched
the surface of all the things it does. For a taste, install it and enter <code>:Gblame</code>
or <code>:Gdiff</code> while editing a file with changes. <code>:Gmove</code> and <code>:Gremove</code> are very
handy as well, but I haven't yet absorbed any of the other commands into my
workflow yet.</p>
<p>Another nice tool is <strong><a href="https://github.com/airblade/vim-gitgutter">gitgutter</a></strong>,
which shows which lines of the current file have been added/removed/modified in
the "gutter" to the left of Vim's line numbers. It seems like a small utility,
but I could honestly not go back to editing without this information available
at a glance. It also enables the following key mappings in my vimrc, which allow
me to jump to the closest modified "hunk" in the current file, without needing
to know anything about where that is. Super handy!</p>
<pre><code>map &#x3C;C-j> :GitGutterNextHunk&#x3C;CR>
map &#x3C;C-k> :GitGutterPrevHunk&#x3C;CR>
</code></pre>
<h2>Miscellaneous</h2>
<p>Some other plugins I use and recommend (but am too lazy to write about further)
include:</p>
<ul>
<li><strong><a href="https://github.com/SirVer/ultisnips">Ultisnips</a></strong>, a powerful snippets system</li>
<li><strong><a href="https://github.com/tristen/vim-sparkup">Sparkup</a></strong>, a concise way to author html</li>
<li><strong><a href="https://github.com/vim-scripts/YankRing.vim">YankRing</a></strong>, for recalling copy/paste history</li>
<li><strong><a href="https://github.com/bling/vim-airline">airline</a></strong>, a stylish, clean, and efficient statusbar</li>
<li><strong><a href="https://github.com/jeetsukumaran/vim-filebeagle">filebeagle</a></strong>, another efficient way to
navigate among project files</li>
<li><strong><a href="http://www.vim.org/scripts/script.php?script_id=3567">colorizer</a></strong>, highlights
css colours in the editor.</li>
</ul>
<p>You can see the full list near the top of <a href="https://github.com/af/dotfiles/tree/master/vim/vimrc">my
vimrc</a>.</p>
<p>I confess to being somewhat of a plugin junkie, so this post is really just
a snapshot of where my setup is now. I'm sure things will be a little different
in a year's time. If you share the same tweaker's mentality, I recommend following
<a href="http://usevim.com/">usevim</a> and the <a href="https://www.reddit.com/r/vim/">vim subreddit</a>,
which are generally how I keep tabs on the Vim community. Also, the
<a href="https://github.com/neovim/neovim">Neovim</a> project is making great progress, and
I'm excited to see how its Lua support and async capabilities will impact the
plugin landscape going forward.</p>
]]></content>
    </entry>
  

    <entry>
      <title>2014 Review</title>
      <link href="/posts/2014-review" />
      <updated>Wed, 07 Jan 2015 00:00:00 GMT</updated>
      <id>/posts/2014-review</id>
      <content type="html"><![CDATA[<p>It's my annual year-in-review, note-form brain dump!</p>
<h2>Reading</h2>
<p>I read 40 books last year, with the following standouts:</p>
<ul>
<li>Refactoring (Martin Fowler)</li>
<li>Envisioning Information (Edward Tufte)</li>
<li>The Disaster Artist (Greg Sestero)</li>
<li>Web Audio API (Boris Smus) <a href="http://chimera.labs.oreilly.com/books/1234000001552/index.html">--> read it online for
free</a></li>
<li>Blankets (Craig Thompson)</li>
<li>Jimmy Corrigan (Chris Ware)</li>
<li>The Innovator's Dilemma (Clayton Christensen)</li>
<li>Show Me The Numbers (Steven Few)</li>
<li>Antifragile (Nassim Taleb)</li>
<li>The Lean Startup (Eric Ries)</li>
<li>The Wisdom of Anxiety (Alan Watts)</li>
</ul>
<h2>Music</h2>
<p>I was well on track to discover exactly zero new music last year, until
R&#x26;B legend D’Angelo came back from the dead to release <a href="http://en.wikipedia.org/wiki/Black_Messiah_%28album%29">Black
Messiah</a> in late December.
While it's definitely not at
<a href="http://en.wikipedia.org/wiki/Voodoo_(D%27Angelo_album)">Voodoo</a>'s level,
I enjoy the new album, and at least it gave me something fresh to listen to.
Looking forward to actively seeking out new music again in 2015.</p>
<h2>Open Source</h2>
<p>In 2014 it was time to learn a few technologies I'd had my eye on for a while:</p>
<ul>
<li><a href="http://d3js.org/">d3</a>, and data visualization in general</li>
<li><a href="http://github.com/facebook/react">React.js</a></li>
<li>the Web Audio API</li>
</ul>
<p>At the end of the year I had a few things to show for my efforts:</p>
<ul>
<li><a href="https://github.com/af/JSnoX">JSnoX</a>, a tool for using React without JSX</li>
<li>A d3-based <a href="http://aaronfranks.com/openra_chart">data visualisation</a> for
<a href="http://openra.net">OpenRA</a></li>
<li>Another data visualization for <a href="http://aaronfranks.com">this site's homepage</a></li>
</ul>
<p>I'm also working on a Web Audio-related side project that will hopefully see the
light of day at some point.</p>
<h2>Work</h2>
<p>Work was steady for 2014. A highlight was definitely implementing a few data
visualisations with d3 (dataviz was obviously a major theme for the year).</p>
<h2>Travel</h2>
<p>Nada.</p>
<h2>Exercise</h2>
<p>Very little.</p>
<h2>Misc</h2>
<p>So it turns out there wasn't too much to write about (here) for 2014. My life last year
was dominated by non-programming concerns, and was overall pretty damn intense and
stressful. I begin 2015 refreshed, and extremely thankful for a lot of
things in my life. One of my goals for the new year is to write here a little more–
<a href="/atom.xml">stay tuned</a> for more questionable ramblings.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Setting up WeeChat on OS X</title>
      <link href="/posts/weechat-on-osx" />
      <updated>Tue, 11 Nov 2014 00:00:00 GMT</updated>
      <id>/posts/weechat-on-osx</id>
      <content type="html"><![CDATA[<p>Hanging out in IRC channels is a great way to learn the nooks and crannies of
programming languages and tools. I've tried several desktop IRC clients in the
past, but each one felt more like a nuisance, and eventually I'd stop using IRC
entirely until I came across the next app to try. Since these days I spend a lot of time
inside a <a href="http://en.wikipedia.org/wiki/Tmux">tmux</a> session, I'd much rather have IRC
in my terminal, rather than granting valuable screen real-estate (and, more importantly,
attention) to a separate native app.</p>
<p>The main contenders for terminal IRC seem to be <a href="http://www.irssi.org/">irssi</a>
and <a href="http://weechat.org/">WeeChat</a>.
I went with WeeChat, since it seemed to be the more modern and actively
maintained of the two. Both are popular options, and you probably can't go wrong
with irssi either. Even though WeeChat is allegedly the more “user-friendly” client, I
encountered some bumps getting it set up on OS X (Yosemite)– hence this post.
A lot of what I learned was cribbed from <a href="http://weechat.org/files/doc/devel/weechat_quickstart.en.html">the WeeChat quickstart
guide</a>, so I
highly recommend reading through it if, like me, you're just getting started.</p>
<p>Below is a screenshot of what you'll end up with at the end of this post. Note
that I'm using <a href="https://github.com/chriskempson/base16">custom terminal colours</a>,
so YMMV on that front. Also, the culmination of my experimentation is
<a href="https://github.com/af/dotfiles/tree/master/weechat">on github</a> if you want to
skip these ramblings.</p>
<p><img src="/img/posts/weechat.jpg" alt="screenshot"></p>
<h2>Installation</h2>
<p>If you're interested in a command-line IRC program for OS X, I'm going to assume
you have <a href="http://brew.sh/">Homebrew</a> installed, or at least know how to get it.
Install WeeChat with:</p>
<p><code>brew install weechat --with-perl --with-python</code></p>
<p>The <code>--with-perl --with-python</code> flags are important if you want to use WeeChat
<a href="http://weechat.org/scripts/">scripts</a>, since most of the popular ones are written
in one of those two languages. You can also add <code>--with-lua</code> and <code>--with-ruby</code>
if you think you'll need plugins from those languages.</p>
<h2>Running WeeChat</h2>
<p>You start WeeChat, predictably enough, by entering <code>weechat</code> in your terminal
app of choice. After that, things can be a bit bewildering. The first time run doesn't give
you any hints for how to connect to a server, configure the program, or
do much of anything. The magic command to get you started is <code>/help</code>. This lists
the available commands used to interact with WeeChat. Each command should be
prefixed with a <code>/</code>, and you can (and should) run <code>/help {command}</code> to get more
information about the important ones.</p>
<p>A few essential commands and hotkeys:</p>
<ul>
<li><code>/quit</code> exits WeeChat</li>
<li><code>/set</code> is used to read &#x26; write your WeeChat configuration. The contents of
<code>/help set</code> is one of the first things you should read as a new WeeChat user.</li>
<li><code>/save</code> saves your current configuration to various config files, in
<code>~/.weechat</code> by default. Out of the box, WeeChat also saves your up-to-date
configuration any time you exit the program.</li>
<li><code>/close</code> closes the current "buffer". If you're familiar with vim, WeeChat's
concept of buffers is similar. Otherwise, just assume that a buffer maps
one-to-one to a connected IRC channel for now.</li>
<li><code>/join {channel}</code> joins an IRC channel (once you're connected to a server;
more on that in the next section).</li>
<li>Use Alt + arrow keys to switch buffers</li>
<li>Use PageUp/PageDown to scroll text in the current buffer</li>
</ul>
<h2>Connecting to Freenode</h2>
<p><a href="http://freenode.net">Freenode</a> is where the majority of programming IRC talk
happens, so let's connect to it. WeeChat comes with basic Freenode
configuration out of the box, which is nice and convenient. I'm going to assume
you have a Freenode account (or will connect without one); registering there is
outside the scope of this post.</p>
<p>You can run <code>/set irc.server.freenode.*</code> to see all of the available freenode
settings. I configured the following settings (substitute your own values where
applicable):</p>
<pre><code>/set irc.server.freenode.addresses chat.freenode.net/7000
/set irc.server.freenode.autoconnect on
/set irc.server.freenode.autojoin {comma-separated list of channels to join}
/set irc.server.freenode.nicks {nicks to use}
/set irc.server.freenode.sasl_password {your freenode password}
/set irc.server.freenode.sasl_username {your freenode username}
/set irc.server.freenode.ssl on
/set irc.server.freenode.ssl_dhkey_size 1024
</code></pre>
<p>I'm a little fuzzy on whether <a href="http://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer">SASL
authentication</a> helps much if you're already
connecting over SSL, but I turned it on anyways. <a href="https://pthree.org/2010/01/31/freenode-ssl-and-sasl-authentication-with-irssi/">This
post</a> has more
information on that.</p>
<p>Once you've entered these settings, <code>/quit</code> and restart WeeChat, and on the next
startup WeeChat should try and auto-connect to Freenode.</p>
<h2>SSL Certificate Errors</h2>
<p>One glitch I hit pretty early was that OS X apparently doesn't ship with the SSL CA
certificates needed to connect to Freenode over SSL. Of course, you could
leave SSL off, but after following the news for the last few years, that
just seems irresponsible. The error message I got looked like this:</p>
<pre><code>gnutls: connected using 1024-bit Diffie-Hellman shared secret exchange
gnutls: receiving 2 certificates
- certificate[1] info:
  - subject `OU=Domain Control Validated,OU=Gandi Standard Wildcard SSL,CN=*.freenode.net', issuer `C=FR,O=GANDI SAS,CN=Gandi Standard SSL CA', RSA key 2048
bits, signed using RSA-SHA1, activated `2014-01-13 00:00:00 UTC', expires `2015-01-14 23:59:59 UTC', SHA-1 fingerprint `a0fde217de32fae602fe67409697e15ac06f0286'
- certificate[2] info:
  - subject `C=FR,O=GANDI SAS,CN=Gandi Standard SSL CA', issuer `C=US,ST=UT,L=Salt Lake City,O=The USERTRUST
Network,OU=http://www.usertrust.com,CN=UTN-USERFirst-Hardware', RSA key 2048 bits, signed using RSA-SHA1, activated `2008-10-23 00:00:00 UTC', expires `2020-05-30
10:48:38 UTC', SHA-1 fingerprint `a9f79883a075ce82d20d274d1368e876140d33b3'
gnutls: peer's certificate is NOT trusted
gnutls: peer's certificate issuer is unknown
irc: TLS handshake failed
irc: error: Error in the certificate.
irc: reconnecting to server in 10 seconds
</code></pre>
<p>The WeeChat FAQ <a href="http://weechat.org/files/doc/weechat_faq.en.html#irc_ssl_connection">has an entry on
this</a>, but
the <code>curl-ca-bundle</code> package it mentions doesn't seem to be available in homebrew.
Instead, you can follow <a href="https://gist.github.com/1stvamp/2158128">this gist</a> to
install the CA bundle that you need. <strong>Update: on OS X 10.11 and later, follow <a href="https://gist.github.com/1stvamp/2158128#gistcomment-1573222">the
instructions in this comment</a>
instead</strong></p>
<p>Back in WeeChat, the following command will point to the CA file that you just
created:</p>
<p><code>/set weechat.network.gnutls_ca_file "/usr/share/curl/ca-bundle.crt"</code></p>
<p>Now restart WeeChat and it should finally connect to Freenode successfully!</p>
<h2>Securing your password</h2>
<p>If you followed the connection instructions above, your IRC password is now
stored in plain text in your WeeChat config file, which is, um, <em>not ideal</em>.
Fortunately, WeeChat has the <code>/secure</code> command, which lets you store sensitive
information in an encrypted local file, and will prompt you
for a password to unlock it on startup. The user guide has <a href="http://www.weechat.org/files/doc/stable/weechat_user.en.html#secured_data">a nice
section on using this
feature</a>.</p>
<h2>WeeChat Scripts</h2>
<p>You can customize and extend WeeChat by installing various "scripts". It comes with
a built-in script manager (try <code>/help script</code>), and <a href="http://weechat.org/scripts/">tons of
scripts</a> are available for installation. As mentioned
earlier, you need to have support for a plugin's language (generally perl or
python) compiled in for them to be installable.</p>
<p>The <a href="http://weechat.org/scripts/source/buffers.pl.html/">buffers.pl</a> and
<a href="http://weechat.org/scripts/source/iset.pl.html/">iset.pl</a> plugins are essential.
Assuming you built WeeChat with perl support, you can install them
with the following commands:</p>
<pre><code>/script install buffers.pl
/script autoload buffers.pl
/script install iset.pl
/script autoload iset.pl
</code></pre>
<p>Buffers.pl gives you an always-visible list of the buffers that you have open
(in my opinion this should be built-in to WeeChat). You can tweak it a bit if
you want, but it works great out of the box. iset is a nice UI for interactively
editing your WeeChat configuration, rather than entering verbose <code>/set</code> commands
every time you want to change something. Install it and read <code>/help iset</code> for more
details.</p>
<p>The other scripts I've found useful so far are:</p>
<ul>
<li><code>urlgrab.py</code> - lists and opens urls from your IRC buffers</li>
<li><a href="https://github.com/sindresorhus/weechat-notification-center"><code>notification_center.py</code></a> -
uses OS X's native notifitions to alert you to IRC highlights and private messages</li>
<li><code>colorize_nicks.py</code> - colours IRC nicknames in the messages themselves</li>
</ul>
<h2>Grab bag</h2>
<p>Here's a miscellaneous list of other stuff I recommend looking into:</p>
<ul>
<li>
<p>Customizing the WeeChat UI colours. For example, the following colour tweaks
made things a bit more readable for me:</p>
<pre><code>/set weechat.bar.title.color_bg black
/set weechat.bar.status.color_bg black
</code></pre>
</li>
<li>
<p>Filtering out join/leaves. In many IRC channels the actual conversation can
be drowned out by tons of join and leave messages. WeeChat has a nice way of
intelligently filtering these out as needed; run
<code>/filter add irc_smart * irc_smart_filter *</code> to activate it.</p>
</li>
<li>
<p>WeeChat lets you easily customize your keyboard hotkeys. I'm a complete hotkey
junkie, so this is one of my favourite features. Read <code>/help key</code> for more info.</p>
</li>
</ul>
<h2>Conclusion</h2>
<p>It's only been two weeks, but I'm really enjoying WeeChat so far. For the first
time, having IRC open feels natural and unobtrusive to my workflow. While the
initial learning curve can be quite steep, once you understand how things are
laid out WeeChat is really fun to explore and customize. <a href="https://github.com/af/dotfiles/tree/master/weechat">My weechat
config</a> is online if you
want to crib some settings. And if you have questions or need help, <code>#weechat</code>
on freenode is a great place to ask.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Open Source Roundup</title>
      <link href="/posts/open-source-roundup" />
      <updated>Fri, 19 Sep 2014 00:00:00 GMT</updated>
      <id>/posts/open-source-roundup</id>
      <content type="html"><![CDATA[<p>I realized recently that I've never written anything about any of the <a href="https://github.com/af?tab=repositories">open
source code</a> I've written. Though
I'm by no means a prolific contributer, there are a few repos kicking around
my github profile that may be of general interest. This post is an attempt to
catalogue a few of them, and reflect on how they turned out.</p>
<h2>djangbone</h2>
<p>My first, and most “successful” project, <a href="github.com/af/djangbone">djangbone</a>
is a REST API library for Django. I was learning Backbone.js at the time (this
was in 2011), and wanted to write some backend APIs that worked with Backbone's
conventions. Djangbone is intentionally minimalistic, but also pretty extensible
and you can create a pretty useful API very quickly.</p>
<p>I've been pleasantly surprised by how much attention Djangbone received. I put it
on <a href="https://www.djangopackages.com/grids/g/api/">Django packages</a> early on, and
that seemed to get it some traction. As of this writing, it's still the 4th most
popular API library there, ranked by GitHub stars.</p>
<h2>backprop</h2>
<p>Another project that received a bit of traction, <a href="https://github.com/af/backprop">backprop</a>
is a Backbone plugin that helps you use JavaScript's
<a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty">properties</a>
on your models.</p>
<p>Even though properties are pretty commonly used in Python, they
don't seem to have found much uptake in JavaScript-land since being <a href="http://ejohn.org/blog/ecmascript-5-objects-and-properties/">introduced in
ES5</a>.
I always thought that was a shame, and replacing Backbone's somewhat ugly <code>model.get('name')</code>
for property access seemed like a perfect fit for them. On top of that, backprop lets
you define lightweight schemas (eg. type coercions and default values) along with
your property definitions.</p>
<h2>littledom</h2>
<p><a href="https://github.com/af/littledom">littledom</a> was a fun pedagogical exercise–
it apes a subset of jQuery's DOM manipulation API. I learned a lot while
writing this and peeking into the internals of jQuery and Zepto. It's also come
in handy for a couple of small side-projects where jQuery felt like overkill.</p>
<h2>shamus</h2>
<p>[shamus] is a project automation/watcher desktop application. It's a
node-webkit app that runs pre-defined tasks when files in a (recursively) watched
directory change. I've found it really useful for running unit tests, linters, and
build tools and receiving near-instant feedback without jumping between apps.
However, since I'm now using <a href="http://en.wikipedia.org/wiki/Tmux">tmux</a> pretty
heavily, I haven't fired shamus up lately. I'd like to try making a curses-based
version to run in a tmux pane at some point, that could be pretty useful too!</p>
<h2>openra_chart</h2>
<p><a href="http://d3js.org">d3</a> is a library that had been on my radar for a long time,
but I'd never sat down and built something with it. Earlier this year I finally
took the plunge and built a little unit visualization for one of my favourite
video games, <a href="http://www.openra.net/">OpenRA</a>.
I still have reservations about the resulting design, but it was
a fun learning exercise. If you're familiar with OpenRA, you should <a href="http://aaronfranks.com/openra_chart">check it
out</a>.</p>
<h2>canvasulative</h2>
<p>A <a href="http://aaronfranks.com/demos/canvasulative/">fun little game</a> I made a few
years back. One of my first experiments with <code>&#x3C;canvas></code>, this is a clone of
a Flash game that I found incredibly addictive. My nephew seemed to really like
my version and told me he played it a lot, which I thought was
pretty great. If I remember correctly, my high score is around 6300...</p>
<h2>Wrapping Up</h2>
<p>There are a few other odds and ends on <a href="https://github.com/af">my GitHub profile</a>,
(including my <a href="https://github.com/af/dotfiles">dotfiles</a> and <a href="https://github.com/af/af.github.com">this web
site</a>). I have a stack of open source ideas
I'd like to get to, but finding the time has really been a challenge of late
(for very good reasons).</p>
]]></content>
    </entry>
  

    <entry>
      <title>2013 Review (in note form)</title>
      <link href="/posts/2013-review" />
      <updated>Tue, 31 Dec 2013 00:00:00 GMT</updated>
      <id>/posts/2013-review</id>
      <content type="html"><![CDATA[<h2>Travel</h2>
<ul>
<li>Portland, OR</li>
<li>Tulum, Mexico</li>
<li>Los Angeles</li>
<li>Toronto &#x26; Ottawa</li>
<li>shorter trips to Seattle/Victoria/Whistler</li>
</ul>
<h2>Exercise</h2>
<ul>
<li>Ran my first 2 half marathons</li>
<li>Both completed in under 2 hours, best time 1:49:52</li>
<li>Can actually do some chin-ups now. Not many, but it's a start</li>
</ul>
<h2>Music</h2>
<ul>
<li>Saw jazz legend <a href="http://en.wikipedia.org/wiki/Kenny_Burrell">Kenny Burrell</a> in concert</li>
<li>Saw <a href="http://en.wikipedia.org/wiki/Avenue_q">Avenue Q</a>, which was equally amazing</li>
<li>New discoveries (no particular order): Flying Lotus,
<a href="http://en.wikipedia.org/wiki/Random_Access_Memories">Random Access Memories</a> (album
of the summer for sure), Michael Kiwanuka, <a href="http://en.wikipedia.org/wiki/Tosca">Tosca</a>,
Mozart’s <a href="https://www.youtube.com/watch?v=6KUDs8KJc_c">Ave Verum Corpus</a>,
and Andrew Mason's equally majestic <em>Hardly Workin’</em></li>
</ul>
<h2>Reading</h2>
<p>Completed 38 books (not bad). Favourites included:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Meditations">Meditations</a> (re-read this incredible classic)</li>
<li><a href="http://www.amazon.com/Pragmatic-Thinking-Learning-Refactor-Programmers/dp/1934356050">Pragmatic Thinking and Learning</a></li>
<li><a href="http://www.amazon.com/Pragmatism-Philosophical-Classics-William-James/dp/0486282708">Pragmatism</a></li>
<li><a href="http://www.amazon.com/Beautiful-Evidence-Edward-R-Tufte/dp/0961392177">Beautiful Evidence</a></li>
<li><a href="http://www.amazon.com/Test-Driven-Development-By-Example/dp/0321146530/">Test Driven Development: By Example</a></li>
<li><a href="http://www.amazon.com/The-Golden-Spruce-Story-Madness/dp/0393328643">The Golden Spruce</a></li>
<li><a href="http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420">Patterns of Enterprise Application Development</a></li>
<li><a href="http://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557">SQL Antipatterns</a></li>
<li><a href="http://www.amazon.com/Practical-Vim-Thought-Pragmatic-Programmers/dp/1934356980">Practical Vim</a> (<em>indispensible</em> if you use Vim)</li>
</ul>
<h2>Work</h2>
<ul>
<li>Participated in Warner Brothers’ Media Camp LA program (a great experience!)</li>
<li>Helped launch a <a href="http://variety.com/2013/digital/news/warner-bros-kicks-off-test-in-startup-reelhouses-enhanced-digital-storefront-1200923528/">pilot program of Warner Bros films on Reelhouse</a></li>
</ul>
<h2>Open Source</h2>
<ul>
<li><a href="https://github.com/af/littledom">littledom</a>, a tiny DOM library</li>
<li><a href="https://github.com/af/backprop">backprop</a>, for using ES5 properties with Backbone</li>
<li><a href="https://github.com/af/shamus">shamus</a>, a work-in-progress desktop app for
instant feedback during development (using node-webkit).</li>
<li>Small contributions to about a dozen other projects. It wasn't much, but it was
something I'd like to build on for 2014.</li>
</ul>
<h2>Misc</h2>
<ul>
<li>Finally set up a personal site (this one)</li>
<li>Learned how to cook beef brisket (easy and delicious!)</li>
<li>Attended the CascadiaJS javascript conference, which was great</li>
</ul>
<p>Overall not bad, but there was some personal stuff that put a damper on 2013
for me. Bring on the New Year!</p>
]]></content>
    </entry>
  

    <entry>
      <title>My Favourite Vim Trick</title>
      <link href="/posts/favourite-vim-trick" />
      <updated>Sun, 27 Oct 2013 00:00:00 GMT</updated>
      <id>/posts/favourite-vim-trick</id>
      <content type="html"><![CDATA[<p>I’ve been a <a href="http://www.vim.org/">vim</a> user for over five years. While it’s one of my favourite
pieces of software, there are two snags that I noticed myself constantly
tripping over while using it:</p>
<ul>
<li>
<p>Using the <code>&#x3C;esc></code> key (or <code>&#x3C;C-[></code> for that matter) to exit Insert mode
is quite a stretch on standard qwerty keyboards. Since vim usage
involves making this mode switch constantly, this is a big annoyance.</p>
</li>
<li>
<p>It must be a weird manifestation of OCD, but no matter which program I’m
using, I compulsively save my work after almost any edit. In vim, this means
hitting <code>:w&#x3C;CR></code> to make sure the current buffer is saved.
That is a lot of keystrokes to go through every few seconds!</p>
</li>
</ul>
<p>My favourite vim mapping addresses both of these problems, and has made editing
much more pleasant.</p>
<p>The first step is to remap our awful CapsLock key to pull double-duty: when
pressed, it works as an <code>&#x3C;esc></code> keypress, and when held down while pressing
another key, it works as a <code>&#x3C;Ctrl></code> modifier key. I picked up this trick from
Steve Losh’s <a href="http://stevelosh.com/blog/2012/10/a-modern-space-cadet/#controlescape">awesomely comprehensive blog post</a> on keyboard customization,
and it has served me very well for the last year. It uses <a href="https://pqrs.org/macosx/keyremap4macbook/index.html.en">KeyRemap4MacBook</a>,
but I’m sure similar programs exist for Linux and Windows.</p>
<p>With that mapping in place, an <code>&#x3C;esc></code> key is very conveniently located next
to the left pinky finger, so getting out of vim's Insert mode is now a snap.</p>
<p>To address the compulsive <code>:w&#x3C;CR></code> problem, I’ve set up custom bindings in Vim
so that every time I hit <code>&#x3C;esc></code>, (in Insert or Normal mode) the buffer is
automatically saved. The mappings (in my .vimrc file) look like this:</p>
<p>{% highlight vim %}
inoremap  :w
autocmd InsertLeave * nnoremap  :w
{% endhighlight %}</p>
<p>The second mapping is a bit of a hack, and will only work after you’ve spent
some time in Insert mode. However, using just <code>nnoremap &#x3C;esc> &#x3C;esc>:w&#x3C;CR></code>
caused weird problems when opening a file for the first time. If anyone has a
more elegant way to handle the Normal mode mapping, I’d love to hear it!</p>
<p>I’ve just started revisiting my dotfiles, cleaning them up, and
<a href="https://github.com/af/dotfiles">putting them on GitHub</a>. Thought this trick might come in handy for anyone
else who has the same annoyances when getting started with vim.</p>
]]></content>
    </entry>
  

    <entry>
      <title>Hello World</title>
      <link href="/posts/hello-world" />
      <updated>Sat, 27 Jul 2013 00:00:00 GMT</updated>
      <id>/posts/hello-world</id>
      <content type="html"><![CDATA[<p>So it looks like I actually got around to putting up a personal site. This
is something I’d thought about doing for a couple years, but had never
invested the time to get it off the ground. After a couple of false starts,
I am going to try and publish at least a few things here going forward.</p>
<p>One of the things I asked myself any time I considered setting
up a personal site is <em>“why”?</em> I think I finally have a few answers to
that question. First off, working on the web platform for the last 7 years
and still not having any kind of personal online space is a bit embarrassing.
While most of my posts here will probably be software/technology related, the
occasional non-technical article will probably find its way here as well.</p>
<p>A second reason for the site is that I’ve noticed my written communication
skills have really deteriorated over time. I haven’t really written anything longer
than 4 paragraphs since university, and anytime you abandon a skill for that
long, atrophy is inevitable.</p>
<p>Finally, I’m hoping to “reset” the way that I communicate online somewhat. I’ve
used Facebook and Twitter for a few years, and I think writing exclusively in
media of their ilk dulls your brain a bit. After the <a href="http://googleblog.blogspot.ca/2013/03/a-second-spring-of-cleaning.html">shutdown of Google Reader</a>,
there has been small renaissance in feed reader software, so
it’s good to see that people are still interested in life beyond 140 characters.
That’s where I am hoping to spend more of my time online.</p>
<p>So hopefully this has been a reasonable defence of this site’s existence.
I’m sort of re-learning how to write, and trying to find a voice,
so it will probably be ugly for a while. Anyways, this site’s source and posts are
all <a href="https://github.com/af/af.github.com">open source on github</a> so if you
see anything wrong, or have any suggestions, let me know. If you are interested in
keeping tabs on what I post, an <a href="http://aaronfranks.com/atom.xml">Atom feed is available</a>.</p>
]]></content>
    </entry>
  
    </feed>