{"version":"1.1","title":"benjamin wil","description":"Software developer, technical writer","language":"en","items":[{"id":"https://benjaminwil.info/antisocial/14","url":"https://benjaminwil.info/antisocial/14","external_url":null,"title":"feed backfilling","summary":"so my website has two main feed sources: the main weblog, and this antisocial feed that came into existence via rss club....","image":null,"banner_image":null,"date_published":"2026-07-03 12:17:34 -0700","date_modified":"2026-07-03 12:17:34 -0700","tags":[],"language":"en","content_html":"<p>so my website has two main feed sources: the main weblog, and this antisocial\nfeed that came into existence via <a href=\"https://daverupert.com/2018/01/welcome-to-rss-club/\">rss club</a>. until now they’ve been\nfully separate things, but i noticed:</p>\n\n<ul>\n  <li>other rss clubbers generally have a single unified feed.</li>\n  <li>based on some emails i’ve received, it seems like some readers here just\ndon’t know about the main weblog feed.</li>\n  <li>from the feed reader’s experience, it could be a bit much to subscribe to\nme twice; i am not very important (positive).</li>\n</ul>\n\n<p>so i decided to update this antisocial feed to also include posts from my\nmain feed. i apologize if this update caused you any displeasure due to\nyour feed reader marking some old-ish posts as unread or something. (the\nmain feed will continue to exclude these all-lowercase antisocial entries.)</p>\n\n<p>if you’d prefer, the classic antisocial-only posts atom and json feeds\ncontinue to live on at new urls:</p>\n\n<ul>\n  <li><a href=\"https://benjaminwil.info/antisocial/antisocial.xml\">https://benjaminwil.info/antisocial/antisocial.xml</a></li>\n  <li><a href=\"https://benjaminwil.info/antisocial/antisocial.json\">https://benjaminwil.info/antisocial/antisocial.json</a></li>\n</ul>\n\n<p>all of this is actually helping me make the design of <a href=\"https://github.com/benjaminwil/lifer\">my static site\ngenerator</a> better. in making this change i uncovered a bug. my rss\nfeed builder supports building both atom and rss feeds. when i created this\nnew <em>selection</em> of weblog and antisocial entries, i failed to ensure both\ncanonical entry collections were set to use the <code>atom</code> format. this caused\nsome entries to be missing encoded html in the built feed. excellent win for\nme, since my current development focus is making arbitrary entry selections,\nand feeds for those selections, a better experience.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/markdown-is-for-humans","url":"https://benjaminwil.info/weblog/markdown-is-for-humans","external_url":null,"title":"Markdown is for humans","summary":"Developers and nerds have seemed satisfied with Markdown as a plain text format for a long time.","image":null,"banner_image":null,"date_published":"2026-06-25 12:21:51 -0700","date_modified":"2026-06-25 12:21:51 -0700","tags":["#<Lifer::Tag:0x00007fffdb5dff88>","#<Lifer::Tag:0x00007fffdb5d26a8>"],"language":"en","content_html":"<p>Developers and nerds have seemed satisfied with Markdown as a plain text\nformat for a long time. Now, I see Markdown approaching the edges of the\nmainstream. I casually mentioned Markdown in conversation with some of\nmy schoolteacher friends and one of them nodded with recognition. That’s\nnew. Maybe it’s because <a href=\"https://workspaceupdates.googleblog.com/2022/03/compose-with-markdown-in-google-docs-on.html\">Google Docs enabled Markdown editing</a> back\nin 2022. Or because, in 2026, <a href=\"https://www.macrumors.com/how-to/ios-import-export-markdown-apple-notes/\">Apple Notes enabled the import and export of\nMarkdown-formatted documents</a>.</p>\n\n<p>Markdown’s creator, John Gruber, wrote that the surge in Markdown’s\npopularity <a href=\"https://daringfireball.net/linked/2026/06/17/vergecast-epic-story-of-markdown\">could be attributed to widespread LLM usage</a>. And yeah, I’ve\ndefinitely seen LLM output filled with Markdown. Maybe the schoolteachers\nsee that, too.</p>\n\n<p>Whether I’m speaking with software developers, technical writers, or\nschoolteachers, though, I see many of them misunderstanding what I think\nis <em>the</em> innovation of Markdown. Compared to the other historical plain text\nmarkup formats like <a href=\"https://en.wikipedia.org/wiki/Setext\">Setext</a> and <a href=\"https://www.phpbb.com/community/help/bbcode\">BBCode</a>, reading and writing\nfull documents in plain text is easy and not syntactically perilous. Yes,\nMarkdown does lend itself to rendering simple rich text and HTML documents. But\nit’s even more useful as a way to increase the information density of\nplain text files pre-render. Gruber summarizes it well in the same post:</p>\n\n<blockquote>\n  <p>Markdown isn’t really a “syntax”. It’s a set of conventions for\nformatting plain text. If everyone agrees to the same basic conventions,\nplain text can be significantly more expressive than a string of unformatted\ncharacters.</p>\n</blockquote>\n\n<p>In the end, I’m grateful for projects like <a href=\"https://commonmark.org\">CommonMark</a> working towards\na complete syntax specification of Markdown.<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup> But I worry that some of their\ndecisions lean in the direction of Markdown that’s harder for humans to read.\nI already see Markdown documents written by authors who think of Markdown as\na feature-complete markup language (it’s not) used to render richer documents.\nMaybe you, too, have seen an order list defined in this way:</p>\n\n<pre><code>1. The first list item.\n1. The second list item.\n1. The third list item.\n</code></pre>\n\n<p>Because GitHub Flavored Markdown, CommonMark, and a bunch of other\nimplementations “correctly” interpret the intention of this as rendering a\nnormal ordered list in HTML:</p>\n\n<blockquote>\n  <ol>\n    <li>The first list item.</li>\n    <li>The second list item.</li>\n    <li>The third list item.</li>\n  </ol>\n</blockquote>\n\n<p>It’s my opinion that if you’re writing a list long enough, or complex enough,\nto benefit from using <code>1.</code> as an auto-incrementer, you shouldn’t be using\nMarkdown. Similarly, if you need to do some of the stuff that <a href=\"https://spec.commonmark.org/0.31.2/#lists\">CommonMark\nimplements for complex lists</a> (see: <a href=\"https://spec.commonmark.org/0.31.2/#example-306\">“There can be any number of\nblank lines between items”</a>\nand <a href=\"https://spec.commonmark.org/0.31.2/#example-314\">“loose lists”</a>;\n<a href=\"https://spec.commonmark.org/0.31.2/#example-308\">insert blank HTML comments to generate two consecutive\nlists</a>; <a href=\"https://spec.commonmark.org/0.31.2/#example-310\">consecutive list\nitems with sub-indentation</a>),\nconsider other tools. CommonMark’s rules and tests are helpful, but they’re\nultimately best for the machines and precarious for humans.</p>\n\n<p>On the other hand, CommonMark and other Markdown specifications include some\nreally great ideas that make Markdown-as-plain-text even better.\nI like Extended Markdown’s simple <a href=\"https://www.markdownguide.org/extended-syntax/#definition-lists\">definition lists</a>:</p>\n\n<pre><code>Lugger\n: A small sailing vessel having two or three masts and a running bowsprit,\n   carrying lugsails.\n</code></pre>\n\n<p>And I like task lists as <a href=\"https://github.blog/news-insights/product-news/task-lists-in-gfm-issues-pulls-comments/\">popularized by GitHub Flavored Markdown</a>:</p>\n\n<pre><code>- [x] Watch *Peter Hujar's Day* (2026).\n- [ ] Watch *Cemetery of Splendor* (2015).\n- [x] Watch *Rose of Nevada* (2025).\n</code></pre>\n\n<p>Notion, Discord, Slack, GitHub, and so on, have cemented Markdown as <em>the</em>\nway to jot down richly-formatted messages and draft simple documents. Markdown\nspecification, implementation, and interoperability do matter and will likely\nmatter more in the future. I just write this as a reminder that Markdown is for\nhumans. My newlines should be for <em>me</em> primarily, the machine secondarily. And\nthe fewer <code>[]{#unique-header-identifier}</code>s I need to insert in my document\nsource, the better.</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>An historical aside: CommonMark was originally dubbed <a href=\"https://blog.codinghorror.com/standard-flavored-markdown/\">Standard\n  Markdown</a>,\n  but <a href=\"https://blog.codinghorror.com/standard-markdown-is-now-common-markdown/\">changed immediately to Common\n  Markdown</a>\n  when Gruber objected. And then to CommonMark when Gruber objected\n  again.  If you read the Standard Markdown introductory post linked,\n  you can see all of the reasons that led to a specification “needing”\n  to exist. Gruber had been invited to collaborate on the project,\n  but he left the CommonMark team on read. It’s clear now that CommonMark\n  would inevitably clash with the one stated goal on Gruber’s <a href=\"https://daringfireball.net/projects/markdown/\">Markdown\n  project page</a>: “The\n  overriding design goal for Markdown’s formatting syntax is to make\n  it as readable as possible.” <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/weblog/i-like-json-feed","url":"https://benjaminwil.info/weblog/i-like-json-feed","external_url":null,"title":"I like JSON Feed","summary":"Recently, I implemented JSON Feed support for my static site generator, Lifer.","image":null,"banner_image":null,"date_published":"2026-06-17 15:24:15 -0700","date_modified":"2026-06-17 15:24:15 -0700","tags":["#<Lifer::Tag:0x00007fffdb18e178>","#<Lifer::Tag:0x00007fffdb5694f0>"],"language":"en","content_html":"<p>Recently, I implemented <a href=\"https://www.jsonfeed.org/\">JSON Feed</a> support for\nmy static site generator, <a href=\"https://github.com/benjaminwil/lifer\">Lifer</a>. My\nimpression is that, in 2026, JSON Feed is still not widely used, while people\ncontinue to rediscover RSS<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup> thanks to the indie web resurgence\nand an appetite for re-decentralization. <a href=\"https://openrss.org/blog/bluesky-has-launched-rss-feeds\">Bluesky supports RSS</a>;\n<a href=\"https://www.rssboard.org/news/211/every-mastodon-user-has-rss-feed\">Mastodon supports RSS</a>; <a href=\"https://support.substack.com/hc/en-us/articles/360038239391-Is-there-an-RSS-feed-for-my-publication\">Substack supports RSS</a>; even Reddit\nsupports RSS<sup id=\"fnref:2\"><a href=\"#fn:2\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">2</a></sup>—but none of them support JSON Feed.</p>\n\n<p>It makes sense for JSON Feed to be less popular than RSS: it’s not\nnearly as old or entrenched; it was created at a time, pre-Twitter implosion,\nin which feed reading had been subsumed by Twitter; and it doesn’t\noffer much <em>new</em> or <em>different</em> over RSS, so why bother. That said, after\nlooking at my implementations of RSS 2.0 and Atom versus my implementation\nof JSON Feed, I found lots to like about JSON Feed.</p>\n\n<p><a href=\"https://www.jsonfeed.org/2017/05/17/announcing-json-feed.html\">The rationale provided</a> by the authors of the spec isn’t written\nin a persuasive way:</p>\n\n<blockquote>\n  <p>We—Manton Reece and Brent Simmons—have noticed that JSON has become\nthe developers’ choice for APIs, and that developers will often go out of\ntheir way to avoid XML. JSON is simpler to read and write, and it’s less\nprone to bugs.</p>\n</blockquote>\n\n<p>Let me reframe this to be more compelling.</p>\n\n<h2 id=\"json-is-better-than-xml-at-storing-html-as-data\">JSON is better than XML at storing HTML as data</h2>\n\n<p>In an Atom feed, you must encode HTML nodes inside of the <code>&lt;content&gt;</code>\nXML node so that they don’t look like the next XML node in the feed. This\nmeans, if you’re publishing HTML in your feeds, that the XML is even less\nhuman-readable than usual. See this excerpt from my blog’s feed:</p>\n\n<pre><code>  &lt;entry&gt;\n    &lt;content&gt;\n      &amp;lt;p&amp;gt;Here’s another blog post vouching for writing Ruby blocks\n      using the semantic rule. Sometimes called “the Weirich rule”\n      because of &amp;lt;a href=&amp;quot;\n      https://en.wikipedia.org/wiki/Jim_Weirich&amp;quot;&amp;gt;\n      Jim Weirich&amp;lt;/a&amp;gt;’s “Braces vs. Do/End” article&amp;lt;\n      sup id=&amp;quot;fnref:weirich&amp;quot;&amp;gt;&amp;lt; a href=&amp;quot;#fn:weirich&amp;quot;\n      class=&amp;quot;footnote&amp;quot; rel=&amp;quot;footnote&amp;quot;\n      role=&amp;quot;doc-noteref&amp;quot;&amp;gt;1&amp;lt;/a&amp;gt;&amp;lt;/sup&amp;gt; and an issue\n      he filed against &amp;lt;\n      a href=&amp;quot;https://github.com/rubocop/ruby-style-guide/issues/162&amp;quot;&amp;gt;&amp;lt;code&amp;gt;rubocop/ruby-style-guide&amp;lt;/code&amp;gt;&amp;lt;/a&amp;gt;.\n      The rule unambiguously answers the question posed by Weirich: “When\n      should you use &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt; for blocks and when\n      should you use &amp;lt;code&amp;gt;do&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt;?”\n      His answer:&amp;lt;/p&amp;gt; &lt;!--…--&gt;\n    &lt;/content&gt;\n</code></pre>\n\n<p>I know you’re thinking that these feeds aren’t meant to be read by humans\nin the raw, so who cares. As a developer, though, wouldn’t you rather deal\nwith simpler raw data? Here’s the same excerpt in JSON Feed (unminified):</p>\n\n<pre><code>\"content_html\":\n  \"&lt;p&gt;Here’s another blog post vouching for writing Ruby blocks using\n  the semantic\\nrule. Sometimes called “the Weirich rule” because\n  of &lt;a href=\\\"https://en.wikipedia.org/wiki/Jim_Weirich\\\"&gt;Jim\n  Weirich&lt;/a&gt;’s\\n“Braces vs. Do/End”\n  article&lt;sup id=\\\"fnref:weirich\\\"&gt;&lt;a\n  href=\\\"#fn:weirich\\\" class=\\\"footnote\\\" rel=\\\"footnote\\\"\n  role=\\\"doc-noteref\\\"&gt;1&lt;/a&gt;&lt;/sup&gt; and an issue he filed against\\n&lt;a\n  href=\\\"https://github.com/rubocop/ruby-style-guide/issues/162\\\"&gt;&lt;code&gt;rubocop/ruby-style-guide&lt;/code&gt;&lt;/a&gt;.\n  The rule unambiguously answers the\\nquestion posed by Weirich:\n  “When should you use &lt;code&gt;{}&lt;/code&gt; for blocks and when\\nshould\n  you use &lt;code&gt;do&lt;/code&gt;/&lt;code&gt;end&lt;/code&gt;?” His answer:&lt;/p&gt; ...\"\n</code></pre>\n\n<h2 id=\"json-is-more-accessible-than-xml\">JSON is more accessible than XML</h2>\n\n<p>JavaScript is one of the most widely-used programming languages in the world,\nand JavaScript Object Notation is a first-class feature of the language. In\na JavaScript context, it’s easy to both generate and parse valid JSON.</p>\n\n<p>Since parsing JSON takes no effort, even client-side in a web browser, I\nfeel there are opportunities for us to go beyond feed reading and aggregation\nwith JSON Feeds. The cost of parsing is so low, and the specified structure\nis simple. Desktop web browsers can even autoformat JSON to be nicely\nhuman readable<sup id=\"fnref:3\"><a href=\"#fn:3\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">3</a></sup>.</p>\n\n<p>New programmers and non-programmers can make sense of JSON, and JSON parsing\ntools, pretty quickly. Feel free to pair this with my “HTML doesn’t need to\nbe escaped in JSON Feed” argument above. RSS is just more abstract to read\nand slightly more error-prone to write. Given this, I think JSON Feed has\nthe accessibility edge over RSS.</p>\n\n<h2 id=\"the-standard-exchange-format-is-json\">The standard exchange format is JSON</h2>\n\n<p>Many popular programming languages besides JavaScript also have first-class\nsupport for JSON. For example, I implemented JSON Feed generation support in\nRuby using <a href=\"https://docs.ruby-lang.org/en/master/JSON.html\">Ruby’s standard JSON library</a>. Writing the implementation\nin Ruby felt no different than doing it in JavaScript.</p>\n\n<p>The reason you’ll find JSON libraries built into so many languages is because\nit’s normal for API services respond to clients in JSON these days. In my\nexperience, XML-based APIs have been eclipsed by JSON-based ones. Even as\nfar back as 2011, a blog post by Dmitriy Samovskiy, <a href=\"http://www.somic.org/2011/06/08/json-vs-xml-in-api/\">“JSON vs. XML in\nAPI,”</a> indicates that developers were realizing that designing JSON-based\nAPIs resulted in a less complex system:</p>\n\n<blockquote>\n  <p>There is no easy and universal way how to represent nested hashes and arrays\nusing XML (if there is, I hope to hear from you about it—I need stable\nlibraries that can convert arrays and hashes to XML and back that could\ninterop among each other for all major programming languages). Of course it’s\npossible and not terribly difficult, but it’s something that one must do.</p>\n\n  <p>Contrast this situation with JSON—you don’t need to worry about this,\nit’s already taken care of for you. The only limitation of JSON that we\nfaced was that JSON doesn’t like integers as hash keys, it wants you to\nconvert them to strings or use an array instead of a hash.</p>\n</blockquote>\n\n<p>I would guess most of the software developers I’ve met and worked with, my\nage or younger, have never had to consume an API that responds in XML. (Even\nmore of them may not know what <a href=\"https://en.wikipedia.org/wiki/SOAP\">SOAP</a> is.)</p>\n\n<p>If JSON is the standard exchange format, it makes sense that websites\nwould benefit from providing content in that format so that content can be\nread… standardly. The longevity and resilience of RSS has made it <em>the\nstandard</em> for website feeds, but we have watched the rest of the Web move\non to JSON for good enough reasons. I’d say “why not JSON Feed?” since it\nalready exists and is well specified.</p>\n\n<h2 id=\"software-developers-are-good-at-working-with-json\">Software developers are good at working with JSON</h2>\n\n<p>Implementing JSON Feed was a breeze. I compared my implementations of Atom,\nRSS, and JSON Feed generation side by side. They’re all shaped the same way,\nand there are only a few more lines of code to required to handle some RSS\nspecification things. What made it a breeze was the simplicity of the JSON\nlibrary API I was using: the public interface is minimal; the method names\nmatch my mental model for working with all kinds of (non-JSON Feed) JSON data.</p>\n\n<p>My comparison revealed to me that the standard Ruby library for RSS is <em>pretty</em>\nbespoke and hasn’t been used by nearly as many people over the years. It’s\nnot a bad library, but there’s so much friction that simply doesn’t exist\nwhen slinging JSON. It’s no contest.</p>\n\n<p>Anyway, this website <a href=\"/feed.json\">now has a JSON Feed</a> if you’d like\nto subscribe to my posts that way.</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>By “RSS,” I really mean “Atom and RSS,” throughout this article. <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:2\">\n      <p>I couldn’t find official documentation for\n  this. Just take the URL to any subreddit and add <code>/.rss</code> to the\n  path, i.e. <code>https://www.reddit.com/r/TVTooHigh/.rss</code>. I’ll say, though, that\n  in the past, the few subreddit feeds I subscribed would stop working… for\n  months at a time. It may be more reliable to use a third-party subreddit\n  RSS feed generator, if reliability matters to you. <a href=\"#fnref:2\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:3\">\n      <p>I often use <a href=\"https://firefox-source-docs.mozilla.org/devtools-user/json_viewer/index.html\">Firefox’s JSON viewer</a>.\n  It’s good. <a href=\"#fnref:3\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/antisocial/13","url":"https://benjaminwil.info/antisocial/13","external_url":null,"title":"taking the summer off work","summary":"after deliberating for a while and doing some budget-math, i decided to take the summer off of work and attempt to recove...","image":null,"banner_image":null,"date_published":"2026-06-16 13:29:28 -0700","date_modified":"2026-06-16 13:29:28 -0700","tags":[],"language":"en","content_html":"<p>after deliberating for a while and doing some budget-math, i decided to take\nthe summer off of work and attempt to recover from burnout. maybe i’ll write\nabout that more over the next few months.</p>\n\n<p>this is the first time since i was fourteen that i haven’t either been\ndoing school or doing work (or doing both). as much as i know this break\nis necessary, i’m not looking forward to it yet.</p>\n\n<p>as an adult, i have been risk averse when it comes to employment and\nmoney. i’ll be living leaner this summer, but i’ll be okay.</p>\n\n<p>my intention this week is to create a calendar. i want to ensure that i’m not\njust rotting away in my apartment full-time. i’ll plan out things i want to\ngo out and do; milestones for personal projects i want to make progress on;\nand well-defined <em>chore goals</em> (i’ve been putting off some things).</p>\n\n<p>if you’re reading this and have experienced burnout, or are getting close,\nhello there. feel free to send me a message. :-)</p>\n"},{"id":"https://benjaminwil.info/weblog/ssh-key-agent-management","url":"https://benjaminwil.info/weblog/ssh-key-agent-management","external_url":null,"title":"SSH agent–managed SSH keys","summary":"You probably already know: there’s no excuse to not be using a password manager in 2026.","image":null,"banner_image":null,"date_published":"2026-05-08 16:24:10 -0700","date_modified":"2026-05-08 16:24:10 -0700","tags":["#<Lifer::Tag:0x00007fffdb18e178>"],"language":"en","content_html":"<p>You probably already know: there’s no excuse to not be using a password\nmanager in 2026. If you read my blog regularly, you may even be a person\nactually using a password manager. It’s possible, though, that you don’t\nuse said password manager to manage your SSH keys.</p>\n\n<p>If you didn’t already know <a href=\"https://developer.1password.com/docs/ssh/manage-keys/\">you can manage your SSH credentials seamlessly in\n1Password</a>. You can\ndo it <a href=\"https://github.com/keepassxreboot/keepassxc/blob/52318f4d22c3707dfe1743502d89d6bbc785b2cb/docs/topics/SSHAgent.adoc\">with KeePassXC, too</a>. I’m not going to mention the other\nbig password managers by name, but at least one of them also already has\nbuilt-in SSH agent support. Yes, the managers implement an SSH agent (see\n<a href=\"https://man.openbsd.org/ssh-agent\"><code>ssh-agent</code></a>) and make authenticating\nvia SSH feel kinda like authenticating to Netflix via a web browser.</p>\n\n<p>More than ever, it’s a good idea to <em>not</em> store any credentials (or sensitive\ndata in general) unencrypted on your disks. <em>More than ever</em> because there\nhave been many notable instances of open-source software having recently been\ncompromised via supply-chain attacks and backdoors. Group-IB characterizes\nsupply-chain attacks as <a href=\"https://www.group-ib.com/blog/supply-chain-attack-groups-2026/\">being hyped</a> right now, which is funny and\nhorrifying.</p>\n\n<p>Between all the free-ish tools you use everyday and the LLM-related software\nyour boss pays for, your computer is more an open wound, ready to be infected,\nthan ever. You likely know this, I’m only here to remind you.</p>\n\n<p>If, like me, you manage an environment or two where you don’t want to install\na password manager, and you simply want to avoid leaving SSH private keys in\nplaintext, you can use GPG and a simple shell script to keep your credentials\nsafe from prying mal-processes:</p>\n\n<pre><code>#!/usr/bin/env sh\n#\n# ssh-enc\n#\n# Usage:\n#   ssh-enc &lt;path to GPG-encrypted SSH private key&gt; [SSH arguments]\n# Example:\n#   $ ssh-enc \"$HOME/.ssh/vps.gpg\" benjaminwil@example.com -vvv\n\nencrypted_ssh_private_key_path=\"$1\"\nshift\n\nssh_arguments=\"$@\"\n\neval \"$(ssh-agent -s)\"\nssh-add &lt;(gpg --decrypt \"$encrypted_ssh_private_key_path\")\n\nssh \"$ssh_arguments\"\n</code></pre>\n\n"},{"id":"https://benjaminwil.info/antisocial/12","url":"https://benjaminwil.info/antisocial/12","external_url":null,"title":"admitting defeat (re: android development environments on guix)","summary":"for over a month i’ve spent a weird amount of my free time trying to set up an android development environment (via react...","image":null,"banner_image":null,"date_published":"2026-04-26 13:26:28 -0700","date_modified":"2026-04-26 13:26:28 -0700","tags":[],"language":"en","content_html":"<p>for over a month i’ve spent a weird amount of my free time trying to set\nup an android development environment (via <a href=\"https://reactnative.dev/\">react native</a>, and then\n<a href=\"https://nativescript.org/\">nativescript</a>) on my laptop running the <a href=\"https://guix.gnu.org/\">guix</a> linux distribution.\ni even had a bit of help thanks to some writing about this topic done by\n<a href=\"https://gofranz.com\">franz geffke</a>:</p>\n\n<ul>\n  <li><a href=\"https://gofranz.com/blog/react-native-on-guix/\">react native (and android development) on guix [with docker]</a></li>\n  <li><a href=\"https://gofranz.com/blog/react-native-android-on-guix-without-docker/\">build react native android apps on guix in 5 minutes</a></li>\n</ul>\n\n<p>unfortunately, i couldn’t take franz’s configuration verbatim and make it\nwork. and beyond that, i also got nerd-sniped trying to make his setups more\nergonomic for me. (i am slightly allergic to having to remember to manually\nopen 2-5 shells, source a bunch of stuff, and then start a bunch of processes\nmanually.)</p>\n\n<p>on my own, i went down some rabbit holes, asked some questions in the\n<em>#nonguix</em> channel on libera, and attempted setting up my own bespoke\nenvironments via guix fhs containers, docker, and even a qemu virtual\nmachine. the closest working environment was the qemu machine. that one at\nleast did not require a bunch of harnessing to appease guix’s declarative,\nimmutable nature. if even allowed me to connect to my physical android device\nwithout too much ritual. i abandoned that strategy, though, because it became\na guix-related time-sink to learn how to set up a non-virtio filesystem so i\ncould continue to run a code editor, etc. on my irl, non-virtual host machine.</p>\n\n<p>could i get any of these strategies to work? with enough time, i think\nyes. but the personal-enjoyment accounting is already starting to be fucked up.\nthis blog post is me surrendering and trying to not feel horrible about all\nof the time i have just admitted to losing.</p>\n\n<p>no hate directed at guix here. i appreciate it the more i learn it. but\ni’m bummed out i couldn’t get the <a href=\"https://guix.gnu.org/en/blog/2023/the-filesystem-hierarchy-standard-comes-to-guix-containers/\">guix container with fhs emulation</a>\nworking with my physical android device. the core of the issue was that the\nadb server required for communication with a physical android device could\nnot be run from within the container no matter what environment shit i told\nthe container it could have access to. and running adb on the host didn’t\n“just work” with the processes inside of the container. with enough time, maybe\ni could get there. but at this point, i also just don’t know enough about the\nandroid sdk tooling to really be effective at creating the developer-harness.</p>\n\n"},{"id":"https://benjaminwil.info/antisocial/11","url":"https://benjaminwil.info/antisocial/11","external_url":null,"title":"new light colourscheme","summary":"it’s a bit weird: yellows and blues and reds. what do you think?","image":null,"banner_image":null,"date_published":"2026-04-05 15:10:38 -0700","date_modified":"2026-04-05 15:10:38 -0700","tags":[],"language":"en","content_html":"<p>it’s a bit weird: yellows and blues and reds. what do you think?</p>\n"},{"id":"https://benjaminwil.info/antisocial/10","url":"https://benjaminwil.info/antisocial/10","external_url":null,"title":"my notetaking system, early 2026","summary":"the process is still evolving, but i’m going to describe my notetaking system as of right now.","image":null,"banner_image":null,"date_published":"2026-04-05 14:37:58 -0700","date_modified":"2026-04-05 14:37:58 -0700","tags":[],"language":"en","content_html":"<p>the process is still evolving, but i’m going to describe my notetaking\nsystem as of right now. i started from zero in novemberish last year and am\ngetting happy with the cadence and quality of my notes as of starting this\nnew system.</p>\n\n<p>the biggest change that comes with the new system is that i’m now <em>paper\nfirst</em>, even if i’m sitting in front of a computer. the procedure for taking\nand processing paper notes is on a weekly cadence:</p>\n\n<ol>\n  <li>at the beginning of a week, start a new page with the date as a header.</li>\n  <li>create two sections on this page: <em>consumption</em> and <em>todos</em>. (usually\n<em>consumption</em> takes up two-thirds of the page, and <em>todos</em> one-third.)</li>\n  <li>create a third section starting on the next page: <em>notes</em>.</li>\n  <li>write down the titles of media consumed over the week in the <em>consumption</em>\nsection. if i have additional thoughts or context to add for a piece of\nmedia, then an endnote indicator (a superscript number like <sup>2</sup>)\nis added. then, the additional notes can be added to the <em>notes</em> section.</li>\n  <li>write down tasks to be completed for the week under <em>todos</em>.<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup> if\nadditional context for a task needs to be written down, the task gets an\nendnote, just like <em>consumption</em> media items. if/when i complete tasks,\nthey get an X.</li>\n  <li>and then the <em>notes</em> section is pretty freeform, where each distinct note\nhas a heading and/or references the endnote indicator from its antecedent\n<em>consumption</em> log or <em>todos</em> task.</li>\n  <li>at the end of the week, digitize all of the notes and save them to my\npersonal wiki, where notes may get incorporated into blog post drafts, longer\nprivate articles about things i’m learning about, or emails i intend to\nsend. by “digitizing” i mostly mean “type out”.</li>\n  <li>if i think an uncompleted <em>todo</em> items are important enough to carry\nforward, they get added to the next week’s <em>todos</em> section.</li>\n</ol>\n\n<p>that’s kind of it for now. it’s a very lightweight process i don’t have\nto think about. i think the next refinements to occur will be on the\nprocessing/digitizing side of things.</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>because i tend not to live by task lists, i only write down aspirational\n  tasks that i’d like to complete for the week, not every boring thing\n  i need to complete to continue living. <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/antisocial/09","url":"https://benjaminwil.info/antisocial/09","external_url":null,"title":"you're allowed to be uninsightful","summary":"i’ve published two (small) non-antisocial blog posts this month, which is about one more than usual:","image":null,"banner_image":null,"date_published":"2026-03-21 10:43:12 -0700","date_modified":"2026-03-21 10:43:12 -0700","tags":[],"language":"en","content_html":"<p>i’ve published two (small) non-antisocial blog posts this month, which is\nabout one more than usual:</p>\n\n<ul>\n  <li><a href=\"https://benjaminwil.info/weblog/ruby-semantic-blocks\">semantic style ruby blocks</a></li>\n  <li><a href=\"https://benjaminwil.info/weblog/portable-feature-flags-in-ruby\">portable feature flags in ten-ish lines of ruby</a></li>\n</ul>\n\n<p>the topics probably aren’t interesting to most people, let alone most rubyists.\nbut lately, i’ve been inspired by some authors and creators (rss club\nmembers included), and the edges of wikipedia, that are pleased to publish\n“the boring” information. i’m not trying to denigrate anyone by saying\nthis. writing what you know, for yourself, to clarify your own thinking,\nand to present information clearly to <em>the maybe one someone somewhere</em>\nwho needs to absorb it, is a good instinct.</p>\n\n<p>said another way: i have relearned that we don’t have to write something\nthat’s interesting to a giant venn diagram of people. most of us aren’t <em>the\nnew yorker</em> and don’t need to be.</p>\n\n<p>i know many of you reading this who write already know this. maybe one of you,\nlike me, needs to be reminded.</p>\n\n<p>one of the creators i’ve been inspired by is the biblical scholar <a href=\"https://danielomcclellan.com/\">dan\nmcclellan</a>. to quote his bio:</p>\n\n<blockquote>\n  <p>his research focuses on the languages and history of the bible, as well as\non the conceptualization of deity, of scripture, and of religious identity\nthrough the methodological lenses of cognitive linguistics and the cognitive\nscience of religion.</p>\n</blockquote>\n\n<p>he has made over three thousand videos now. he isn’t afraid to repeat\nhimself. he says lots of boring stuff that scholars in his field know quite\nwell. as someone with no credentials in this field, i appreciate that one\nof his goals is to better communicate what the consensus view of scholars\nis when in comes to controversial social and/or theological issues with\nregard to christianity in the west. he also is skilled at “stitching” videos\nthat spread misinformation about christian shit and dunking on the content\ncreators. sometimes he can get pretty mean.</p>\n\n<p>i am not interested in many of the videos he publishes, and i definitely\ndon’t watch them all, but seeing how consistent he is in form, content, and\nmessage, and how he bravely repeats himself in such a tireless way, gives\nme hope that i can continue to be at least as prolific as i’ve been this month.</p>\n\n<p>cheers to us boring people.</p>\n"},{"id":"https://benjaminwil.info/weblog/portable-feature-flags-in-ruby","url":"https://benjaminwil.info/weblog/portable-feature-flags-in-ruby","external_url":null,"title":"Portable feature flags in ten-ish lines of Ruby","summary":"It may make sense to use a mature feature flag library or pay for feature flags as a service in your complex application....","image":null,"banner_image":null,"date_published":"2026-03-21 10:18:36 -0700","date_modified":"2026-03-21 10:18:36 -0700","tags":["#<Lifer::Tag:0x00007fffdb6d57d0>","#<Lifer::Tag:0x00007fffdb18e178>"],"language":"en","content_html":"<p>It may make sense to use a mature feature flag library or pay for feature\nflags as a service in your complex application. That said, you can build\npretty robust feature flags in just a few lines of Ruby:</p>\n\n<pre><code>require \"json\"\n\nmodule Features\n  class &lt;&lt; self\n    def as_json\n      flags = self.public_methods - Object.public_methods - [:as_json]\n      flags\n        .to_h { |method|\n          [method.to_s.sub(\"?\", \"\"), self.public_send(method)]\n        }\n        .to_json\n    end\n\n     def éric_rohmer_mode_enabled? = enabled?(\"ERIC_ROHMER_MODE\")\n\n     private def enabled?(env_string)\n       return false if (value = ENV[env_string]).nil?\n       value != \"false\" &amp;&amp; value.length != 0\n     end\n   end\n end\n</code></pre>\n\n<p>In this example, we track environment variables for each of our feature flags\n(just one, for now: <code>ERIC_ROHMER_MODE</code>). The interface returns a boolean\nvalue when we ask whether the given flag is enabled. Because we’re managing\nthe flags within a single module, we can do nice things such as introduce\nthe <code>Features.as_json</code> method to the current enabled status of all of our\nfeature flags, meaning we can send this data to other systems and to web\nclients more easily:</p>\n\n<pre><code>Features.as_json\n=&gt; \"{\\\"éric_rohmer_mode_enabled\\\":false}\"\n</code></pre>\n\n<p>If you don’t need the portability of JSON, you can\nwrite even fewer lines of Ruby to get the same functionality by relying on\ntruthy and falsey outputs instead of booleans.</p>\n\n<p>As long as you keep higher-complexity methods like <code>Features.as_json</code> to\na minimum, this module can easily grow with you as your need for weirder\nfeature flags increases. If some features should only be available to users\nwith a beta tester role, or you want to expose some functionality when a\ncertain URL parameter is present, it’s just a matter of injecting your user\nobject and your request parameters object:</p>\n\n<pre><code>require \"date\"\nrequire \"json\"\n\nmodule Features\n  ÉRIC_ROHMER_LAUNCH_DAY = Date.new(1920, 03, 21)\n\n  NULL_SCOPE = {\n    url_params: {},\n    user: nil\n  }\n\n  class &lt;&lt; self\n    def as_json(scope = NULL_SCOPE)\n      flags = self.public_methods - Object.public_methods - [:as_json]\n      flags\n        .to_h { |method|\n          [method.to_s.sub(\"?\", \"\"), self.public_send(method, **scope)]\n        }\n        .to_json\n    end\n\n     def éric_rohmer_mode_enabled?(_)\n       enabled?(\"ERIC_ROHMER_MODE\") &amp;&amp;\n         Time.now.to_date &gt;= ÉRIC_ROHMER_LAUNCH_DAY\n     end\n\n     def infinite_money_enabled?(user:, **)\n       enabled?(\"INFINITE_MONEY\") &amp;&amp; !user.nil? &amp;&amp; user.beta_tester?\n     end\n\n     def preview_mode_enabled?(url_params:, **)\n       enabled?(\"PREVIEW_MODE\") &amp;&amp; url_params[:preview] == \"yes\"\n     end\n\n     private def enabled?(env_string)\n       return false if (value = ENV[env_string]).nil?\n       value != \"false\" &amp;&amp; value.length != 0\n     end\n   end\n end\n</code></pre>\n\n<p>As long as you’re keeping track of potential dependencies (<code>NULL_SCOPE</code> in\nthis example) and passing in reasonable default values, <code>Features.as_json</code>\nstill works sans arguments, and each flag check can independently be as\ncomplex as you’d like it to be.</p>\n\n<pre><code>JSON.parse Features.as_json\n=&gt;\n{\"éric_rohmer_mode_enabled\"=&gt;false,\n \"preview_mode_enabled\"=&gt;false,\n \"infinite_money_enabled\"=&gt;false}\n\nJSON.parse Features.as_json(user: beta_tester, url_params: {})\n=&gt;\n{\"éric_rohmer_mode_enabled\"=&gt;false,\n \"preview_mode_enabled\"=&gt;false,\n \"infinite_money_enabled\"=&gt;true}\n</code></pre>\n\n<p>I’ve used keyword arguments in my interface because I prefer them to positional\narguments. This ensures the flag method arguments remain legible\nin your application code and are easy comprehend by other readers. But as\nyou can see, keyword arguments make flags a bit more annoying to write once\nyou’ve introduced dependencies.</p>\n\n<p>The most awkward thing here is that even feature flags methods that\ndon’t require dependency injection must define an argument (<code>_</code> or\n<code>_unused</code>). The second most awkward thing is that, only because we’re\nusing keyword arguments, we need to pass a double-splat argument (<code>**</code>)\nto ensure, when <code>Features.as_json</code> is computing the given dependencies for\neach flag dynamically, irrelevant arguments are ignored without raising an\n<code>ArgumentError</code>. Luckily, the relevant dependencies remain very, very visible\nto anyone else reading.</p>\n\n<p>Every codebase I’ve worked on deals with feature flags a little bit\ndifferently. I’d love to hear about what’s different in your\napplication’s. (Send me a message!)</p>\n"},{"id":"https://benjaminwil.info/antisocial/08","url":"https://benjaminwil.info/antisocial/08","external_url":null,"title":"oscar predictions 2026","summary":"these are not the things that i necessarily would want to win, but what i think will happen.","image":null,"banner_image":null,"date_published":"2026-03-13 21:14:30 -0700","date_modified":"2026-03-13 21:14:30 -0700","tags":[],"language":"en","content_html":"<p>these are not the things that i necessarily would want to win, but what i\nthink will happen. (i’ve got nothing better to do.)</p>\n\n<p>best picture: <em>Hamnet</em></p>\n\n<p>best actress: Jessie Buckley, <em>Hamnet</em></p>\n\n<p>best actor: Timothée Chalamet, <em>Marty Supreme</em></p>\n\n<p>best supporting actress: Elle Fanning, <em>Sentimental Value</em></p>\n\n<p>best supporting actor: Benicio del Toro, <em>One Battle After Another</em></p>\n\n<p>best director: Paul Thomas Anderson, <em>One Battle After Another</em></p>\n\n<p>best original song: “Golden” from <em>Kpop Demon Hunters</em></p>\n\n<p>best original score:  <em>Hamnet,</em> Max Richter</p>\n\n<p>best animated film:  <em>KPop Demon Hunters</em></p>\n\n<p>best international film: <em>Sentimental Value</em>, Norway</p>\n\n<p>best documentary feature: <em>Mr. Nobody Against Putin</em></p>\n\n<p>best casting: <em>Marty Supreme</em></p>\n\n<p>best sound: <em>F1</em></p>\n\n<p>best cinematography: <em>Train Dreams</em></p>\n\n<p>best original screenplay: <em>Sinners,</em> Ryan Coogler</p>\n\n<p>best adapted screenplay: <em>Bugonia</em>, Will Tracy</p>\n\n<p>best live action short film: <em>Butcher’s Stain</em></p>\n\n<p>best animated short film: <em>The Girl Who Cried Pearls</em></p>\n\n<p>best documentary short film: <em>Children No More: Were and Are Gone</em></p>\n\n<p>best visual effects: <em>Jurassic World Rebirth</em></p>\n\n<p>best production design: <em>Sinners</em></p>\n\n<p>best film editing: <em>F1</em></p>\n\n<p>best makeup and hairstyling: <em>Frankenstein</em></p>\n\n<p>best costume design: <em>Frankenstein</em></p>\n"},{"id":"https://benjaminwil.info/weblog/ruby-semantic-blocks","url":"https://benjaminwil.info/weblog/ruby-semantic-blocks","external_url":null,"title":"Semantic style Ruby blocks","summary":"Here’s another blog post vouching for writing Ruby blocks using the semantic rule.","image":null,"banner_image":null,"date_published":"2026-03-08 16:06:46 -0700","date_modified":"2026-03-08 16:06:46 -0700","tags":["#<Lifer::Tag:0x00007fffdb6d57d0>","#<Lifer::Tag:0x00007fffdb18e178>"],"language":"en","content_html":"<p>Here’s another blog post vouching for writing Ruby blocks using the semantic\nrule. Sometimes called “the Weirich rule” because of <a href=\"https://en.wikipedia.org/wiki/Jim_Weirich\">Jim Weirich</a>’s\n“Braces vs. Do/End” article<sup id=\"fnref:weirich\"><a href=\"#fn:weirich\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup> and an issue he filed against\n<a href=\"https://github.com/rubocop/ruby-style-guide/issues/162\"><code>rubocop/ruby-style-guide</code></a>. The rule unambiguously answers the\nquestion posed by Weirich: “When should you use <code>{}</code> for blocks and when\nshould you use <code>do</code>/<code>end</code>?” His answer:</p>\n\n<ul>\n  <li>Use braces (<code>{}</code>) for blocks that return values.</li>\n  <li>Use keywords (<code>do</code>/<code>end</code>) for blocks executed for side effects.</li>\n</ul>\n\n<h2 id=\"an-explanation\">An explanation</h2>\n\n<p>Let’s say we were iterating over some movies in order to print out their titles:</p>\n\n<pre><code>films = [\n  \"A Tale of Springtime\",\n  \"A Tale of Winter\",\n  \"A Summer's Tale\",\n  \"A Tale of Autumn\"\n]\n\nfilms.each do |title|\n  puts title\nend\n</code></pre>\n\n<p>An <code>#each</code> block only ever executes for side effects and never returns a\nvalue we can do stuff with. If we wanted to pre-format our list\nof films, we would need to iterate in such a way that mutates our film list\n(or creates a new list) before printing the films out:</p>\n\n<pre><code>films.map! { |title|\n  title.upcase\n}\n\nfilms.each do |title|\n  puts title\nend\n</code></pre>\n\n<p>At a glance, a reader can see two different types of blocks performing two\ndifferent functions: one mutates data; the other is executed for side effects\n(printing out a list of films). An author not using the semantic rule might\nhave written this:</p>\n\n<pre><code>films.map! { |title| title.upcase }\nfilms.each { |title| puts title }\n</code></pre>\n\n<p>Or this:</p>\n\n<pre><code>films.map! do |title|\n  title.upcase\nend\n\nfilms.each do |title|\n  puts title\nend\n</code></pre>\n\n<p>Both of these are readable but do not communicate intent as clearly as the\nsemantic style blocks. My primary goal when authoring code is to communicate\nmy intent to other readers, so I appreciate the ability to be as precise\nin as few characters as possible.</p>\n\n<h2 id=\"criticisms-of-the-style\">Criticisms of the style</h2>\n\n<p>To me, there are two compelling reasons to be critical of semantic style\nblocks: the readability of <code>do</code>/<code>end</code> one-liners; and the inability of\nautomated tools to format Ruby code consistently based on the semantic\nrule. I can agree that, sometimes, one-liners meant to execute side effects\nwould make reading code more difficult:</p>\n\n<pre><code>films.each do |title| puts title end\n# is less readable than:\nfilms.each { |title| puts title }\n</code></pre>\n\n<p>But Ruby is so expressive that, in the off-chance you need to write a\n<code>do</code>/<code>end</code> one-liner, I’m confident there are other ways of achieving better\nreadability without ditching the rule:</p>\n\n<pre><code>films.each do |title| puts(title) end\n</code></pre>\n\n<p>As for auto-formatting Ruby code while abiding by the semantic rule, this seems\nlike a solvable problem in the long term. The “problem” is that Ruby is\n“too” expressive, and the tooling would have to understand a lot about the\nprogram and the author’s intent to reformat to braces or <code>do</code>/<code>end</code> correctly.</p>\n\n<p>There is <a href=\"https://github.com/standardrb/standard/issues/109\">an interesting issue filed against\n<code>standardrb</code></a> discussing\nthis. And, as of 1.0.0, <code>standardrb</code> has a relaxed, <a href=\"https://github.com/standardrb/standard/pull/263\">“let the author\nchoose”</a> approach to this\nblock syntax. If you’re developing an application and your Ruby code is\nauto-formatted, I hope you will still choose to be intentional whenever\nyou’re writing not-auto-formattable code.</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:weirich\">\n      <p>Weirich’s blog is no longer online but is <a href=\"https://web.archive.org/web/20140117145536/http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc\">archived by the Wayback\n        Machine</a>. <a href=\"#fnref:weirich\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/antisocial/07","url":"https://benjaminwil.info/antisocial/07","external_url":null,"title":"your mime type is showing","summary":"hi.","image":null,"banner_image":null,"date_published":"2026-03-04 23:21:54 -0800","date_modified":"2026-03-04 23:21:54 -0800","tags":[],"language":"en","content_html":"<p>hi. <a href=\"https://www.carolinecrampton.com/the-view-from-rss/\">rss club showed up in my feeds\ntoday</a>, and then\ni remembered that <em>this feed is linked there</em> and i haven’t used it in a\nwhile. and then i clicked on the feed and realized that nginx was rendering\nthe feed with a mime type of <code>text/xml</code> rather than <code>application/rss+xml</code>. so\ni fixed that.</p>\n\n<p><code>text/xml</code> will likely tell your browser to render the feed as an xml in the\nbrowser. whereas <code>application/rss+xml</code>, <code>application/atom+xml</code>, and so on,\nwill tell your browser to use whatever application is configured to be your\nfeedreader. on my ios device, for example, clicking a link to this feed now\nresults in a dialog modal. “open this feed in reeder?” it asks. this is much\nnicer than the browser rendering a fucking unstyled text file.</p>\n\n<p>i noticed some other rss club feeds have similar issues, so if you’re reading\nthis and your a clubber, do consider checking out your feeds.</p>\n\n<p>on my main feed (<a href=\"https://benjaminwil.info/weblog\">html</a>,\n<a href=\"https://benjaminwil.info/feed.xml\">rss</a>) i succeeded in my informal goal\nof posting one-ish thing per month in 2025. i intend to keep it up, and\nmaybe i’ll even throw some more stuff in this antisocial feed this year, too.</p>\n\n<p>bye.</p>\n"},{"id":"https://benjaminwil.info/weblog/vff-2026","url":"https://benjaminwil.info/weblog/vff-2026","external_url":null,"title":"Victoria Film Festival 2026","summary":"This month was the 32nd occurrence of the Victoria Film Festival here in Victoria, British Columbia.","image":null,"banner_image":null,"date_published":"2026-02-20 18:47:33 -0800","date_modified":"2026-02-20 18:47:33 -0800","tags":["#<Lifer::Tag:0x00007fffdb16d270>"],"language":"en","content_html":"<p>This month was the <span style=\"font-variant: small-caps;\">32<sup>nd</sup>\n</span> occurrence of the <a href=\"https://www.victoriafilmfestival.com\">Victoria Film\nFestival</a> here in Victoria,\nBritish Columbia. It is likely <a href=\"https://cheknews.ca/packed-theatres-mark-record-breaking-victoria-film-festival-1305971/\">the best-selling VFF in the history of the\nfestival</a> and featured ninety-one feature-length films from twenty-five\ncountries. For a small city-like region like Greater Victoria, the festival\noperates at a higher level than we really deserve, despite the criticism\nthat it’s “just” a “greatest hits” of other, larger 2025 film fests. It’s\nthe best VFF that I’ve personally attended, and I think next year is probably\ngonna be even better.</p>\n\n<p>Since I live and work in Victoria and was just living my normal life, I could\nonly attend a handful of (ten) shows in the evenings, but I overheard others\nbragging about seeing twenty—and even thirty—movies over the course of\nthe ten-day event. Do what you will with it: this article is just a rundown\nof the films I saw and how much I’d recommend them. We’re doing nebulous\nstar ratings from between one and four stars\n(i.e. <span aria-label=\"4 out of 4 stars\" class=\"star-rating\">★★★★</span>)\nthat take into account my enjoyment of the work and my enjoyment of the\nfestival screening.</p>\n\n<h2 id=\"sunset\">100 Sunset</h2>\n\n<p><em>Kunsang Kyirong, 2025, Canada</em></p>\n\n<p>A Canadian immigrant story that I personally haven’t seen before, <em>100\nSunset</em> is focused on the Tibetan diaspora in Parkdale, Toronto. Kyirong’s\nquiet directorial debut is bolstered by veteran (as far as I’m concerned)\ncinematographer <a href=\"https://www.nikolaymichaylov.com/\">Nikolay Michaylov</a>’s\neffortless ability to make you feel like you’re in the subject’s head.  It is\nfull of challenging asshole characters and interesting story-decisions.\n<span aria-label=\"2.5 out of 4 stars\" class=\"star-rating\">★★½</span></p>\n\n<h2 id=\"nirvanna-the-band-the-show-the-movie\">Nirvanna the Band the Show the Movie</h2>\n\n<p><em>Matt Johnson, 2025, Canada</em></p>\n\n<p>I went in not having consumed any of <a href=\"https://nirvannathebandthe.show/episodes/#webseries\">the original web\nseries</a> or <a href=\"https://nirvannathebandthe.show/episodes/#tv_show\">the television show</a>. I was\nappeased, as were my friends who <em>love</em> the antecedent content. I really hope\nthat the distributed cut of the movie will also include actual <em>Back to the\nFuture</em> score samples.  If you’re a sucker for time travel, gonzo filmmaking,\nor buddy comedies, you will have a good time.\n<span aria-label=\"3.5 out of 4 stars\" class=\"star-rating\">★★★½</span></p>\n\n<h2 id=\"beautiful-and-neat-room\">Beautiful and Neat Room</h2>\n\n<p><em>Maria Petschnig, 2025, United States</em></p>\n\n<p>An unhinged tale about a working artist who can’t afford her Brooklyn\napartment without short-term renting out her spare room to other people who\ncan’t afford their own Brooklyn apartments. The principal actress, Charlotte\nAubin, makes this work despite some of the dialogue (with a venti-sized\ncast of supporting actors) smelling slightly undercooked. You <em>will</em> leave\nhating every roommate you’ve ever had.  This was the first, and only, film I\nsaw at the makeshift thirtyish-seater cinema-venue Toaster Rocket located\nat <a href=\"https://www.printhole.ca/\">Print Hole</a>. I gotta say, this was a good\nvenue. Maybe even better than the <em>real cinema</em> Screen 5 at the Capitol 6\nwhere <em>100 Sunset</em> screened.<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup>\n<span aria-label=\"2.5 out of 4 stars\" class=\"star-rating\">★★½</span></p>\n\n<h2 id=\"pillion\">Pillion</h2>\n\n<p><em>Harry Lighton, 2025, United Kingdom &amp; Ireland</em></p>\n\n<p>The crowd loved it, and it was heartwarming. This is incredible considering the\nmovie focuses on a BDSM relationship, which is an intense subculture that I’m\npositive ninety percent of the audience, including myself, know nothing about.\nA feat. Experiencing the narrative through the narrow, naive point of view\nof our protagonist, Harry, will remain burned into my long-term memory.\n<span aria-label=\"3 out of 4 stars\" class=\"star-rating\">★★★</span></p>\n\n<h2 id=\"blue-heron\">Blue Heron</h2>\n\n<p><em>Sophy Romvari, 2025, Canada &amp; Hungary</em></p>\n\n<p>Like <em>100 Sunset</em>, this one is another feature-length debut by a Canadian\nwoman-filmmaker. It amazingly, deservedly, has already been acquired for\ndistribution by Janus Films. It’s a semi-autobiographical story about\na Hungarian-Canadian family whose oldest child is struggling with mental\nillness. It brings a sharp, fresh perspective to the banal family tragedy\nmovie we’ve seen many times over, and it incorporates both narrative and\ndocumentary elements in a surprisingly uncomplicated way. Despite the things\nI really didn’t like about it (millenial needle drops; [spoiler redacted]),\nit is probably my number one pick from the festival.\n<span aria-label=\"4 out of 4 stars\" class=\"star-rating\">★★★★</span></p>\n\n<h2 id=\"levers\">Levers</h2>\n\n<p><em>Rhayne Vermette, 2025, Canada</em></p>\n\n<p>I was excited and primed for this, having seen Vermette’s debut feature\n<a href=\"https://en.wikipedia.org/wiki/Ste._Anne_(film)\"><em>Ste. Anne</em></a>\na couple of years ago. This screening was in collaboration\nwith local events promoter and zine-maker <a href=\"https://destroyedcinema.neocities.org/\"><em>Destroyed\nCinema</em></a>. <em>Destroyed</em> programmed this\nscreening to be followed by live music, which rocks. I think this complemented\nthe film a lot. <em>Levers</em> kinda gives you a Guy Madden-high as you follow\ndozens of (almost a hundred?) extras in rural Manitoba during a mysterious\npseudo-apocolyptic solar eclipse, leaving the town in darkness for seemingly a\n<em>very</em> long time. It was purportedly filmed <a href=\"https://www.thestar.com/entertainment/tiff/tiff-2025-this-surreal-canadian-film-was-shot-on-broken-cameras-and-based-on-tarot/article_74f4f2dd-3835-4217-ad16-82665d84a7fe.html\">on broken cameras</a>, though\nI don’t think that stands out as much as it just having a bedroom-filmmaker,\nno-lighting, 1980s made-for-television look. There are also tarot cards\ninvolved.\n<span aria-label=\"4 out of 4 stars\" class=\"star-rating\">★★★★</span></p>\n\n<h2 id=\"rose-of-nevada\">Rose of Nevada</h2>\n\n<p><em>Mark Jenkin, 2025, United Kingdom</em></p>\n\n<p>A perfect follow-up to <em>Levers</em>, <em>Rose of Nevada</em> also looks like a cursed\n1980s television show episode, albeit a bit more crackerjack. The gentility\nof the fishing village setting and warm, vintage look  makes you forget that\nthis is a hard <em>The Twilight Zone</em> episode. By “hard,” I mean good.\n<span aria-label=\"4 out of 4 stars\" class=\"star-rating\">★★★★</span></p>\n\n<h2 id=\"the-blue-trail\">The Blue Trail</h2>\n\n<p><em>Gabriel Mascaro, 2025, Brazil</em></p>\n\n<p>A dystopian-future movie that’s more character than genre, and I appreciate\nthat the character also happens to be a seventy-five year old woman. This\npremise alone gets at something we deserve more of in a time when nearly all of\nour genre movies are about rich people who are played by actors who are rich people\nwho, at some point, have been in a Marvel movie.\n<span class=\"star-rating\">★★★</span></p>\n\n<h2 id=\"a-useful-ghost\">A Useful Ghost</h2>\n\n<p><em>Ratchapoom Boonbunchachoke; 2025; Thailand, France, Singapore &amp; Germany</em></p>\n\n<p>Another directorial debut. I look forward to seeing more films from\nBoonbunchachoke, but unfortunately I gotta be mean about this one. It’s\na black comedy that isn’t very funny and is probably an hour too long. It\nseems to me that there were too many cooks in the production-kitchen, which\nled to a lot of independently interesting story-ingredients being forced into\nan ambitious, professional, but ultimately unseasoned and conventional stew.\n<span aria-label=\"2 out of 4 stars\" class=\"star-rating\">★★</span></p>\n\n<h2 id=\"a-poet\">A Poet</h2>\n\n<p><em>Simón Mesa Soto; 2025; Colombia, Germany &amp; Sweden</em></p>\n\n<p>To me, this feels like a 2000s indie comedy revival movie. It was revitalizing\nto see a two-hour movie about such a pathetic and misguided person with <em>no\njokes</em> in it, but formally this movie has almost nothing going on.\n<span aria-label=\"2 out of 4 stars\" class=\"star-rating\">★★</span></p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>Not a huge compliment, but still. Screen 5, unfortunately, is <em>the\n  worst</em>, smallest, dimly-lit cinema experience you’ll have in the city. You\n  can see and hear the blood orange <em>EXIT</em> signs more easily than you can the\n  movie you’re there to see. <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/weblog/new-website","url":"https://benjaminwil.info/weblog/new-website","external_url":null,"title":"New website","summary":"Today I’m launching my website redesign. I hope that you like it.","image":null,"banner_image":null,"date_published":"2026-01-26 08:20:59 -0800","date_modified":"2026-01-26 08:20:59 -0800","tags":[],"language":"en","content_html":"<p>Today I’m launching my website redesign. I hope that you like it. Comparing\nthe new design to the old one<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup>, my design seems to accidentally commemorate\nthe soft ending of my career as a techincal writer. (I continue to search for\nand take software development roles.) We’ve gone from “bold and friendly” to\n“brutal and web-traditional” as I transformed from curious observer of software\nto grisled maintainer of software. The purple accent is gone and has been\nreplaced with blues and blacks (in light mode) and yellows (in dark mode),\nand the IBM Plex Sans typeface has been replaced by your browser’s default\nserif typeface. For most of you, that’s probably Times New Roman, bread\nnull butter. “Times New Roman,” <a href=\"https://practicaltypography.com/a-brief-history-of-times-new-roman.html\">writes typographer Matthew Butterick</a>,\n“connotes apathy.” While I’d often agree, I wanna ask him if all stoicism is\napathy, then? I hope my redesign broadcasts to readers my pragmaticism and\nconnects me to the ancestral proto-social web where hobbyists and developers\nshared knowledge and experience for free, openly, via HTTP and RSS.</p>\n\n<p>With the redesign comes new pages, as well: <a href=\"/colophon\">the colophon</a>.</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>Here’s <a href=\"https://web.archive.org/web/20230528122559/https://benjaminwil.info/weblog/providence-rhode-island/\">an example webpage archived by Archive.org</a>. <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/weblog/2025-film","url":"https://benjaminwil.info/weblog/2025-film","external_url":null,"title":"The best films I saw: 2025 edition","summary":"As always, in an unranked order, here are the thirty best movies I was able to watch in 2025.","image":null,"banner_image":null,"date_published":"2025-12-31 12:00:00 -0700","date_modified":"2025-12-31 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb713850>"],"language":"en","content_html":"<p>As always, in an unranked order, here are the thirty best movies I was able\nto watch in 2025. This list was also <a href=\"https://letterboxd.com/benjaminwil/list/top-thirty-2025/\">published on Letterboxd</a>.</p>\n\n<p>I don’t think this year’s list is particularly interesting, except in that\nHong Sang-soo has three entries and there are a couple (<em>Aftersun</em>,\n<em>Sexy Beast</em>) directorial debuts in here. If I had to throw these all out\nand pick out only one it’d be Haneke’s <em>Benny’s Video</em>.</p>\n\n<p>Here are links to previous lists: <a href=\"/weblog/2024-film\">2024</a>,\n<a href=\"/weblog/2023-film\">2023</a>, <a href=\"/weblog/2022-film\">2022</a>, <a href=\"/weblog/2021-film\">2021</a>,\n<a href=\"/weblog/2020-film\">2020</a>, <a href=\"/weblog/2019-film\">2019</a>,\n<a href=\"/weblog/2018-film\">2018</a>, <a href=\"/weblog/2017-film\">2017</a>.</p>\n\n<ul>\n  <li>Charlotte Wells: <em>Aftersun</em>, 2022</li>\n  <li>Larry Clark: <em>Another Day in Paradise</em>, 1998</li>\n  <li>Michael Haneke: <em>Benny’s Video</em>, 1992</li>\n  <li>Jack Dunphy: <em>Bob’s Funeral</em>, 2024</li>\n  <li>Hong Sang-soo: <em>By the Stream</em>, 2024</li>\n  <li>Adam Curtis: <em>Can’t Get You Out of My Head</em>, 2021</li>\n  <li>Agnès Varda: <em>Cléo from 5 to 7</em>, 1962</li>\n  <li>Bill Duke: <em>Deep Cover</em>, 1992</li>\n  <li>Sidney Lumet: <em>Dog Day Afternoon</em>, 1975</li>\n  <li>Stanley Kwan Kam-Pang: <em>Full Moon in New York</em>, 1989</li>\n  <li>Tracey Todd: <em>The Flavor of Cassava Leaf Over Rice</em>, 2025</li>\n  <li>Sam Crane, Pinny Grylls: <em>Grand Theft Hamlet</em>, 2024</li>\n  <li>Hong Sang-soo: <em>In Another Country</em>, 2012</li>\n  <li>Leos Carax: <em>It’s Not Me</em>, 2024</li>\n  <li>Clint Eastwood: <em>Juror #2</em>, 2024</li>\n  <li>Werner Herzog: <a href=\"https://en.wikipedia.org/wiki/Lessons_of_Darkness\"><em>Lessons of Darkness</em></a>, 1992</li>\n  <li>Alain Guiraudie: <em>Misericordia</em>, 2024</li>\n  <li>Kelly Reichardt: <em>The Mastermind</em>, 2025</li>\n  <li>Norman Jewison: <em>Moonstruck</em>, 1987</li>\n  <li>Richard Linklater: <em>Nouvelle Vague</em>, 2025</li>\n  <li>Wim Wenders: <a href=\"http://www.cineoutsider.com/reviews/dvd/r/room_666.html\"><em>Room 666</em></a>, 1982</li>\n  <li>Jonathan Glazer: <em>Sexy Beast</em>, 2000</li>\n  <li>Adam Curtis: <a href=\"https://jacobin.com/2025/07/adam-curtis-y2k-blair-mcqueen\"><em>Shifty</em></a>, 2025</li>\n  <li>David Cronenberg: <em>The Shrouds</em>, 2024</li>\n  <li>Kristoffer Borgli: <em>Sick of Myself</em>, 2022</li>\n  <li>Ryan Coogler: <em>Sinners</em>, 2025</li>\n  <li>Boris Lojkine: <em>Souleymane’s Story</em>, 2024</li>\n  <li>Johan Grimonprez: <em>Soundtrack to a Coup d’Etat</em>, 2024</li>\n  <li>Hong Sang-soo: <a href=\"https://thetake-up.com/a-travelers-needs/\"><em>A Traveler’s Needs</em></a>, 2024</li>\n  <li>Tsai Ming-laing: <em>The Wayward Cloud</em>, 2005</li>\n</ul>\n"},{"id":"https://benjaminwil.info/weblog/porto","url":"https://benjaminwil.info/weblog/porto","external_url":null,"title":"Porto, Portugal","summary":"After EuRuKo in Viana do Castelo, I spent some time in Porto.","image":null,"banner_image":null,"date_published":"2025-10-29 18:06:14 -0700","date_modified":"2025-10-29 18:06:14 -0700","tags":["#<Lifer::Tag:0x00007fffdb6e19e0>","#<Lifer::Tag:0x00007fffdb1afee0>"],"language":"en","content_html":"<p>After <a href=\"https://2025.euruko.org\">EuRuKo</a> in <a href=\"/weblog/viana-do-castelo\">Viana do\nCastelo</a>, I spent some time in Porto. In Viana do\nCostelo, some locals said that Porto is not as tourism-oriented as Lisbon.\nIf that’s true, I <em>can’t imagine</em> how tourist-friendly Lisbon must be. I stayed\nnear the historic centre of Porto, and it was quite touristic. The Wikipedia\narticle about Porto has <a href=\"https://en.wikipedia.org/wiki/Porto#Tourism\">a little tourism\nsection</a> with links to articles and\nstudies that indiciate that Porto has been fundamentally changed by an increase\nto tourism over the last twenty years. As a tourist-foreigner there, I can’t\ncomplain: it was an easy place to be a tourist.</p>\n\n<p>Even on the outside of mainstream tourism destinations, Porto caters well to\nforeigners. For example, all of <a href=\"https://cinematrindade.pt\">Cinema Trindade</a>’s\npromotional and advertising materials were crystal clear about which films were\nbeing shown in English or had English subtitles available. Across the street\nfrom Cinema Trindade was a wine bar (<strong>FUNQ</strong>) operated by and filled with Porto\nexpatriates. <a href=\"https://www.batalhacentrodecinema.pt\">Batalha Centro de Cinema</a>, a\nslightly more tourist-oriented cinema and cultural centre, seemed to have one\nAnglo-friendly showing every night of the week.</p>\n\n<p>So Porto was a hospitable, pretty unique, and a very laid back place\nto take a vacation. If you’re going to Porto, I have a few recommendations:</p>\n\n<ul>\n  <li>I already mentioned <strong>The Batalha Centro de Cinema</strong>, which is not only a\ntwo-screen cinema but a cinema bookstore, bar, and gallery. There were posters\nall over the city  for their David Bowie film series which was happening over\nthe course of three or four months. Only having visited here twice, I don’t\nknow the true health of this organization, but it gives me hope that the\ncinema isn’t actually dying. The book shop was special, as I don’t usually see\nso much literature dedicated to film in a single place.</li>\n  <li>The <strong>Guindalense Futebol Clube</strong> is a mostly outdoor pub on the edge of a\ncliff that looks out over the historic Dom Luís I Bridge and Vila Nova de Gaia\nand serves traditional Portuguese hotdogs and sandwiches. It’s a great view\nand a nice, cool place to sit.</li>\n  <li><strong><a href=\"https://www.serralves.pt/en/\">Serralves</a></strong> is a great contemporary art museum.\nThe programming that was on during my visit featured artists from all over the\nworld, but to me the most interesting features were both Portuguese\nfilmmakers. First, the permanant <a href=\"https://www.serralves.pt/en/ciclo-serralves/manoel-de-oliveira-exposicao-permanente/\">Casa do Cinema Manoel de\nOliveira</a>\nroom and theatre, which celebrates the late Porto director and writer. In\naddition to bits of the filmmaker’s personal art collection and a synchronized\nprojection of selected works, there is a video-library wall where visitors can\nwatch entire films and browse information about Oliveira’s filmography.\nSecond, <em><a href=\"https://www.serralves.pt/en/ciclo-serralves/0606-uma-coisa-do-outro-mundo/\">Uma Coisa do Outro\nMundo</a>\n[A Thing From Another World]</em>, a video installation by Jorge Jácome featuring\nfaux-documentary loops featuring disturbing (but funny) military personnel\nencounters with aliens.</li>\n  <li><strong><a href=\"https://www.torto-porto.com/\">Torto</a></strong> is an excellent cocktail bar. If you\nonly go to one, make it this one.</li>\n  <li>If you’re looking for some gentle breakfast or lunch near Cedofeita, go to\n<strong>Hakko</strong>, a tiny lunch place with exceptional specialty coffee, a great plate\nof Turkish eggs, and a great record collection, or <strong>Bicho</strong>, a bright bakery\nand cafḗ just a block away.</li>\n  <li>If you’re still in Cedofeita, go to the <strong>Catraio</strong> beer garden for a huge\nselection of craft beer or <strong>Genuíno</strong> for an effortless family-style dinner\npaired with natural wines.</li>\n  <li>Also in the Cedofeita neighbourhood, <strong><a href=\"https://www.materiaprima.pt/\">Materia\nPrima</a></strong> is my favourite type of book and record\nshop. From their website: “Our interests are broadband, and not focused on any\nparticular aesthetics. We operate with the most expansive and inclusive\ndefinition of culture, and work to make accessible to a widest public, the most\nadventurous, experimental, innovative and sometimes exotic artists, musicians,\nindependent labels and publishers.”</li>\n  <li>Pastel de nata is a pastry that is literally everywhere in Portugal, it seems.\n<strong>Manteigaria</strong> is a chain of bakeries that made the best ones I tried. But\nhonestly, each and every one I had was pretty good.</li>\n</ul>\n"},{"id":"https://benjaminwil.info/weblog/viana-do-castelo","url":"https://benjaminwil.info/weblog/viana-do-castelo","external_url":null,"title":"Viana do Castelo, Portugal","summary":"I was at EuRuKo last month, held in a small city in the Norte Region of Portugal called Viana do Castelo.","image":null,"banner_image":null,"date_published":"2025-10-01 14:02:53 -0700","date_modified":"2025-10-01 14:02:53 -0700","tags":["#<Lifer::Tag:0x00007fffdb6e19e0>","#<Lifer::Tag:0x00007fffdb1afee0>"],"language":"en","content_html":"<p>I was at <a href=\"https://2025.euruko.org\">EuRuKo</a> last month, held in a small city in\nthe Norte Region of Portugal called Viana do Castelo. The conference was held in\nthe Centro Cultural de Viana do Castelo, which is a really open, really\nimpressive events venue and cultural centre built close to mouth of the River\nLima into the Atlantic Ocean.</p>\n\n<p>The word “castelo” translates to “castles,” and, yes, there are many historic\ncastles and castle-like buildings throughout the city and larger Viana do\nCastelo district. If EuRuKo hadn’t been scheduled here, it’s unlikely that I\nwould have ever known to come here, but I’m glad I did.</p>\n\n<p>The fact that everyone front-of-house in the restaurants spoke English\nconfidently also tells me that this <em>is</em> a destination for tourists, especially\nconsidering that this was less true in the other smaller municipalities I visited\nthroughout the Norte Region of Portugal. This is probably also because it’s a\ndestination on the <a href=\"https://en.wikipedia.org/wiki/Camino_de_Santiago\">Camino de\nSantiago</a>. So what I’m trying\nto say is that it was an exceptional place for a foreigner like me to visit for\na couple of days.  If you’re going to visit Viana do Castelo, I can offer a few\nrecommendations:</p>\n\n<ul>\n  <li><strong>Sanctuarium</strong> is a bar and café at the top of the mountain of Santa Luzia, a\nshort walk up from the towering Sanctuary of the Sacred Heart of Jesus.\nThere’s a both a steep staircase and a funicular operated by the Church that\ncan be used to get to the summit. Go to Sanctuarium on a clear day so you can\nsee the city and the water down below. The garden seating here is enviable,\nand many locals had drove up to the top of the mountain to picnic.</li>\n  <li><strong>Pacóvio</strong> is a tiny wine and tapas bar not far from the Centro Cultural. I\nfound no better place to try the regional wine and low-key local food. I think\nit’s owner-operated, with just a single couple running the front-of-house and\nback-of-house by themselves.</li>\n  <li><strong>Peloton Coffee and Cycling</strong> is a chill, slow coffee place if you’re in need\nof specialty coffee.</li>\n  <li><strong>Ribeiro’s Brewers</strong> is a craft beer bar with an always-fresh tap list. When\nI visited, there were plenty small-batch Portuguese, Spanish, and German beers\non the menu, and the staff was pretty excited to talk beer.</li>\n</ul>\n"},{"id":"https://benjaminwil.info/weblog/rails-routing-constraints","url":"https://benjaminwil.info/weblog/rails-routing-constraints","external_url":null,"title":"Catch-all routes and routing constraints in Rails applications","summary":"I’ve worked with more than one Ruby on Rails application that has a catch-all GET route at the end of its config/routes.r...","image":null,"banner_image":null,"date_published":"2025-09-19 08:48:50 +0100","date_modified":"2025-09-19 08:48:50 +0100","tags":[],"language":"en","content_html":"<p>I’ve worked with more than one Ruby on Rails application that has a catch-all\n<code>GET</code> route at the end of its <code>config/routes.rb</code> file:</p>\n\n<pre><code>Rails.application.routes.draw do\n  resources :posts\n  resources :users\n\n  # This route is defined after all other routes as a catch-all.\n  get \"/*path\", to: \"fallbacks#show\"\nend\n</code></pre>\n\n<p>What this means is that there is a <code>FallbacksController</code> that handles any\nrouting that isn’t already handled by previously-defined routes. In this simple\nexample, a path like <code>/posts/123</code>, <code>/posts/doesnt-exist</code>, or <code>/users/brock</code> would\nbe rightly handled by the resource routes that have been defined, but some other\npath like <code>/about</code> or <code>/contact</code> would be routed through\n<code>FallbacksController#show</code>. If the fallbacks controller becomes responsible for\nfiguring out what content the user wants to view <em>or</em> rendering some other page\nlike a 404 page:</p>\n\n<pre><code>class FallbacksController &lt; ApplicationController\n  rescue_from ActiveRecord::RecordNotFound, with: :render_404\n\n  def show\n    # If a page with the given path cannot be found, `#find_by!`\n    # raises an `ActiveRecord::RecordNotFound` exception.\n    @page = Page.find_by!(path: params[:path])\n  end\nend\n</code></pre>\n\n<p>This simple controller action looks the same way many other simple controller\nactions look, where the main difference is that we’re handling requests for any\npath not already handled by other routes. <code>/about</code> would route to our static\npage with a <code>#path</code> attribute of <code>/about</code>. <code>/page-that-doesnt-exist</code> would route\nto a 404.</p>\n\n<h2 id=\"when-a-catch-all-route-accumulates-complexity\">When a catch-all route accumulates complexity</h2>\n\n<p>But the applications I’ve worked on that have implemented a catch-all route like\nthis don’t intend to just serve content for <code>/about</code> or <code>/contact</code> pages. They\nall have implemented the catch-all so that they can present connected groups of\npages that have a tree-like structure, like a taxon tree:</p>\n\n<pre><code>/unisex\n└── /unisex/jeans\n    └── /unisex/jeans/raw\n└── /unisex/tops\n    └── /unisex/tops/oversized\n</code></pre>\n\n<p>And using this taxon tree, they often want to present increasingly filtered-down\ngroups of products for a product listing page.</p>\n\n<p>The Rails applications I’ve worked on that provide this catch-all route have all\nstuffed a lot of complexity into their <code>FallbacksController#show</code> action.</p>\n\n<p>For example, if we decide that some subset of pages should be rendered in some\nother way:</p>\n\n<pre><code>class FallbacksController &lt; ApplicationController\n  JEANS_SECTION = \"/unisex/jeans\"\n  TOPS_SECTION = /unisex/tops\"\n\n  rescue_from ActiveRecord::RecordNotFound, with: :render_404\n\n  def show\n    path = params[:path]\n\n    # If a page with the given path cannot be found, `#find_by!`\n    # raises an `ActiveRecord::RecordNotFound` exception.\n    @page = Page.find_by!(path: params[:path])\n\n    if path.starts_with? JEANS_SECTION\n      render \"jeans_listing\"\n    elsif path.starts_with? TOPS_SECTION\n      render \"tops_listing\"\n    else\n      render \"show\"\n    end\n  end\nend\n</code></pre>\n\n<p>Now, even though we are rendering three different templates, our only dependency\nis a <code>@page</code> record. In this example controller action, the code indicates that\nour pages are basically all the same but can now be presented in three different\nways. In my opinion that’s an acceptable amount of complexity.</p>\n\n<p>But this can get out of hand fast if we want other variations of the product\nlisting pages, or tack on other pages that require a top-level route like\n<code>/about</code> or <code>/contact</code>:</p>\n\n<pre><code>class FallbacksController &lt; ApplicationController\n  GRAVEYARD_CATEGORY = \"graveyard\"\n\n  JEANS_SECTION = \"/unisex/jeans\"\n  TOPS_SECTION = /unisex/tops\"\n\n  STATIC_PAGES = [\"/about\", \"/contact\"]\n\n  rescue_from ActiveRecord::RecordNotFound, with: :render_404\n\n  def show\n    path = params[:path]\n\n    # If a page with the given path cannot be found, `#find_by!`\n    # raises an `ActiveRecord::RecordNotFound` exception.\n    @page = Page.find_by!(path: params[:path])\n\n    # Only include products that have been discontinued.\n    @products =\n      if path.includes?(GRAVEYARD_CATEGORY)\n        Product.where(discontinued_at: ..Time.now, taxons: @page.taxons)\n      else\n        Product.where(taxons: @page.taxons)\n      end\n\n    render_404 and return if (@products.none? &amp;&amp; !STATIC_PAGES.include?(path))\n\n    if STATIC_PAGES.include?(path)\n      render \"static_page\"\n    elsif path.starts_with? JEANS_SECTION\n      render \"jeans_listing\"\n    elsif path.starts_with? TOPS_SECTION\n      render \"tops_listing\"\n    else\n      render \"show\"\n    end\n  end\nend\n</code></pre>\n\n<p>So here we’ve added a lot of functionality to <code>FallbacksController#show</code>.</p>\n\n<ul>\n  <li>the rendering of static pages</li>\n  <li>the rendering of a “product graveyard” for collections of discontinued products</li>\n  <li>the rendering of a 404 page if a collection of <code>@products</code> happens to be empty\nand we’re not trying to render a static page like <code>/about</code>.</li>\n</ul>\n\n<p>Obviously this is a bit contrived; if we actually needed to render all of these\npages from a single controller action, we might restructure it a bit. But\nhopefully this highlights the fact that… this should have always been served\nby many controllers.</p>\n\n<p>Using typical Rails routes, undoing this technical debt could be a considerable\namount of work, though, if we don’t want to break the existing routing. And, of\ncourse, maybe we do have requirements for static pages like the about page: that\nthey are served via <code>/about</code> rather than <code>/some-controller-prefix/about</code>.</p>\n\n<h2 id=\"reducing-complexity-using-routing-constraints\">Reducing complexity using routing constraints</h2>\n\n<p>The least-effort way around the controller action stuffing would be use <a href=\"https://guides.rubyonrails.org/routing.html#advanced-constraints\">routing\ncontraints</a>, which allows us to stop stuffing\nall of this complexity into a single controller action. You can express this\neither as a lamdba or as a class that adheres to <a href=\"https://github.com/rails/rails/blob/v8.0.0/actionpack/lib/action_dispatch/routing/mapper.rb#L29\">Rails’s contraints API</a>:</p>\n\n<pre><code>class PageConstraints\n  # Matches page paths. To be really nice, we'll optionally account for a\n  # slash at the beginning and/or end of the request path. i.e. `about`,\n  # `/about`, `about/`, or `/about/`.\n  PAGE_PATH_REGEXP = %r{\\A/?[^/]*/?\\z}\n\n  def matches?(request) = request.path.match?(PAGE_PATH_REGEXP)\nend\n\nclass GraveyardCategoryConstraints\n  GRAVEYARD_CATEGORY_KEYWORD = \"graveyard\"\n\n  def matches?(request)\n    request.path.match? %r{.+#{GRAVEYARD_CATEGORY_KEYWORD}.*}\n  end\nend\n\nRails.application.routes.draw do\n  resources :posts\n  resources :users\n\n  # Example using a custom constraints lambda.\n  get \"/*path\",\n    contraints: -&gt;(request) {\n      request.path.match?(Product.known_category_prefixes)\n    },\n    to: \"products#show\"\n\n  # Example using a custom constraints class.\n  constraints GraveyardCategoryConstraints.new do\n    get \"/*path\", to: \"graveyard_products#show\"\n  end\n\n  # Example using a custom constraints class.\n  contraints PageConstraints.new do\n    get \"/*path\", to: \"pages#show\"\n  end\n\n  # Aaaaaannd the old fallback route.\n  get \"/*path\", to: \"fallbacks#show\"\nend\n</code></pre>\n\n<p>I won’t include example code for all of the individual controllers, but I hope\nyou can see how splitting the single, monolithic <code>FallbacksController#show</code>\naction into four separate controllers would make each of the actions much more\nmaintainable.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/see-you-at-euruko-2025","url":"https://benjaminwil.info/weblog/see-you-at-euruko-2025","external_url":null,"title":"See you at EuRuKo 2025","summary":"I’ll be at EuRuKo, the European Ruby conference, in Viana do Castelo, Portugal, this month.","image":null,"banner_image":null,"date_published":"2025-09-09 12:15:46 -0700","date_modified":"2025-09-09 12:15:46 -0700","tags":[],"language":"en","content_html":"<p>I’ll be at <a href=\"https://2025.euruko.org/\">EuRuKo</a>, the European Ruby conference, in\nViana do Castelo, Portugal, this month. Maybe I’ll see you there? We could grab\na coffee.</p>\n"},{"id":"https://benjaminwil.info/weblog/typesetting-album-artist-separation","url":"https://benjaminwil.info/weblog/typesetting-album-artist-separation","external_url":null,"title":"Typesetting artist name–album title separation","summary":"Recently I’ve had two occasions to think about how to typeset musical artist names when next to their album release names...","image":null,"banner_image":null,"date_published":"2025-07-30 11:54:45 -0700","date_modified":"2025-07-30 11:54:45 -0700","tags":[],"language":"en","content_html":"<p>Recently I’ve had two occasions to think about how to typeset musical artist\nnames when next to their album release names. I couldn’t find a very\nauthoritative source on the subject, so I’ll offer up my own findings.</p>\n\n<p>For music-related documents and user interfaces, you may sometimes need display\nan artist and album title next to each other. What are reasonable choices for\nseparators? Publications like Pitchfork and applications like Bandcamp, Spotify,\nand Tidal try to side-step this issue by avoiding interface components where\nthese two elements are displayed next to each other.  They instead prefer to put\none above the other on separate lines. That’s a reasonable solution, but let’s\npretend it’s a luxury we don’t have.</p>\n\n<p>Maybe the simplest solution would be to use different font styles for the artist\nand album:</p>\n\n<blockquote>\n  <p>\n    <strong aria-label=\"Artist name\">Lizzy Mercier Desclaux</strong>\n    <span aria-label=\"Album name\">Mambo Nassau</span>\n  </p>\n</blockquote>\n\n<p>Let’s pretend we don’t have this luxury and that we must reach for typesetting\nseparator-characters.</p>\n\n<p>If we want to optimize for easy authorship, we could use colons:</p>\n\n<blockquote>\n  <p>Lizzy Mercier Desclaux: Mambo Nassau</p>\n</blockquote>\n\n<p>However, colons sometimes appear in album titles. Especially if you’re attempting\nto present artist and album titles across many or all musical genres, this might\nnot be the best choice. For some genres, like classical and contemporary art\nmusic recordings, colons might even create ambiguity (or readability issues)\nabout which part is the album and which part is the artist:</p>\n\n<blockquote>\n  <p>Chen Pi-Hsien: Messiaen: 20 Regards sur l’Enfant-Jésus, I-27</p>\n</blockquote>\n\n<p>There are other simple separators like commas and slashes that share this\nambiguity problem. So we want to optimize for disambiguation, using an en- or\nem-dash seems to be safer, at least for now, in 2025:</p>\n\n<blockquote>\n  <p>Lizzy Mercier Desclaux – Mambo Nassau</p>\n</blockquote>\n\n<blockquote>\n  <p>Chen Pi-Hsien – Messiaen: 20 Regards sur l’Enfant-Jésus, I-27</p>\n</blockquote>\n\n<p>Using dashes is also good enough for NME, iTunes, Apple Music, and Discogs to\nseparate artist names from album titles, if that means anything to you. It does\nto me. Except in situations where sub-pixel real estate matters, dashes look\ngood, are good disambiguators, and should be renderable by any font that’s any\ngood.</p>\n\n<p>If you’re considering using a hyphen instead of a dash: please don’t. Hyphens\nfrequently appear in human names and album titles, and would not be a good\nseparator or a smart disambiguator. I’ll admit that even dashes are an unusual\nseparator character. But since they appear so infrequently in this context,\nthey’re a shoo-in. For more information about the difference between hyphens,\nen-dashes, and em-dashes, I recommend <a href=\"https://practicaltypography.com/hyphens-and-dashes.html\">the Butterick’s Practical Typography\narticle about hyphens and\ndashes</a>.</p>\n"},{"id":"https://benjaminwil.info/weblog/github-discussions-suck","url":"https://benjaminwil.info/weblog/github-discussions-suck","external_url":null,"title":"GitHub Discussions is modelled poorly for open-ended conversations","summary":"Note that this article criticizes GitHub’s Discussions feature (originally launched in 2017) as it exists now, in July 20...","image":null,"banner_image":null,"date_published":"2025-07-22 20:12:56 -0700","date_modified":"2025-07-22 20:12:56 -0700","tags":[],"language":"en","content_html":"<p><em>Note that this article criticizes GitHub’s Discussions feature (originally\nlaunched in 2017) as it exists now, in July 2025.</em></p>\n\n<p>In case you don’t know, <a href=\"https://docs.github.com/discussions\">Discussions</a> is\nGitHub’s answer to forums and <a href=\"https://stackoverflow.com/questions\">Stack\nOverflow</a>-style Q&amp;As. Users can reply to an\ninitial message in a discussion and upvote, downvote, or comment on any response.\nIn addition to announcement threads and polls, discussions can either be\n<strong>open-ended discussions</strong> or <strong>question/answer discussions</strong>.</p>\n\n<p>Question/answer discussions:</p>\n\n<ul>\n  <li>can be viewed in one of a few sort orders (top voted first; newest first; oldest first) and</li>\n  <li>can have a single response marked as “the answer” to the discussion.</li>\n</ul>\n\n<p>Open-ended discussions:</p>\n\n<ul>\n  <li>can also be viewed in one of a few sort orders (top voted first; newest first; oldest first) and</li>\n  <li>do not have any response marked as “the answer.”</li>\n</ul>\n\n<p>The Q&amp;A discussions improve upon the Stack Overflow model in an important way:\nthe project itself is the owner of the discussion board. That means that project\nadministrators are hypothetically present, moderating conversations and\ncorrecting potential mis/disinformation.</p>\n\n<h2 id=\"user-interface-deficiencies\">User interface deficiencies</h2>\n\n<p>Unfortunately, unlike the Q&amp;A discussions, the open-ended discussions feature is\nan afterthought in comparison.  Even visually, responses to open-ended\ndiscussions look disconnected from one another. Each response is an island,\nwith borders, primed for its own disparate comments thread.</p>\n\n<figure>\n  <a target=\"_blank\" href=\"/weblog/assets/github-discussions-suck/thread-comparisons-discourse-discussions-issues.png\">\n    <img src=\"/weblog/assets/github-discussions-suck/thread-comparisons-discourse-discussions-issues@0.5.png\" alt=\"Side by side, comments on a Discourse thread, comments on a GitHub discussion, and comments on a GitHub issue, showcasing the user interface of each document.\" />\n  </a>\n  <figcaption>\n    <p>\n      From left to right: comments on Discourse conversation, a GitHub discussion,\n      and a GitHub issue. Of the three, the GitHub discussion stands out as having\n      a visible textarea with placeholder text \"Write a reply\" between two\n      messages meant to be read as replies to each other. It also stands out as\n      visually separating the messages from each other. This design\n      indicates that this isn't a discussion: it's meant to be listing of\n      threads.\n    </p>\n\n    <p>\n      You might have noticed that the Discourse thread I captured actually contains a\n      reply to an earlier message in the thread not shown here. This is a bit\n      complicated, but regardless, the thread is still displayed in chronological\n      message order.\n    </p>\n  </figcaption>\n</figure>\n\n<p>While Discourse threads and GitHub issues both have their own user interface\nchallenges and deficiencies, issues are displayed more like I would personally\nexpect open-ended discussions to be displayed: a single conversation, without\nnested comments, and visually each message in the issue is linked to indicate a\nchronology. Interestingly, issues can be converted into discussions by project\nadministrators–but not the other way around (for reasonable complexity-related\nreasons, I’m sure), though admins can create an issue <em>from</em> a discussion.</p>\n\n<p>As a GitHub repository administrator, you must configure Discussions and the\nproject’s enabled discussion categories. Each category will allow for\ndiscussions of one type (announcements; polls; Q&amp;As; open-ended discussions).\nWhen creating a new discussion category, the default selected mode is\n<strong>question/answer</strong>. In my experience, this really shows.  For example, see\n<a href=\"https://github.com/laravel/framework/discussions/categories/show-and-tell\">Laravel’s “Show and Tell” discussion\ncategory</a>,\nwhich contains hundreds of “unanswered” links and plugs that members of the\nLaravel community may find relevant. No offence to anyone (I’m not a member\nof the Laravel community), but calling these “unanswered” feels like a\nmistake. Given this example, and the visual design of the discussion page, it\nseems clear that GitHub’s designers prioritized the functionality\nof the Q&amp;A-style discussions.</p>\n\n<p>All four discussion types have the exact same threading system, well-suited to\nStack Overflow-like Q&amp;As, and less well-suited for announcements made by project\nmaintainers and open-ended discussions.  For all four discussion types,\nresponses can be upvoted individually and have their own nested comments\nthreads. This specifically makes having an open-ended discussion quite complex:\nopen-ended discussions are now not just open-ended, but also achronological,\nnon-linear, or single-threaded, depending on how nested comments are (ab)used.</p>\n\n<h2 id=\"de-linearizing-conversations\">De-linearizing conversations</h2>\n\n<p>Years ago, I started <a href=\"https://github.com/orgs/solidusio/discussions/4634\">a discussion on the Solidus\nproject</a> to have an\nopen-ended discussion about how to handle a particular issue I was facing\nintegrating with the Solidus framework’s provided frontend templates. There was\nno need for upvotes (or downvotes, thankfully), but all responders ended up\ncommenting on a single response to the thread. The shape of this discussion\nwould have been better suited to a single, flat thread, i.e.:</p>\n\n<pre><code># original post -&gt; [responses]\n\nOriginal Poster   \"Hi, this is a question or comment about The Project.\"\nResponder 1       └── \"Hi, this is a response to the question or comment.\"\nResponder 2       └── \"Hi, this is also a response to the question or comment, but I'm also in conversation with Responder 1, who responded before me.\"\n</code></pre>\n\n<p>rather than the tree structure it ended up as due to the GitHub Discussion’s design\nchoices:</p>\n\n<pre><code># original post -&gt; [response -&gt; [comments]]\n\nOriginal Poster   \"Hi, this is a question or comment about The Project.\"\nResponder 1       └── \"Hi, this is a response to the question or comment.\"\nResponder 2           └── \"Hi, this is also a response to the question or comment, but I'm also in conversation with Responder 1, who responded before me.\"\n</code></pre>\n\n<p>The tree structure makes the otherwise-linear conversation full of potential for\nnon-linearity and complexity. After all, this is purportedly a single discussion.\nImagine what this simple, linear conversation would look like with ten, or\nfifty, more participants.</p>\n\n<p>Perhaps my discussion should have actually been a <a href=\"https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues\">GitHub\nissue</a>\nto begin with. Or, maybe, a message from the discussion should have been used as\nthe source for a new issue. Well, it doesn’t matter. This discussion has long\nbeen abandoned and no action has been directly taken as the result of it. It’s\nmeaningful that issues imply actionability and discussions do not, but I find it\ntroubling that issues prioritize the chronology and linearity of a conversation\nwhile GitHub’s open-ended discussions don’t.</p>\n\n<p>GitHub’s <a href=\"https://github.blog/open-source/maintainers/create-a-home-for-your-community-with-github-discussions/\">announcement blog post for Discussions</a> describes the feature as\n“dedicated space for conversations,” and now, years later, that still feels\nuntrue as I attempt to use these features or read past discussions.\nIt also describes the feature as a way to “create a home for your community,”\ndespite most discussion boards I’ve seen more closely resembling a community\nsupport, Stack Overflow-like Q&amp;A feed.</p>\n\n<h2 id=\"just-using-it-wrong\">“Just using it wrong”</h2>\n\n<p>There is a place for nested conversations. I don’t think the GitHub discussion I\nstarted is one of them. The nested response-comments makes the conversation look\nlike the first responder’s comment is <em>more important</em> than the following\ncomments. The structure and styles of the HTML document tell that story, too.\nAny discussion-readers not participating or reading closely might not understand\nthat all of these messages are in response to the original discussion message\nequally.</p>\n\n<p>You could minimize this by saying discussion participants are not using\nDiscussions “properly.” Hm, but should a responder have to think that hard about\nwhether to respond or comment on a response? Should they have to make this worse\nby accepting a previous commenter or responder’s decision to “use the feature\nwrong”? In the world of Stack Overflow-like Q&amp;As, this complexity makes sense.\nFor an “open-ended discussion” it does not.</p>\n\n<p>GitHub’s own documentation about <a href=\"https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#about-participation-in-a-discussion\">how to participate in a\ndiscussion</a>\nis quite complex:</p>\n\n<blockquote>\n  <ul>\n    <li>Comment in response to the original comment from the author of the discussion</li>\n    <li>Create a comment thread by replying to an individual comment that another\ncommunity member made within the discussion\n<br />…</li>\n    <li>Upvote discussions and top-level comments to give them more visibility</li>\n  </ul>\n</blockquote>\n\n<p>As a way to describe the critical functionality of a message board, these\nparticipation instructions seem complex.  Unfortunately, you can’t just say\n“reply to a thread,” or “contribute a message to the conversation,” because\nthese things aren’t really conversations.</p>\n\n<p>I don’t have much more to say about this other than I don’t think Discussions\nis a good form factor for most real, meaningful discussions, and they\ndefinitely aren’t good at being the primary forum for conversations being had by\nserious free and/or open-source software projects.</p>\n"},{"id":"https://benjaminwil.info/weblog/no-screenshots","url":"https://benjaminwil.info/weblog/no-screenshots","external_url":null,"title":"Prefer text over screenshots","summary":"If you want me to read some text, use your computer’s text-copy commands to provide me with the data rather than taking a...","image":null,"banner_image":null,"date_published":"2025-05-07 21:02:46 -0700","date_modified":"2025-05-07 21:02:46 -0700","tags":["#<Lifer::Tag:0x00007fffdb18e178>"],"language":"en","content_html":"<p>If you want me to read some text, use your computer’s text-copy commands to\nprovide me with the data rather than taking a screenshot. There are a lot of\ngood reasons to do this.</p>\n\n<h2 id=\"screen-size-variability\">Screen size variability</h2>\n\n<p>The sender won’t always know how to format a screenshot so the receiver can read\nit easily. I’m sure that you, too, have pinch-zoomed your way across a wide\nimage on a narrow touchscreen. Pinch-zooming your way across a wide image filled\nwith text can make reading a slow and error-prone process.</p>\n\n<h2 id=\"reliability-and-rediscoverability\">Reliability and rediscoverability</h2>\n\n<p>Raw text content will always be more searchable than images. This allows you and\nothers to rediscover the text when it is useful again later on.</p>\n\n<p>I know that OCR exists and text can be extracted from images and videos in an\nautomated way now. Unfortunately, I know too well that OCR is lossy and can even\nproduce text with comprehensive typos. So, searching for text content from OCRed\nimages cannot be as reliable as raw text content. Yes, even if you throw an LLM\nin at the end to help normalize the OCRed text.</p>\n\n<h2 id=\"text-can-be-translated\">Text can be translated</h2>\n\n<p>It’s true that raw text and OCRed text can both be translated into other\nlanguages. But I’d always feel more confident throwing the raw text into\ntranslation software for the reasons given in my previous point.</p>\n\n<h2 id=\"text-can-be-transformed\">Text can be transformed</h2>\n\n<p>If you want me to read some text, you may also want me to decode, decant, or\nedit the raw text.</p>\n\n<p>Without any specialized software, our computers are still good at text\nediting. Being able to copy text from one application and paste it in another\nis beyond convenient. Not only can you transform the text content, you\ncan transform its display to better see or make sense of it.</p>\n\n<p>Without any specialized software, our computers are not great at duping, editing,\nor processing image content. Having to manually re-copy text from an image or\nvideo is less efficient.</p>\n\n<h2 id=\"text-is-portable\">Text is portable</h2>\n\n<p>Going a bit deeper on that last point: text is more portable than an image. Text\ntakes up less disk space, can be trivially opened by many softwares on many\nsystems. Text can be printed out on even the most rudimentary of printers.</p>\n\n<h2 id=\"why\">Why?</h2>\n\n<p>As a software developer, I often participate in message threads in which someone\nwants to discuss a piece of code or documentation, or a shapeless stack of log\nmessages. Some senders would post a screenshot containing a representation of\nthe text rather than the raw text. I never enjoy this, especially when I’m\nreading from my phone.</p>\n\n<p>There may be real reasons they did this:</p>\n\n<ul>\n  <li>The software being used makes it too difficult to reliably select text\n(cheers, iOS).</li>\n  <li>The software being used makes it too difficult to copy text (cheers, Tmux).</li>\n</ul>\n\n<p>For anyone with these reasons, I recommend finding other software that allows\nyou to more easily select and copy text. Or, I recommend learning the\ndifficult-to-use software’s select- and copy-commands. Or, as a last resort, I\nrecommend recopying manually the text content you wish to send me.</p>\n\n<p>You may be the sender and the text’s secondary reader for now, but in the future\nyou may be the text’s primary reader. Make reading the text easier for yourself.</p>\n"},{"id":"https://benjaminwil.info/weblog/the-shrouds-2024","url":"https://benjaminwil.info/weblog/the-shrouds-2024","external_url":null,"title":"The Shrouds (2024)","summary":"In one of the first scenes, Karsh explains to a date that the GraveTech cemetery he built, where Becca, his Jewish wife, ...","image":null,"banner_image":null,"date_published":"2025-04-30 00:00:00 +0000","date_modified":"2025-04-30 00:00:00 +0000","tags":["#<Lifer::Tag:0x00007fffdb16d270>","#<Lifer::Tag:0x00007fffdb706538>"],"language":"en","content_html":"<p>In one of the first scenes, Karsh explains to a date that the GraveTech\ncemetery he built, where Becca, his Jewish wife, is buried, is a\n“non-denominational” grounds. This isn’t quite the right word considering the\ninter-faith inhabitants of the cemetery. Karsh, a gentile, says that in the\nend he’ll be buried there, next to Becca. This is not the last time in <em>The\nShrouds</em> that Karsh will use an exact, but incorrect, word. As a tech founder,\nit’d be normal for Karsh to misfield words. Many people with CEO-brain are\nnaive to a fault and put boundless trust in the specialists around them. Karsh\ndelegates to his dead wife’s sister’s specialist ex-husband Maury so that\nhe can sleep, drive around in his Tesla, and emote.</p>\n\n<p>It’d also be normal for the specialists and executive-types around him to use\nthe wrong words. And they do, unless in this near-future Canada it’s accurate\nto call one’s AI personal assistant their “avatar.” An avatar is meant to be a\nrepresentation of one’s self. Karsh has no avatar in the film. Although Karsh’s\npersonal assistant Hunny represents him in video calls, she is importantly\nnot Karsh, but a Memoji-esque representation of his late wife created by Maury.</p>\n\n<p>I’m inclined to attribute the wrongful usage of the word “avatar” to\nthe writer-director, who has an immaculate history of making the holiest\nvibes-based cinema. He need not care whether he gets things a little wrong,\nand his work is often more interesting because of what he gets wrong. Then,\nmaybe he also means to say that after death, the manifestation of our loved\nones say more about us than anyone else. We have Cronenberg on record saying\nthat <em>The Shrouds</em> is “autobiographical,” inspired by the loss of his wife\nCarolyn. So Karsh is the avatar, a Cronenberg stand-in, and the Director-Artist\nwho keeps the distorted love-memories alive through his own flawed creations.</p>\n"},{"id":"https://benjaminwil.info/weblog/atom-vs-rss","url":"https://benjaminwil.info/weblog/atom-vs-rss","external_url":null,"title":"Atom vs. RSS","summary":"While working on my static site generator, Lifer, I was occasionally annoyed by how my test feeds were being read by RSS ...","image":null,"banner_image":null,"date_published":"2025-04-05 10:41:32 -0700","date_modified":"2025-04-05 10:41:32 -0700","tags":["#<Lifer::Tag:0x00007fffdb587c70>","#<Lifer::Tag:0x00007fffdb7d3268>"],"language":"en","content_html":"<p>While working on my static site generator,\n<a href=\"https://github.com/benjaminwil/lifer\">Lifer</a>, I was occasionally annoyed by how\nmy test feeds were being read by RSS feed readers. And I was occasionally\nannoyed at the <code>rss</code> Ruby gem source code for generating XML tags in my feeds\nthat I wasn’t explicitly specifying. Chris Wellons’s <a href=\"https://nullprogram.com/blog/2013/09/23/\">Atom vs. RSS</a> blog\npost expresses the same feelings of surprise I felt when digging deeper into the\nancient history that is the Atom and RSS 2.0 specifications.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/ported-to-lifer","url":"https://benjaminwil.info/weblog/ported-to-lifer","external_url":null,"title":"This website has been ported to Lifer 0.9","summary":"Since releasing Lifer 0.3 in January I’ve released six more minor versions to get the project stable enough to start usin...","image":null,"banner_image":null,"date_published":"2025-04-05 10:03:19 -0700","date_modified":"2025-04-05 10:03:19 -0700","tags":["#<Lifer::Tag:0x00007fffdb5694f0>","#<Lifer::Tag:0x00007fffdb906ec8>"],"language":"en","content_html":"<p>Since releasing <a href=\"/weblog/lifer-0-3/\">Lifer 0.3 in January</a> I’ve released six\nmore minor versions to get the project stable enough to start using. <a href=\"https://github.com/benjaminwil/lifer/blob/v0.9.0/CHANGELOG.md\">The\nchangelog entries</a> don’t make the releases sound that interesting,\nbut as an end user I’m much happier with the build performance, the tag support,\nand Lifer’s awareness of original publication <em>and</em> last updated dates.</p>\n\n<div class=\"feed-only\">\n  <small> Note to readers subscribed via a newsfeed: sorry if the feed has\n  spammed you with new entries spanning the many years of this blog's existence.\n  My Jekyll feed's settings were bad, and it seemed not worth it to me to make\n  the feed's transition any more graceful. </small>\n</div>\n\n<p>benjaminwil.info looks and feels the same way it always did, but it’s no longer\nbeing generated by <a href=\"https://jekyllrb.com\">Jekyll</a>–but by Lifer. There’s still\nplenty to do before I could cut a v1.</p>\n\n<p>Lifer definitely has swerved out of the <em>Jekyll clone</em> lane into the <em>could be a\ngood and unique site generator someday</em> lane, and I’m excited about some upcoming\nfeatures that make it even more flexible for people who are willing to commit\na bit of Ruby to their site repository.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/for-rails-newbies","url":"https://benjaminwil.info/weblog/for-rails-newbies","external_url":null,"title":"From developer to Rails developer","summary":"In 2023, I wrote this guide to getting familiar with Ruby and Rails for my employer, Super Good Software.","image":null,"banner_image":null,"date_published":"2025-02-11 09:00:00 -0700","date_modified":"2025-02-11 09:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb18e178>"],"language":"en","content_html":"<p>In 2023, I wrote <a href=\"https://supergood.software/from-developer-to-rails-developer-and-then-some/\">this guide to getting familiar with Ruby and Rails</a> for my\nemployer, <a href=\"https://super.gd\">Super Good Software</a>. In 2025, I wouldn’t change\nmuch too much about this article, which, I think, is a testiment to how mature\nand <em>developer experience-focused</em> the Ruby and Rails ecosystems are.</p>\n\n<p>But I would stop recommending <a href=\"https://pry.github.io/\">the Pry REPL</a> now. In\n2025, even the oldest supported version of Ruby now includes an enhanced IRB\nthat provides many of the features I used to depend on Pry for. One can simply\ninstall <a href=\"https://github.com/ruby/debug\">the <code>debug</code> gem</a> to get even more\nPry-like behaviours from IRB.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/lifer-0-3","url":"https://benjaminwil.info/weblog/lifer-0-3","external_url":null,"title":"Lifer 0.3","summary":"I recently released 0.3.0 of my static site generator project Lifer, which I intend to use to build this website in the (...","image":null,"banner_image":null,"date_published":"2025-01-05 13:14:00 -0700","date_modified":"2025-01-05 13:14:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb5694f0>","#<Lifer::Tag:0x00007fffdb906ec8>"],"language":"en","content_html":"<p>I recently released 0.3.0 of my static site generator project\n<a href=\"https://github.com/benjaminwil/lifer\">Lifer</a>, which I intend to use to build\nthis website in the (near) future. Right now, I build this website using\n<a href=\"https://jekyllrb.com\">Jekyll</a>, the “simple, blog-aware” static site generator.</p>\n\n<p>Lifer and Jekyll have some things in common. For example, they’re both written\nin Ruby, and they both output HTML documents and RSS feeds to an output\ndirectory. They both read frontmatter metadata from Markdown files to help you\nmaintain collections of pages and blog posts that belong to a small- or\nmedium-sized website.</p>\n\n<p>Jekyll has done me no wrong, but there are things about Jekyll I have found\nopinionated or hard to work around: Jekyll requires you to use Liquid templates\nfor generating posts and pages; <code>_posts</code> is a bit too magic a collection of\narticles; its built-in asset pipeline is not very flexible.</p>\n\n<p>It seemed like a good opportunity for me to try designing my own site generator,\nto see how simple I could make something I could use for myself, and to learn\nfirst-hand where all of the hidden complexity lies.</p>\n\n<p>Now, 150-ish commits in, the shape of the site generator I want is coming\ntogether. I started this project, casually, over two years ago. So, at this\nrate, it’ll be a long time before anyone else can actually use Lifer. Testing\nthe generator in production, though, will be quite a milestone. Stay tuned.</p>\n"},{"id":"https://benjaminwil.info/weblog/2024-film","url":"https://benjaminwil.info/weblog/2024-film","external_url":null,"title":"The best films I saw: 2024 edition","summary":"In no particular order, here’s my annual list of the movies I loved that I saw for the first time in 2024.","image":null,"banner_image":null,"date_published":"2024-12-31 12:00:00 -0700","date_modified":"2024-12-31 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb713850>"],"language":"en","content_html":"<p>In no particular order, here’s my annual list of the movies I loved that I saw\nfor the first time in 2024. This year, I included two limited series as entries,\nwhich is a bit unusual of me. This list is also <a href=\"https://letterboxd.com/benjaminwil/list/top-thirty-2024/\">published on\nLetterboxd</a>.</p>\n\n<p>Here’s links to my previous years’s lists: <a href=\"/weblog/2023-film\">2023</a>,\n<a href=\"/weblog/2022-film\">2022</a>, <a href=\"/weblog/2021-film\">2021</a>, <a href=\"/weblog/2020-film\">2020</a>,\n<a href=\"/weblog/2019-film\">2019</a>, <a href=\"/weblog/2018-film\">2018</a>, <a href=\"/weblog/2017-film\">2017</a>.</p>\n\n<p>This year’s list:</p>\n\n<ul>\n  <li>Hong Sang-soo: <em>The Woman Who Ran</em>, 2020</li>\n  <li>William Friedkin: <em>The Caine Mutiny Court-Martial</em>, 2023</li>\n  <li>Théo Jollet: <em>Meet Doug</em>, 2021</li>\n  <li>Hong Sang-soo: <em>Nobody’s Daughter Haewon</em>, 2013</li>\n  <li>Tsai Ming-liang: <em><a href=\"https://www.filmcomment.com/blog/film-of-the-week-rebels-of-the-neon-god/\">Rebels of the Neon God</a></em>, 1992</li>\n  <li>Ryûsuke Hamaguchi: <em><a href=\"https://www.newyorker.com/culture/the-current-cinema/the-beautifully-unnerving-gaze-of-evil-does-not-exist\">Evil Does Not Exist</a></em>, 2023</li>\n  <li>Robert Altman: <em>The Player</em>, 1992</li>\n  <li>Paul Schrader: <em>Hardcore</em>, 1979</li>\n  <li>Luca Guadagnino: <em>Challengers</em>, 2024</li>\n  <li>Harris Mayersohn: <em>Stand Up Solutions</em>, 2024</li>\n  <li>Bernard Rose: <em><a href=\"https://www.rogerebert.com/reviews/ivans-xtc-2002\">ivans xtc.</a></em>, 2000</li>\n  <li>Albert Serra: <em>Pacifiction</em>, 2022</li>\n  <li>Léa Mysius: <em>The Five Devils</em>, 2022</li>\n  <li>Bill Ross IV &amp; Turner Ross: <em><a href=\"https://www.voxmagazine.com/arts/45365-true-false-2020/article_a02b0d76-5f33-11ea-ace0-937f6e7a9225.html\">45365</a></em>, 2009</li>\n  <li>Bill Ross IV &amp; Turner Ross: <em>Tchoupitoulas</em>, 2012</li>\n  <li>Abbas Kiarostami: <em>Where Is the Friend’s House?</em>, 1987</li>\n  <li>Paolo Sorrentino: <em>The New Pope</em>, 2020</li>\n  <li>Elaine May: <em><a href=\"https://www.newyorker.com/goings-on-about-town/movies/mikey-and-nicky-2\">Mikey and Nicky</a></em>, 1976</li>\n  <li>Krzysztof Kieślowski: <em>Three Colours: Blue</em>, 1993</li>\n  <li>Éric Rohmer: <em>A Tale of Springtime</em>, 1990</li>\n  <li>Matthew Rankin: <em><a href=\"https://www.bfi.org.uk/sight-and-sound/reviews/universal-language-beautifully-absurd-crosscultural-odyssey\">Universal Language</a></em>, 2024</li>\n  <li>Miguel Gomes : <em><a href=\"https://mubi.com/en/notebook/posts/all-is-full-of-grace-miguel-gomes-on-grand-tour\">Grand Tour</a></em>, 2024</li>\n  <li>Sean Baker: <em>Anora</em>, 2024</li>\n  <li>Francis Ford Coppola: <em>Megalopolis</em>, 2024</li>\n  <li>Ira Sachs: <em>Forty Shades of Blue</em>, 2005</li>\n  <li>Payal Kapadia: <em><a href=\"https://roughcutfilm.com/2024/08/21/review-all-we-imagine-as-light-is-a-stunning-tale-of-intimacy-as-dissent/\">All We Imagine as Light</a></em>, 2024</li>\n  <li>Steven Zaillian: <em>Ripley</em>, 2024</li>\n  <li>Krzysztof Kieślowski: <em>Three Colours: White</em>, 1994</li>\n  <li>Hong Sang-soo: <em><a href=\"https://www.criterion.com/current/posts/7406-hong-sangsoo-s-tale-of-cinema\">Tale of Cinema</a></em>, 2005</li>\n  <li>Wim Wenders: <em>Perfect Days</em>, 2023</li>\n</ul>\n"},{"id":"https://benjaminwil.info/weblog/2023-film","url":"https://benjaminwil.info/weblog/2023-film","external_url":null,"title":"The best films I saw: 2023 edition","summary":"As usual: here’s my annual list of the thirty best movies I watched for the first time this year.","image":null,"banner_image":null,"date_published":"2023-12-31 12:00:00 -0700","date_modified":"2023-12-31 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb713850>"],"language":"en","content_html":"<p>As usual: here’s my annual list of the thirty best movies I watched for the\nfirst time this year. In no particular order. I also publish it <a href=\"https://letterboxd.com/benjaminwil/list/top-thirty-2023/\">on\nLetterboxd</a>.</p>\n\n<p>I’ve been doing this for a while now, so here are some convenience links to\nprevious lists: <a href=\"/weblog/2022-film\">2022</a>, <a href=\"/weblog/2021-film\">2021</a>,\n<a href=\"/weblog/2020-film\">2020</a>, <a href=\"/weblog/2019-film\">2019</a>, <a href=\"/weblog/2018-film\">2018</a>,\n<a href=\"/weblog/2017-film\">2017</a>.</p>\n\n<p>And now, the list:</p>\n\n<ul>\n  <li>Ryûsuke Hamaguchi: <em><a href=\"https://cinema-scope.com/features/brief-encounters-hamaguchi-ryusukes-wheel-of-fortune-and-fantasy/\">Wheel of Fortune and Fantasy</a></em>, 2021</li>\n  <li>Abel Ferrara: <em>Bad Lieutenant</em>, 1992</li>\n  <li>Sofia Coppola: <em>Priscilla</em>, 2023</li>\n  <li>Hal Hartley: <em>The Unbelievable Truth</em>, 1989</li>\n  <li>William Peter Blatty: <em>The Exorcist III</em>, 1990</li>\n  <li>Dustin Guy Defa: <a href=\"https://www.highonfilms.com/editing-2021-short-film-review-mubi/\"><em>Editing</em></a>, 2021</li>\n  <li>Hal Hartley: <a href=\"https://variety.com/2001/film/reviews/no-such-thing-1200468350/\"><em>No Such Thing</em></a>, 2001</li>\n  <li>Michael Haneke: <em>Funny Games</em>, 1997</li>\n  <li>George Miller: <em>Three Thousand Years of Longing</em>, 2022</li>\n  <li>Olivier Assayas: <em>Clouds of Sils Maria</em>, 2014</li>\n  <li>Abel Ferrara: <em>The Blackout</em>, 1997</li>\n  <li>Hong Sang-soo: <em>Claire’s Camera</em>, 2017</li>\n  <li>Abel Ferrara: <em>King of New York</em>, 1990</li>\n  <li>Jim Jarmusch: <em>Paterson</em>, 2016</li>\n  <li>Eugene Kotlyarenko: <em>A Wonderful Cloud</em>, 2015</li>\n  <li>Michael Haneke: <a href=\"https://deepfocusreview.com/definitives/cache/\"><em>Caché</em></a>, 2005</li>\n  <li>Kelly Reichardt: <em>First Cow</em>, 2019</li>\n  <li>Stanley Kubrick: <em>Barry Lyndon</em>, 1975</li>\n  <li>Ridley Scott: <em>The Last Duel</em>, 2021</li>\n  <li>Tsai Ming-liang: <em>The Skywalk Is Gone</em>, 2002</li>\n  <li>Larry Clark: <a href=\"https://i-d.vice.com/en/article/7kv7n9/bully-larry-clark-cast-interview\"><em>Bully</em></a>, 2001</li>\n  <li>Kelly Reichardt: <em>Showing Up</em>, 2022</li>\n  <li>Sebastián Silva: <a href=\"https://www.bfi.org.uk/sight-and-sound/reviews/rotting-sun-this-shapeshifting-queer-comedy-unsparing-its-barbs\"><em>Rotting in the Sun</em></a>, 2023</li>\n  <li>Michael Mann: <em>Thief</em>, 1981</li>\n  <li>George Sluizer: <em><a href=\"https://www.theringer.com/movies/2018/9/5/17819076/the-vanishing-streaming-movie-influence\">The Vanishing</a></em>, 1988</li>\n  <li>Tom Noonan: <em>What Happened Was…</em>, 1994</li>\n  <li>Janicza Bravo: <em>House Comes with a Bird</em>, 2022 <a href=\"https://www.miumiu.com/us/en/miumiu-club/womens-tales/womens-tales-23.html\">🎥</a></li>\n  <li>George Armitage: <em>Miami Blues</em>, 1990</li>\n  <li>Robert Altman: <em>3 Women</em>, 1977</li>\n  <li>John Patton Ford: <em>Emily the Criminal</em>, 2022</li>\n</ul>\n\n"},{"id":"https://benjaminwil.info/weblog/2022-film","url":"https://benjaminwil.info/weblog/2022-film","external_url":null,"title":"The best films I saw: 2022 edition","summary":"In 2022 I watched some movies for the first time, as I do every year.","image":null,"banner_image":null,"date_published":"2023-01-01 12:00:00 -0700","date_modified":"2023-01-01 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb713850>"],"language":"en","content_html":"<p>In 2022 I watched some movies for the first time, as I do every year. And these\nare the thirty<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup> that were the best, most interesting, etc.:</p>\n\n<ul>\n  <li>Tsai Ming-liang: <em>Vive L’Amour</em>, 1994</li>\n  <li>Amalia Ulman: <em>El Planeta</em>, 2021</li>\n  <li>Pier Paolo Pasolini: <em>Teorema</em>, 1968</li>\n  <li>Spike Lee: <em>Jungle Fever</em>, 1991</li>\n  <li>Pier Paolo Pasolini, Vittorio De Sica, Luchino Visconti, Franco Rossi, Mauro Bolognini: <em>The Witches</em>, 1967</li>\n  <li>Mariano Llinás: <a href=\"https://en.wikipedia.org/wiki/La_Flor\"><em>La Flor</em></a>, 2018</li>\n  <li>David Cronenberg: <em>Crimes of the Future</em>, 2022</li>\n  <li>Radu Jude: <em>Bad Luck Banging or Loony Porn</em>, 2021</li>\n  <li>Akira Kurosawa: <em>Seven Samurai</em>, 1954</li>\n  <li>Sophy Romvari: <em>Grandma’s House</em>, 2018</li>\n  <li>Paul Thomas Anderson: <em>Licorice Pizza</em>, 2021</li>\n  <li>William Friedkin: <em>The French Connection</em>, 1971</li>\n  <li>S. S. Rajamouli: <em>RRR</em>, 2022</li>\n  <li>Shirley Clarke: <em>Portrait of Jason</em>, 1967</li>\n  <li>Joachim Trier: <em>The Worst Person in the World</em>, 2021</li>\n  <li>Rhayne Vermette: <a href=\"https://mubi.com/notebook/posts/an-impossible-being-rhayne-vermette-discusses-ste-anne\"><em>Ste. Anne</em></a>, 2021</li>\n  <li>Sofia Bohdanowicz: <em>Never Eat Alone</em>, 2016</li>\n  <li>Edgar Morin, Jean Rouch: <em>Chronicle of a Summer</em>, 1961</li>\n  <li>Jane Schoenbrun: <em>We’re All Going to the World’s Fair</em>, 2021</li>\n  <li>Steven Soderbergh: <em>Schizopolis</em>, 1996</li>\n  <li>Wendell B. Harris, Jr.: <a href=\"https://en.wikipedia.org/wiki/Chameleon_Street\"><em>Chameleon Street</em></a>, 1989</li>\n  <li>J. Lee Thompson: <em>Conquest of the Planet of the Apes</em>, 1972</li>\n  <li>Ti West: <em>Pearl</em>, 2022</li>\n  <li>Derek Jarman: <em>Blue</em>, 1993</li>\n  <li>Sofia Bohdanowicz: <a href=\"https://en.wikipedia.org/wiki/Maison_du_Bonheur\"><em>Maison du Bonheur</em></a>, 2017</li>\n</ul>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>I’m counting <a href=\"https://en.wikipedia.org/wiki/La_Flor\"><em>La Flor</em></a> as five movies because it’s 808 minutes long.\n  Each year I try to get to a list of thirty, and some years it’s hard to. And\n  this is one of those years. <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/weblog/providence-rhode-island","url":"https://benjaminwil.info/weblog/providence-rhode-island","external_url":null,"title":"Providence, RI","summary":"I was in Providence, Rhode Island, for RubyConf Mini and had the opportunity to eat and drink at some amazing places.","image":null,"banner_image":null,"date_published":"2022-12-02 11:40:00 -0700","date_modified":"2022-12-02 11:40:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb6e19e0>","#<Lifer::Tag:0x00007fffdb1afee0>"],"language":"en","content_html":"<p>I was in Providence, Rhode Island, for <a href=\"/weblog/rubyconf-mini\">RubyConf Mini</a> and had the\nopportunity to eat and drink at some amazing places. If you’re going to\nvisit Providence, I can give you the following recommendations:</p>\n\n<ul>\n  <li><a href=\"https://oberlinrestaurant.com/\">Oberlin</a>: Well-executed (!!) restaurant and bar. Try the raw bar. Try\nthe pasta. Try the toast. Walk in early, or make a reservation.</li>\n  <li><a href=\"https://www.fortnightpvd.com/\">Fortnight</a>: Workers’s cooperative wine bar. Unpretentious. Cared\nfor. Excellent wine and amaros menu (especially for someone coming from the\nwest coast of Canada).</li>\n  <li><a href=\"https://havenbrothersmobile.com/\">Haven Brothers</a>: A long-time institution. Go inside to see how to\nfit a full kitchen inside a horse trailer, stay for a stupid hot dog.</li>\n  <li><a href=\"https://www.marcelinosboutiquebar.com/\">Marcelino’s</a>: An unusual hotel bar. Great mediterranean-inspired\ncocktail menu.</li>\n  <li><a href=\"https://www.eddybar.com/\">eddy</a>: Thoughtful collection of wine, spirits, cocktails, and\ncharcuterie. Definitely worth going here more than once.</li>\n  <li><a href=\"https://as220.org/\">AS220</a>: A non-profit arts centre with a bar and live events, with\nlots of history. <a href=\"https://en.wikipedia.org/wiki/AS220\">It’s got a Wikipedia page</a>.</li>\n  <li><a href=\"http://pckrl.com/\">Pickerel</a>: A tiny ramen bar. Interesting appetizers, drinks, and\ndesserts. It seems like the people working there enjoy working there. While\nyou’re in the neighbourhood: explore Luongo Square. If you’re waiting for\na seat at the bar, go across the square to <a href=\"https://averyprovidence.com/\">The Avery</a> while you wait.</li>\n</ul>\n\n"},{"id":"https://benjaminwil.info/weblog/rubyconf-mini","url":"https://benjaminwil.info/weblog/rubyconf-mini","external_url":null,"title":"RubyConf Mini","summary":"I attended RubyConf Mini in Providence, Rhode Island. If I met you there: it was a pleasure to have met you.","image":null,"banner_image":null,"date_published":"2022-11-26 12:54:53 -0700","date_modified":"2022-11-26 12:54:53 -0700","tags":["#<Lifer::Tag:0x00007fffdb6d57d0>","#<Lifer::Tag:0x00007fffdb18e178>"],"language":"en","content_html":"<p>I attended <a href=\"https://rubyconfmini.com\">RubyConf Mini</a> in Providence, Rhode Island. If I\nmet you there: it was a pleasure to have met you. This conference was a\nplanned-last-minute conference, relative to its partner conference,  RubyConf,\nin Austin. Their plan was to create much smaller, two-track conference for\nanyone unwilling or unable to go to Austin.</p>\n\n<p>If the conference happens again next year, and you’re at all interested in\nthe Ruby programming language, I would recommend attending.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/777","url":"https://benjaminwil.info/weblog/777","external_url":null,"title":"777","summary":"Recently I released an EP 777. You can stream it or purchase it on Bandcamp.","image":null,"banner_image":null,"date_published":"2022-06-01 11:37:53 -0700","date_modified":"2022-06-01 11:37:53 -0700","tags":["#<Lifer::Tag:0x00007fffdb753298>","#<Lifer::Tag:0x00007fffdb752cf8>"],"language":"en","content_html":"<p>Recently I released an EP <em>777</em>. You can stream it or purchase it <a href=\"https://bwbw.bandcamp.com/album/777\">on\nBandcamp</a>.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/2021-film","url":"https://benjaminwil.info/weblog/2021-film","external_url":null,"title":"The best films I saw: 2021 edition","summary":"As usual: here are thirty films, that I liked or thought were good, that I watched for the first time this year.","image":null,"banner_image":null,"date_published":"2021-12-31 12:00:00 -0700","date_modified":"2021-12-31 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb713850>"],"language":"en","content_html":"<p>As usual: here are thirty films, that I liked or thought were good, that I\nwatched for the first time this year. In no particular order.</p>\n\n<ul>\n  <li>Éric Rohmer: <em>Six in Paris</em>,                            1965</li>\n  <li>Angela Schanelec: <em>I Was at Home, But…</em>,                2019</li>\n  <li>Geneviève Dulude-De Celles: <em>A Colony</em>,                 2018</li>\n  <li>Pedro Costa: <em>Vitalina Varela</em>,                         2019</li>\n  <li>Jackie Chan: <em>Police Story</em>,                            1985</li>\n  <li>Sean Baker: <em>Starlet</em>,                                  2012</li>\n  <li>Robert Altman: <em>California Split</em>,                      1974</li>\n  <li>Éric Rohmer: <em>Rendezvous in Paris</em>,                     1995</li>\n  <li>Spike Lee: <em>Bamboozled</em>,                                2000</li>\n  <li>Thomas Vinterberg: <em>Another Round</em>,                     2020</li>\n  <li>Éric Rohmer: <em>Sign of the Lion</em>,                        1962</li>\n  <li>Juzo Itami: <em>Tampopo</em>,                                  1985</li>\n  <li>Stanley Kubrick: <em>Eyes Wide Shut</em>,                      1999</li>\n  <li>Pietro Marcello: <em>Martin Eden</em>,                         2019</li>\n  <li>Nicolas Winding Refn: <em>Fear X</em>,                         2003</li>\n  <li>Solange Knowles: <em>When I Get Home</em>,                     2019</li>\n  <li>Kevin Jerome Everson: <em>Park Lanes</em>,                     2015</li>\n  <li>The Wachowskis: <em>Bound</em>,                                1996</li>\n  <li>Wes Craven: <em>Scream</em>,                                   1996</li>\n  <li>Spike Lee: <em>Da 5 Bloods</em>,                               2020</li>\n  <li>Apichatpong Weerasethakul: <a href=\"https://www.youtube.com/watch?v=8Hk4zepxyoE\"><em>Blue</em></a>,              2017</li>\n  <li>Tony Kaye: <em>American History X</em>,                        1998</li>\n  <li>Tsai Ming-liang: <a href=\"https://www.filmcomment.com/blog/film-week-afternoon-tsai-ming-liang/\"><em>Afternoon</em></a>,                   2015</li>\n  <li>Robin Hardy: <em>The Wicker Man</em>,                          1973</li>\n  <li>Leos Carax: <em>Annette</em>,                                  2021</li>\n  <li>James Wan: <em>Malignant</em>,                                 2021</li>\n  <li>Jean-Luc Godard: <em>First Name: Carmen</em>,                  1983</li>\n  <li>Corneliu Porumboiu: <em>Infinite Football</em>,                2018</li>\n  <li>John Maringouin: <em>Ghostbox Cowboy</em>,                     2018</li>\n  <li>Dasha Nekrasova: <em>The Scary of Sixty-First</em>,            2021</li>\n</ul>\n\n"},{"id":"https://benjaminwil.info/weblog/now-a-gollum-organization-member","url":"https://benjaminwil.info/weblog/now-a-gollum-organization-member","external_url":null,"title":"Now a Gollum organization member","summary":"Earlier this year, I was invited to join the Gollum organization after making some contributions to the main Gollum repos...","image":null,"banner_image":null,"date_published":"2021-11-02 19:04:00 -0700","date_modified":"2021-11-02 19:04:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb18e178>"],"language":"en","content_html":"<p>Earlier this year, I was invited to join the <a href=\"https://github.com/gollum\">Gollum organization</a> after\nmaking some contributions to the <a href=\"https://github.com/gollum/gollum\">main Gollum repository</a>. I’ve been\nparticipating by triaging incoming issues and bug reports, reviewing pull\nrequests, and contributing changes to improve the Gollum user experience for\nmobile users.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/no-longer-there","url":"https://benjaminwil.info/weblog/no-longer-there","external_url":null,"title":"No longer there","summary":"I released an EP called No longer there. You can stream it or purchase it on Bandcamp.","image":null,"banner_image":null,"date_published":"2021-07-07 09:00:00 -0700","date_modified":"2021-07-07 09:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb753298>","#<Lifer::Tag:0x00007fffdb752cf8>"],"language":"en","content_html":"<p>I released an EP called <em>No longer there</em>. You can stream it or purchase it <a href=\"https://bwbw.bandcamp.com/album/no-longer-there\">on\nBandcamp</a>.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/treatise-on-luck","url":"https://benjaminwil.info/weblog/treatise-on-luck","external_url":null,"title":"Treatise on Luck","summary":"Mark Francis Johnson’s Treatise on Luck is a book of poems that investigates luck: where it comes from, where it goes, an...","image":null,"banner_image":null,"date_published":"2021-01-31 12:00:00 -0700","date_modified":"2021-01-31 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb7d36f0>","#<Lifer::Tag:0x00007fffdb7d3268>"],"language":"en","content_html":"<p>Mark Francis Johnson’s <a href=\"https://www.gauss-pdf.com/post/162628927505/gpdf238gpdfe027-mark-francis-johnson-treatise\"><em>Treatise on Luck</em></a> is a book of poems that\ninvestigates luck: where it comes from, where it goes, and where it isn’t. It’s\na book from <a href=\"https://gauss-pdf.com\">Gauss PDF</a>, a digital publisher I am interested in.</p>\n\n<p>From the book:</p>\n\n<blockquote>\n  <p>The grooming staple I’m never without is<br />\nXD’s Eau Sauvage. It was the first fragrance<br />\nI drank when I was young. In a way, it was<br />\nmy first love. I am not sure if I’d still drink it<br />\nfor the love I felt for it back then or the<br />\nfragrance itself, or for luck. It’s nostalgic.</p>\n</blockquote>\n\n"},{"id":"https://benjaminwil.info/weblog/2020-film","url":"https://benjaminwil.info/weblog/2020-film","external_url":null,"title":"The best films I saw: 2020 edition","summary":"A marked improvement in my film consumption since 2019. The following list is thirty films long.","image":null,"banner_image":null,"date_published":"2020-12-31 12:00:00 -0700","date_modified":"2020-12-31 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb713850>"],"language":"en","content_html":"<p>A marked improvement in my film consumption since 2019. The following list is\nthirty films long. All films I saw for the first time in 2020.</p>\n\n<ul>\n  <li>Alejandro Landes:          <em>Monos</em>,                   2019</li>\n  <li>Marcell Iványi:            <em>Wind</em>,                    1996</li>\n  <li>Éric Rohmer:               <em>My Night at Maud’s</em>,      1969</li>\n  <li>Sofia Bohdanowicz:         <a href=\"https://cinema-scope.com/cinema-scope-online/tiff-2020-point-and-line-to-plane-sofia-bohdanowicz-canada/\"><em>Point and Line to Plane</em></a>, 2020</li>\n  <li>Federico Fellini:          <em>I Vitelloni</em>,             1953</li>\n  <li>Jean-Luc Godard:           <em>Tout Va Bien</em>,            1972</li>\n  <li>Louis Malle:               <em>My Dinner with Andre</em>,    1981</li>\n  <li>Jim Jarmusch:              <em>Night on Earth</em>,          1991</li>\n  <li>Jodie Mack:                <a href=\"https://mubi.com/notebook/posts/jodie-mack-introduces-her-film-the-grand-bizarre\"><em>The Grand Bizarre</em></a>, 2018</li>\n  <li>Pablo Larraín:             <em>Ema</em>,                     2019</li>\n  <li>Olivier Assayas:           <em>Carlos</em>,                  2010</li>\n  <li>Crystal Moselle:           <em>Skate Kitchen</em>,           2018</li>\n  <li>Kazik Radwanski:           <em>Anne at 13,000 ft</em>,       2019</li>\n  <li>Raoul Peck:                <em>I Am Not Your Negro</em>,     2016</li>\n  <li>Nicolas Winding Refn:      <em>Pusher</em>,                  1996</li>\n  <li>Terrence Malick:           <em>Days of Heaven</em>,          1978</li>\n  <li>Spike Lee:                 <em>Malcolm X</em>,               1992</li>\n  <li>François Truffaut:         <em>Antoine and Colette</em>,     1962</li>\n  <li>Dash Shaw: <em><a href=\"https://brieftake.com/interview-my-entire-high-school-s-dash-shaw/\">My Entire High School Sinking Into the Sea</a></em>, 2016</li>\n  <li>Paul Harrill:              <em>Light from Light</em>,        2019</li>\n  <li>Peter Bogdanovich:         <em>Targets</em>,                 1968</li>\n  <li>Ladj Ly:                   <em>Les Misérables</em>,          2019</li>\n  <li>Spencer Williams:         <a href=\"https://en.wikipedia.org/wiki/The_Blood_of_Jesus\"><em>The Blood of Jesus</em></a>, 1941</li>\n  <li>François Truffaut:         <em>Jules and Jim</em>,           1962</li>\n  <li>Guy Maddin:                <em>Brand Upon the Brain!</em>,   2006</li>\n  <li>Philippe Lesage:           <em>Genesis</em>,                 2018</li>\n  <li>Tsai Ming-liang:           <em>Walker</em>,                  2012</li>\n  <li>Scott Cummings:            <a href=\"https://buffalojuggalosfilm.tumblr.com\"><em>Buffalo Juggalos</em></a>,  2014</li>\n  <li>Éric Rohmer:            <em>The Bakery Girl on Monceau</em>, 1963</li>\n  <li>Lev Kalman, Whitney Horn:  <em>Two Plains &amp; a Fancy</em>, 2018</li>\n</ul>\n\n"},{"id":"https://benjaminwil.info/weblog/assimilated","url":"https://benjaminwil.info/weblog/assimilated","external_url":null,"title":"Assimilated","summary":"I just released a new LaunchBar 6 theme called Assimilated.","image":null,"banner_image":null,"date_published":"2020-12-25 12:00:00 -0700","date_modified":"2020-12-25 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb6f8d48>","#<Lifer::Tag:0x00007fffdb6f8b68>"],"language":"en","content_html":"<p>I just released a new <a href=\"https://www.obdev.at/products/launchbar/index.html\">LaunchBar 6</a> theme called Assimilated.</p>\n\n<p>I am kind of shocked that I still use LaunchBar, but as long as I use macOS for\nwork I guess I’ll be using LaunchBar, too. Like <a href=\"https://github.com/benjaminwil/bijou\">Bijou</a>, my five-year-old\ntheme, I wanted a LaunchBar theme that would blend in with the macOS window\nchrome. With the release of Big Sur, I needed to create a completely new theme.</p>\n\n<p><a href=\"https://github.com/benjaminwil/assimilated\">See the GitHub repo</a> for more information and installation instructions.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/letter-for-you","url":"https://benjaminwil.info/weblog/letter-for-you","external_url":null,"title":"Letter for you","summary":"I released some music last week. It’s a short album called Letter for you. You can stream it or purchase it on Bandcamp.","image":null,"banner_image":null,"date_published":"2020-12-21 09:00:00 -0700","date_modified":"2020-12-21 09:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb753298>","#<Lifer::Tag:0x00007fffdb752cf8>"],"language":"en","content_html":"<p>I released some music last week. It’s a short album called <em>Letter for\nyou</em>. You can stream it or purchase it <a href=\"https://bwbw.bandcamp.com/album/letter-for-you\">on Bandcamp</a>. Bandcamp is also a\ngreat place to read the lyrics for each song.</p>\n\n<p>I hope you enjoy the release.</p>\n\n"},{"id":"https://benjaminwil.info/antisocial/06","url":"https://benjaminwil.info/antisocial/06","external_url":null,"title":"prefers-color-scheme: dark","summary":"i decided it was time to make a dark colour scheme for this website.","image":null,"banner_image":null,"date_published":"2020-09-16 12:00:00 -0700","date_modified":"2020-09-16 12:00:00 -0700","tags":[],"language":"en","content_html":"<p>i decided it was time to make a dark colour scheme for this website. i haven’t\ntouched the styles on here in a while, and it was weird to go through them and\nsee how my brain had decided to organize them.</p>\n\n<p>i didn’t do a bad job. but, i dunno, definitely a younger version of me did it.</p>\n\n<p>there’s no way to “toggle” the colour schemes on the website itself. it depends\non you telling your browser (or in some cases your OS) which colour scheme you\nprefer: either light or dark.</p>\n"},{"id":"https://benjaminwil.info/weblog/film-title-poem-2016","url":"https://benjaminwil.info/weblog/film-title-poem-2016","external_url":null,"title":"Film Title Poem (2016)","summary":"Please also read Jennifer West’s introduction to the film.","image":null,"banner_image":null,"date_published":"2020-07-30 11:00:00 -0700","date_modified":"2020-07-30 11:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb706538>"],"language":"en","content_html":"<p><em>Please also read <a href=\"https://mubi.com/notebook/posts/jennifer-west-introduces-her-film-film-title-poem\" target=\"_blank\">Jennifer West’s introduction to the film</a>.</em></p>\n\n<p>Of the many shorts I’ve seen that appropriate and then collage movie stills or\nsequences, I interpret Film Title Poem as one of the more appreciative ones. In\nit, Jennifer West shines a flashlight on many of the films in the western\ncanon, the ones that either have weird staying power (<em>Men in Black</em>)\nor are held up as cult classics to the cinephiles (<em>L’Avventura</em>)\nor are the more obscure works of particular filmmakers who are considered\ncanonical (Gus Van Sant’s <em>Paranoid Park</em>). There are even shout-outs\nto some very revered experimental titles (go <em>T,O,U,C,H,I,N,G</em>,\n<em>Moth Light</em>). I should also mention the expertly stolen soundtrack,\nfeaturing scores from <em>Solaris</em> among other movies I’m blanking on,\neven though the music is still as clear as can be in my memory.</p>\n\n<p>When I say, “shines a flashlight,” I mean exactly that. As someone with\nwarm feelings for the majority of these movies, I was happy to see them\nbeing rediscovered on this wall of film titles somewhere. The titles are\npresented in half-alphabetical order, half-some sort of order. In some\nmoments I looked for meaning in the order: hidden sequences in the blinking,\nthe repetition of some titles. I didn’t get very far reading the film like\nthis, but didn’t mind either way. I was more focused on the Brakhagian\nscratches in the celluloid, highlighting movie-crushes and crossing out the\n(?) trash. Whether you can enjoy following along on this late-night tour\nor not, I think there’s value in flipping through these film titles with\nvery little other context, re-evaluating them on the spot, re-evaluating my\nmemories of them, and pitting them against the other film titles on the wall.</p>\n"},{"id":"https://benjaminwil.info/weblog/self-hosted-git-remote","url":"https://benjaminwil.info/weblog/self-hosted-git-remote","external_url":null,"title":"Self-hosting a tiny git remote","summary":"There are plenty of full-featured git forges out there.","image":null,"banner_image":null,"date_published":"2020-03-22 12:00:00 -0700","date_modified":"2020-03-22 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb18e2b8>","#<Lifer::Tag:0x00007fffdb18e178>"],"language":"en","content_html":"<p>There are plenty of full-featured git forges out there. If you’re a software\ndeveloper, you’ve probably used GitHub, Bitbucket, and GitLab at some point –\nand you’re maybe familiar with <a href=\"https://gitea.io\">Gitea</a>,\n<a href=\"https://gogs.io\">Gogs</a>, or <a href=\"https://sr.ht\">SourceHut</a>.</p>\n\n<p>All of this software is great, and each git forge has valuable features that save\nusers time and effort when working on projects.</p>\n\n<p>Sometimes, though, all I need is a simple <a href=\"https://git-scm.com/docs/git-remote\">git remote</a> to sync\na simple project. I don’t need issue trackers, wikis, continuous integration,\nor a way to manage patches coming from multiple contributors.</p>\n\n<p>For these use cases, I have set up a tiny git remote that only I can access.</p>\n\n<h2 id=\"create-a-synced-directory\">Create a synced directory</h2>\n\n<p>The first problem that needs solving: where should the remote live? I have\nchosen to use a simple synced directory.</p>\n\n<p>There is nothing special about this directory. It is just another directory I\nintend to sync using some Dropbox-like file syncing software. (Don’t worry: I do\nnot ever sync working directories. I’ll discuss this later.)</p>\n\n<p>We have many ways to sync directories in 2020: whether you use a hosted service\nlike Google Drive or use a self-hosted solution like\n<a href=\"https://owncloud.org/\">ownCloud</a>. I personally use\n<a href=\"https://syncthing.net/\">Syncthing</a>, which runs 24/7 on a media server in my\nliving room – and then syncs to all my other devices whenever they’re connected\nto a network.</p>\n\n<p>The directory I sync is simply called <code>Git</code>. It lives in my user’s <code>$HOME</code> directory.</p>\n\n<p>If you’re asking yourself, “why not just use SSH?” right now, I suggest skipping\nto the <a href=\"#why-not-just-use-ssh\">Why not just use SSH?</a> section of this article.</p>\n\n<h2 id=\"add-new-repositories\">Add new repositories</h2>\n\n<p>The next problem is: how to get <code>project-directory</code> from <em>Computer A</em> to\n<em>Computer B</em>. The short answer would be, “use the synced directory” – but I want\nto do this the right way.<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup></p>\n\n<p>In my <code>Git</code> directory, I can start to <a href=\"https://git-scm.com/docs/git-init\">initialize git\nrepositories</a> with the <code>--bare</code> flag:</p>\n\n<p><code>\ngit init --bare ~/Git/my-project.git\n</code></p>\n\n<p>The <code>--bare</code> flag means that the git repository being initialized (or cloned,\nactually) is <em>not</em> going to be a working directory.</p>\n\n<p>If I try to change directory to my new repo, git even warns me about this:</p>\n\n<p><code>\ncd ~/Git/my-project.git\nfatal: this operation must be run in a work tree\n</code></p>\n\n<p>You can read more about using bare git repositories this way in the <em>Pro Git</em>\nbook. Specifically, see <a href=\"https://git-scm.com/book/en/v2/Git-on-the-Server-Getting-Git-on-a-Server\">4.2 Git on the Server – Getting Git on a\nServer</a>.</p>\n\n<h2 id=\"push-to-repositories\">Push to repositories</h2>\n\n<p>I’m about ready to push work. So far, I’ve:</p>\n\n<ul>\n  <li>Built a home for git repositories I want to sync: <code>~/Git</code>.</li>\n  <li>Made my first bare git repository at <code>~/Git/my-project.git</code>.<sup id=\"fnref:2\"><a href=\"#fn:2\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">2</a></sup></li>\n</ul>\n\n<p>Now, I can take any working directory and add my bare repository as a remote:</p>\n\n<p><code>\ngit remote add syncthing ~/Git/my-project.git\n</code></p>\n\n<p>And when I’m ready to push my work from my branch (in this case <code>my-branch</code>):</p>\n\n<p><code>\ngit push syncthing my-branch\n</code></p>\n\n<h2 id=\"clone-repositories\">Clone repositories</h2>\n\n<p>When I’m ready to clone the project from another workstation, I just need\nto make sure my synced directory is available and fully synced. The messiest\npart of this is that (with Syncthing, at least) the synced directory <em>may</em> use a\ndifferent path on my different workstations.</p>\n\n<p>When I clone, it’s nice to manually set the <code>--origin</code> so I’m mindful that I’m\npushing to and pulling from my tiny git remote:</p>\n\n<p><code>\ngit clone --origin syncthing ~/Git/my-project.git\n</code></p>\n\n<p>And if I forget (like I often do), I can always change the name of the remote\nlater using <code>git remote rename</code>:</p>\n\n<p><code>\ngit clone ~/Git/my-project.git my-project\ncd my-project\ngit remote rename origin syncthing\n</code></p>\n\n<h2 id=\"caveats\">Caveats</h2>\n\n<p>My tiny git remote works great for small projects I don’t intend to share with\nanyone. But I think it’s important to highlight the caveats:</p>\n\n<ul>\n  <li>If my syncing software fails (on the server <em>or</em> a client), I risk losing work.</li>\n  <li>If this is my only git remote, I risk losing work. I must use multiple git\nremotes.</li>\n</ul>\n\n<p>If my syncing software does fail, but I’ve already cloned my project on\nmultiple workstations, I <em>may</em> be able to recover. That said, I do need to\nbe conscious of the state of my syncing software if I want to successfully\nuse my tiny remote.</p>\n\n<h2 id=\"why-not-just-use-ssh\">Why not just use SSH?</h2>\n\n<p>Some readers have rightly pointed out that this setup is more complex and has\nmore caveats than just pulling from your other workstations via SSH:</p>\n\n<p><code>\ngit remote add workstation_2 benjaminwil@111.111.11.11:/home/benjaminwil/my-project\n</code></p>\n\n<p>If I’m lucky: <code>111.111.11.11</code> is a static IP address that I already know. And if\nI’m really lucky: it’s just a domain name, like <code>benjaminwil.info</code>. Luck has\nnothing to do with it, but you know what I mean.</p>\n\n<p>The reasons that I prefer using a synced directory, as described in this\narticle, are:</p>\n\n<ul>\n  <li>There is built-in redundancy. Syncthing makes local copies of my latest\nchanges whenever a workstation running Syncthing is on a network.</li>\n  <li>I am lazy. I am too often wiping my secondary devices and not setting up SSH\nkeys to my primary devices.</li>\n  <li>I don’t personally have a static IP address at home. While there are ways to\ntake care of that problem, I haven’t ventured down that path.</li>\n</ul>\n\n<p>All that said, I also have a remote set up that I only access via SSH. It’s my\n“always off-site” backup, and it is very valuable to me.</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>I could technically work out of a project directory that’s actively being\n  synced. But there are lots of files I don’t want to or need to sync.</p>\n\n      <p>Syncing would occur more slowly if I had to sync 200MB of NodeJS modules\n  between workstations. And if I accidentally leave a process running on\n  <em>Workstation A</em> and then start work from <em>Workstation B</em>, I could cause\n  some weird problems for myself. <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:2\">\n      <p>I don’t have to add <code>.git</code> to the end of a bare git repo, but it’s a\n  nice convention. <a href=\"#fnref:2\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/weblog/2019-film","url":"https://benjaminwil.info/weblog/2019-film","external_url":null,"title":"The best films I saw: 2019 edition","summary":"I watched a lot of mediocre and objectively-pretty-bad movies this year.","image":null,"banner_image":null,"date_published":"2019-12-31 12:00:00 -0700","date_modified":"2019-12-31 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb713850>"],"language":"en","content_html":"<p>I watched a lot of mediocre and objectively-pretty-bad movies this year. So much\nso that I don’t think I can get to a list that’s thirty items’ long (as I did in\n<a href=\"/weblog/2018-film\">2018</a> and <a href=\"/weblog/2017-film\">2017</a>). That said, I watched some pretty wonderful\nthings:</p>\n\n<ul>\n  <li>James Benning: <em><a href=\"http://rarefilm.net/american-dreams-lost-and-found-1984-james-benning-documentary/\">American Dreams (Lost and Found)</a></em>, 1984</li>\n  <li>Sofia Bohdanowicz, Deragh Campbell: <em><a href=\"https://cinema-scope.com/features/audrey-ii-sofia-bohdanowicz-and-deragh-campbells-ms-slavic-7/\">MS Slavic 7</a></em>, 2019</li>\n  <li>Virgil Vernier: <em><a href=\"https://www.filmcomment.com/article/mercuriales-virgil-vernier/\">Mercuriales</a></em>, 2014</li>\n  <li>Bong Joon-Ho: <em>Memories of Murder</em>, 2003</li>\n  <li>Paweł Pawlikowski: <em>Cold War</em>, 2018</li>\n  <li>Kazuhiro Sôda: <em><a href=\"https://www.nytimes.com/2008/04/07/movies/07camp.html?_r=0\">Campaign</a></em>, 2007</li>\n  <li>Apichatpong Weerasethakul: <a href=\"https://en.wikipedia.org/wiki/Uncle_Boonmee_Who_Can_Recall_His_Past_Lives\">Uncle Boonmee Who Can Recall His Past\nLives</a>, 2010</li>\n  <li>Ricky D’Ambrose: <em><a href=\"https://www.villagevoice.com/2018/08/14/ricky-dambroses-minimalist-notes-on-an-appearance-is-obsessed-with-absence/\">Notes on an Appearance</a></em>, 2018</li>\n  <li>Agnès Varda: <em>Le Bonheur</em>, 1965</li>\n  <li>Lucien Castaing-Taylor, Véréna Paravel: <em><a href=\"https://en.wikipedia.org/wiki/Leviathan_(2012_film)\">Leviathan</a></em>, 2012</li>\n  <li>Nathan Silver: <em><a href=\"https://www.rogerebert.com/reviews/stinking-heaven-2015\">Stinking Heaven</a></em>, 2015</li>\n  <li>Sofia Bohdanowicz: <em>Veslemoy’s Song</em>, 2018</li>\n  <li>Manbiki Kazoku: <em>Shoplifters</em>, 2018</li>\n  <li>Toshio Matsumoto: <em><a href=\"https://en.wikipedia.org/wiki/Funeral_Parade_of_Roses\">Funeral Parade of Roses</a></em>, 1969</li>\n  <li>Robert Hamilton: <em>The Five Finger Splash</em>, 2019 <a href=\"https://vimeo.com/315744145\">🎥</a></li>\n  <li>Rodrigo Sorogoyen: <em>The Realm</em>, 2018</li>\n  <li>Ethan Coen, Joel Coen: <em>The Ballad of Buster Scruggs</em>, 2019</li>\n  <li>Noah Baumbach: <em>Marriage Story</em>, 2019</li>\n  <li>Bong Joon-Ho: <em>Parasite</em>, 2019</li>\n  <li>Ryan Ermacora, Jessica Johnson: <em><a href=\"https://jessicajohnson.ca/labour%2Fleisure\">Labour/Leisure</a></em>, 2019</li>\n</ul>\n\n<p>Due to this feeling incomplete to me, here are some non-movie things that might\nhave made this list in the parallel universe:</p>\n\n<ul>\n  <li><em>Mindhunter</em> (season two)</li>\n  <li><em>Watchmen</em></li>\n  <li>Jane Campion, Gerard Lee, and Garth Davis’ <em><a href=\"https://en.wikipedia.org/wiki/Top_of_the_Lake\">Top of the Lake</a></em> (season\none)</li>\n  <li>Nicholas Winding Refn’s <em><a href=\"https://en.wikipedia.org/wiki/Too_Old_to_Die_Young\">Too Old to Die Young</a></em></li>\n</ul>\n\n"},{"id":"https://benjaminwil.info/antisocial/04","url":"https://benjaminwil.info/antisocial/04","external_url":null,"title":"assessing my role in software freedom advocacy","summary":"over the last year i’ve become increasingly conscious of how my life and work intersects with free and proprietary softwa...","image":null,"banner_image":null,"date_published":"2019-02-24 19:11:02 -0700","date_modified":"2019-02-24 19:11:02 -0700","tags":[],"language":"en","content_html":"<p>over the last year i’ve become increasingly conscious of how my life and work\nintersects with free and proprietary software. notably:</p>\n\n<ul>\n  <li>i spent the better part of a year enabling midsize companies’ ability to “make\nmoney” using an open source ecommerce framework.</li>\n  <li>i went from working a contract at a small consultancy – who invested a\nsubstantial amount of money into that ecommerce framework – to joining the\nconsultancy and being acquired by… a very large company using the framework.</li>\n  <li>i became increasingly wary of people who make money via the internet.</li>\n  <li>i started thinking about other potential career tracks?</li>\n  <li>i switched from using arch linux full-time at work to using macos.</li>\n  <li>i saw some silly news stories about dicey open source software licenses.</li>\n  <li>i joined <a href=\"http://tilde.town\">tilde.town</a> and witnessed many people learning about and\nexperimenting with free software – and it’s worth noting that there is a wider\n(still expanding) tilde subculture.</li>\n  <li>i’ve relied on amazon to provide me with many of my basic needs and\nconvenience purchases, and i haven’t felt incredibly bad about it even though\ni think their existence is a net-negative for the world and the open web.</li>\n  <li>i reduced my reliance on google services – specifically g suite for email,\ncalendar, and file storage, but i also started using duckduckgo as the default\nsearch engine in all of my browsers.</li>\n  <li>i started managing my own private git remote/server. it’s not impressive, but\ni’m always learning something.</li>\n</ul>\n\n<p>this list is rambly, and it’s not clear what i (let alone <em>you</em>) should be\ntaking from these experiences. today, this list is telling me <em>my role in\nsoftware freedom advocacy is too small</em>. i say this as someone who isn’t\ninterested in being a professional advocate of any kind, but as someone who\nloves computers, software, and the <em>potential</em> of the internet (which becomes\nundermined a bit more each day).</p>\n\n<p>i can make my role larger by contributing to free software projects more and\nmore often; by choosing to use free and open source alternatives to proprietary\nsoftware (<a href=\"https://wiki.gnome.org/Apps/Dia\">ahem, lucidchart</a>); and by advocating for diy solutions to\nproblems that big companies solve if you’re willing to throw money at them. most\nimportantly, i can socialize the idea of software freedom when i speak to people\ninside and outside of the tech industry: i can write about it more, i can write\nabout why i feel it’s important, and so on.</p>\n\n<p>recently, i was introduced to the oggcast/podcast <a href=\"http://faif.us\">free as in\nfreedom</a> – which relaunched at the end of 2018 after a two-year\nhiatus. it’s hosted by <a href=\"http://ebb.org/bkuhn/\">bradley m. kuhn</a> and <a href=\"https://blogs.gnome.org/gnomg/\">karen\nsandler</a> who <em>are</em> professional free sofware\nadvocates. if you found my rambly thoughts on this topic semi-interesting, i’d\nrecommend listening to the following (recent) episodes:</p>\n\n<ul>\n  <li><a href=\"http://faif.us/cast/2018/dec/31/0x5f/\">0x5f: was 2018 the year of non-foss licensing?</a></li>\n  <li><a href=\"http://faif.us/cast/2019/jan/13/0x60/\">0x60: can anyone live in full software freedom today? (part i)</a></li>\n  <li><a href=\"http://faif.us/cast/2019/feb/19/0x61/\">0x61: can anyone live in full software freedom today? (part ii)</a></li>\n</ul>\n\n"},{"id":"https://benjaminwil.info/antisocial/03","url":"https://benjaminwil.info/antisocial/03","external_url":null,"title":"how to move into a new place","summary":"i’m moving this month, and so far it’s going smoothly.","image":null,"banner_image":null,"date_published":"2019-02-06 18:04:22 -0700","date_modified":"2019-02-06 18:04:22 -0700","tags":[],"language":"en","content_html":"<p>i’m moving this month, and so far it’s going smoothly.</p>\n\n<p>in the last nine years, i’ve moved ten times. most of the time, i only had to\nworry about my own things – but on one occasion i moved with two other people. i\ncan’t yet call myself a moving expert, but i’ve become increasingly efficient at\nmoving. i want to offer you, readers, some tips.</p>\n\n<p>some of these are uninsightful, common sense tips – but things to hold close to\nyour heart. when you’re moving: things get stressful, and common sense\nbecomes… uncommon.</p>\n\n<p>without further adieu:</p>\n\n<h2 id=\"dont-procrastinate\">don’t procrastinate</h2>\n\n<p>spend at least a week thinking about the move. and prepare to spend at least two\ndays moving (if you’re able to take two days).</p>\n\n<h2 id=\"write-out-an-inventory\">write out an inventory</h2>\n\n<p>and don’t inventory by room – rooms are too big. create <em>zones</em> that you need\nto pack, and use this to better plan your moving-tetris.</p>\n\n<p>i super-recommend <em>writing</em> the inventory down, on paper or using a to-do list\napp on your phone.</p>\n\n<h2 id=\"plan-to-get-rid-of-things\">plan to get rid of things</h2>\n\n<p>while you’re inventory-ing, make a list of things you no longer need – or need\nto replace. you could go the extra kilometre and make a list of things you\n<em>don’t</em> have but would like to.</p>\n\n<p>again: write this plan down somewhere. it’s no good to you if you forget half of\nthe plan.</p>\n\n<h2 id=\"plan-to-move-the-large-things-last\">plan to move the large things last</h2>\n\n<p>your small objects (books, records, kitchen objects, etc.) are the heaviest and\nmost time consuming things to pack. get them packed and out of the way. these\nare also the easiest things to tetris and put into a moving vehicle.</p>\n\n<h2 id=\"overcommit\">overcommit</h2>\n\n<p>this can apply to your moving experience in a number of ways. for me:</p>\n\n<ul>\n  <li>i make sure more than enough family members/friends are available to help move\n(and that none of them would have to do too much work)</li>\n  <li>i make sure i have lots of time to deal with the move, and lots of time with\nmoving vehicles, elevator keys, and what have you.</li>\n  <li>nothing is held together with paperclips. my boxes and bins <em>work</em>, and won’t\nfall apart.</li>\n</ul>\n\n<hr />\n\n<p>alright, so these are my initial moving tips. as i continue this next moving\nprocess, i may need to amend them.</p>\n"},{"id":"https://benjaminwil.info/antisocial/02","url":"https://benjaminwil.info/antisocial/02","external_url":null,"title":"using jekyll collections for a secondary, rss-only feed","summary":"this post outlines how i’m generating this feed as a separate, secondary feed using jekyll collections.","image":null,"banner_image":null,"date_published":"2019-01-21 23:17:12 -0700","date_modified":"2019-01-21 23:17:12 -0700","tags":[],"language":"en","content_html":"<p>this post outlines how i’m generating this feed as a separate, secondary feed\nusing <a href=\"https://jekyllrb.com/docs/collections/\">jekyll collections</a>. this is completely possible using the\ncurrent version (as of this post: <a href=\"https://github.com/jekyll/jekyll-feed/releases/tag/v0.11.0\">0.11.0</a>) of the\n<a href=\"https://github.com/jekyll/jekyll-feed\"><code>jekyll-feed</code></a> plugin. this plugin is included in all new jekyll\nprojects that have been generated with the <code>jekyll new</code> command.</p>\n\n<p>the main blog feed for this site is at the default location:</p>\n\n<p><code>\nhttps://benjaminwil.info/feed.xml\n</code></p>\n\n<p>and the feed you’re reading from now is at:</p>\n\n<p><code>\nhttps://benjaminwil.into/antisocial/feed.xml\n</code></p>\n\n<h2 id=\"collection-names\">collection names</h2>\n\n<p>there is one caveat: <code>jekyll-feed</code> doesn’t provide a way to set a custom name\nfor your secondary feed. any other feeds you make use basic site metadata:</p>\n\n<ul>\n  <li>your <code>site.title</code> or <code>site.name</code> variable’s value</li>\n  <li>a pipe character with some spaces around it (<code> | </code>)</li>\n  <li>and your collection name – with the first letter capitalized</li>\n</ul>\n\n<p>this can look a little bit stupid if you aren’t careful:</p>\n\n<p><code>\nCool Website | My-new-collection\n</code></p>\n\n<p>yeah, that’s the feed name that would show up in your friends’ rss readers.</p>\n\n<p>i have <a href=\"https://github.com/jekyll/jekyll-feed/pull/261\">a pull request open</a> on the <code>jekyll-feed</code> repository that fixes\nthis. but if you want custom names right now, you’ll have to use my fork of the\n<code>jekyll-feed</code> gem.</p>\n\n<h2 id=\"step-one-update-the-jekyll-feed-gem\">step one: update the jekyll-feed gem</h2>\n\n<p>when you create a new jekyll site using the <code>jekyll new</code> command, the version of\nthe <code>jekyll-feed</code> plugin included is <code>~&gt; 0.6</code>. to create a secondary feed, you\nneed to manually update your <code>Gemfile</code> to use <code>jekyll-feed</code> <code>~&gt; 0.11</code>:</p>\n\n<p><code>ruby\n# Gemfile ...\ngroup :jekyll_plugins do\n  gem \"jekyll-feed\", \"~&gt; 0.11\"\nend\n</code></p>\n\n<p>and add this <code>git</code> argument if you’re comfortable using my fork of the plugin\n(until my – or another similar – pull request has been merged):</p>\n\n<p><code>ruby\n# Gemfile ...\ngroup :jekyll_plugins do\n  gem \"jekyll-feed\", \"~&gt; 0.11\", git: https://github.com/benjaminwil/jf\nend\n</code></p>\n\n<h2 id=\"step-two-create-a-new-collection\">step two: create a new collection</h2>\n\n<p>in your site’s <code>_config.yml</code> file, you need to add the name and metadata for the\ncollection you intend to use for the feed. in my case:</p>\n\n<p><code>yml\n# _config.yml ...\ncollections:\n  antisocial:\n    output: true\n    permalink: /antisocial/:name\n</code></p>\n\n<p><code>output: true</code> ensures a separate file is generated for each item in the\ncollection (the permalink page), and the <code>permalink:</code> setting is probably\nfamiliar to you: use it to set your collection post’s uris.</p>\n\n<p>the jekyll permalinks docs include a list of <a href=\"https://jekyllrb.com/docs/permalinks/#collections\">available collections permalinks\nvariables</a>. the variable i’m using (<code>:name</code>) just attaches the\nfilename to the uri.</p>\n\n<p>your new collection can be created in the directory <code>_collection_name</code> (unless\nyou’ve set a custom <code>collections_dir:</code> in your <code>_config.yml</code>). in my case:\n<code>_antisocial</code>.</p>\n\n<h2 id=\"step-three-pick-a-layout\">step three: pick a layout</h2>\n\n<p>you can either use your standard <code>post</code> layout or make a new one. if you’re a\njekyll user, you likely know all about layouts: so i won’t go into any more\ndetail here.</p>\n\n<p>you can either set a <code>layout:</code> value in the frontmatter for every collection\nitem, or you can set each collection item’s layout globally from your\n<code>_config.yml</code>:</p>\n\n<p><code>yml\n# _config.yml ...\ndefaults:\n  -\n    scope:\n      path: \"\" # an empty string here means all files in the project\n      type: \"antisocial\"\n    values:\n      layout: \"your_preferred_layout\"\n</code></p>\n\n<p>this is some ugly yaml, but that’s what is has to be <a href=\"https://jekyllrb.com/docs/configuration/front-matter-defaults/\">according to the front\nmatter defaults docs</a>.</p>\n\n<h2 id=\"step-four-configure-the-feed\">step four: configure the feed</h2>\n\n<p>we’re pretty much done now. we just have to configure the secondary feed\ninformation using the provided <code>jekyll-feed</code> <a href=\"https://github.com/jekyll/jekyll-feed#collections\">configuration\nsettings</a>.</p>\n\n<p>again, in your <code>_config.yml</code>:</p>\n\n<p><code>yml\n# _config.yml ...\nfeed:\n  collections:\n    antisocial:\n      path: \"/antisocial/feed.xml\"\n</code></p>\n\n<p>where <code>antisocial:</code> is the name of your collection and the <code>path:</code> value is a\nstring with your preferred feed location.</p>\n\n<p>now that you’ve configured the feed, you can start to add new posts to your\ncollection directory.</p>\n\n<p>note that if you’re keeping a blog you still need to use <code>date:</code> front matter to\nensure your posts get to the feed.</p>\n\n"},{"id":"https://benjaminwil.info/antisocial/01","url":"https://benjaminwil.info/antisocial/01","external_url":null,"title":"intro to antisocial feed","summary":"test.","image":null,"banner_image":null,"date_published":"2019-01-17 17:01:34 -0700","date_modified":"2019-01-17 17:01:34 -0700","tags":[],"language":"en","content_html":"<p>test.</p>\n\n<p>i’ve been made aware of a thing called rss club and i am interested in it. not\njust because i’m a feed junky, but because i’m nostalgic (even whimsical) for\nthe web as i experienced it as a kid.</p>\n\n<p>so, i’m calling this <em>antisocial feed</em> not to be antisocial towards you, reader.\nand not to be reactively anti–social media.<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup></p>\n\n<p>i’m calling it <em>antisocial feed</em> because of me: if you knew me, before we hit\n201x, you’d know that i used to be social: i used to have curiousity, attention,\nand so on. i used to (think i had been) thoughtful about my (multitude of)\ninteractions with strangers online.</p>\n\n<p>i participated in forums: about video games, japanese rock music. i wrote\ncollaborative poems with my friend staxu. these are not things i feel up to\ndoing anymore, probably because i feel anxious about them: it’s vulnerable,\nor unprofessional, or exposing; i worry that i’d be misunderstood.</p>\n\n<p>are there like-minded people out there? willing to communicate with me, even\nin passing? sometimes other people seem inaccessible to me. sometimes i am\nworried that the only people left are trolls or deluded alpha-male wannabes.</p>\n\n<p>sorry – what an intro. i haven’t really made it clear what <em>antisocial feed</em> is\ngoing to be. for now, expect posts about the following topics:</p>\n\n<ul>\n  <li>how to (and how not to) communicate with others.</li>\n  <li>a ruby on rails-based personal journal platform i’m building: <a href=\"https://github.com/maeku/maeku\">maeku</a>.</li>\n  <li>irc, gopher, and free software in 2019. &lt;3</li>\n  <li>movies that are okay. (i’m yet another rss club person <a href=\"https://letterboxd.com/benjaminwil\">on letterboxd</a> – nice!)</li>\n  <li>why i’m not writing poetry for a living, even though that’s what i went to\nschool for.</li>\n</ul>\n\n<h2 id=\"postscript\">postscript</h2>\n\n<p>yeah, thanks for reading this far. i’m writing this on a static site generated\nby jekyll, and there’s <em>no</em> html view for this yet. it’s also separate from <a href=\"https://benjaminwil.info/weblog\">my\nmain feed</a>. more about this later.</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>reprise to self: all literature and media is inherently a little social. <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/weblog/2018-film","url":"https://benjaminwil.info/weblog/2018-film","external_url":null,"title":"The best films I saw: 2018 edition","summary":"For film-watching, 2018 wasn’t as good to me as 2017. But I did see a handful of movies worth remembering.","image":null,"banner_image":null,"date_published":"2018-12-31 12:00:00 -0700","date_modified":"2018-12-31 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb713850>"],"language":"en","content_html":"<p>For film-watching, 2018 wasn’t as good to me as 2017. But I did see a handful of\nmovies worth remembering. The following list is thirty films long – all films that\nI saw for the first time this year.</p>\n\n<ul>\n  <li>Eric Baudelaire: <em><a href=\"http://cinema-scope.com/spotlight/letters-max-eric-baudelaire-france/\">Letters to Max</a></em>, 2014</li>\n  <li>Spike Lee: <em><a href=\"https://en.wikipedia.org/wiki/Crooklyn\">Crooklyn</a></em>, 1994</li>\n  <li>John Cassavetes: <em><a href=\"https://film.avclub.com/john-cassavetes-final-major-work-love-streams-is-an-1798181120\">Love Streams</a></em>, 1984</li>\n  <li>Alexander Sokurov: <em><a href=\"https://mubi.com/notebook/posts/god-and-man-aleksandr-sokurovs-the-sun\">The Sun</a></em>, 2015</li>\n  <li>Pedro Costa: <em><a href=\"https://en.wikipedia.org/wiki/Colossal_Youth_(film)\">Collosal Youth</a></em>, 2006</li>\n  <li>Bingham Bryant &amp; Kyle Molzan: <em><a href=\"https://variety.com/2016/film/reviews/for-the-plasma-review-1201808672/\">For the Plasma</a></em>, 2016</li>\n  <li>Jacques Audiard: <em><a href=\"https://www.tiff.net/tiff/the-sisters-brothers/\">The Sisters Brothers</a></em>, 2018</li>\n  <li>Jonas Mekas: <em><a href=\"https://www.nga.gov/features/experimental-cinema-in-eastern-europe/historys-shadow/reminiscences-of-a-journey-to-lithuania.html\">Reminiscences of a Trip to Lithuania</a></em>, 1972</li>\n  <li>Sean Baker: <em>The Florida Project</em>, 2017</li>\n  <li>Luca Guadagnino: <em>Call Me by Your Name</em>, 2017</li>\n  <li>Steven Soderbergh: <em>Unsane</em>, 2018</li>\n  <li>Agnès Varda: <em>Kung-fu master!</em>, 1988</li>\n  <li>Steve James: <em><a href=\"https://en.wikipedia.org/wiki/Hoop_Dreams\">Hoop Dreams</a></em>, 1994</li>\n  <li>Tom DeCillo: <em><a href=\"http://www.tomdicillo.com/portfolio/down-in-shadowland/\">Down in Shadowland</a></em>, 2014</li>\n  <li>Boots Riley: <em>Sorry to Bother You</em>, 2018</li>\n  <li>Renata Gąsiorowska: <em>Pussy</em>, 2016 <a href=\"https://vimeo.com/308707509\">🎥</a></li>\n  <li>Ruben Östlund: <em>The Square</em>, 2017</li>\n  <li>Lynne Ramsay: <em>You Were Never Really Here</em>, 2018</li>\n  <li>Jacques Rivette: <em>Wuthering Heights</em>, 1985</li>\n  <li>Angela Schanelec: <em><a href=\"http://worldscinema.org/2015/01/angela-schanelec-mein-langsames-leben-aka-passing-summer-2001/\">Passing Summer</a></em>, 2001</li>\n  <li>Kevin Jerome Everson: <em>Three Quarters</em>, 2015</li>\n  <li>Benoît Forgeard: <em>Respect</em>, 2011</li>\n  <li>Paul Thomas Anderson: <em>Phantom Thread</em>, 2017</li>\n  <li>Denis Côté: <em>Curling</em>, 2010</li>\n  <li>Gastón Solnicki: <em><a href=\"http://cinema-scope.com/spotlight/kekszakallu-gaston-solnicki-argentina/\">Kékszakállú</a></em>, 2016</li>\n  <li>Greta Gerwig: <em>Lady Bird</em>, 2017</li>\n  <li>Alex Ross Perry: <em>Golden Exits</em>, 2017</li>\n  <li>Éric Rohmer: <em><a href=\"http://sensesofcinema.com/2017/1967/la-collectionneuse/\">La Collectionneuse</a></em>, 1967</li>\n  <li>Yorgos Lanthimos: <em>The Favourite</em>, 2018</li>\n  <li>Wes Anderson: <em>Isle of Dogs</em>, 2018</li>\n  <li>Hugh Gibson: <em><a href=\"https://www.theglobeandmail.com/arts/film/film-reviews/no-happy-endings-in-hugh-gibsons-the-stairs/article32228963/\">The Stairs</a></em>, 2016</li>\n</ul>\n\n"},{"id":"https://benjaminwil.info/weblog/bijou","url":"https://benjaminwil.info/weblog/bijou","external_url":null,"title":"Bijou","summary":"I updated my LaunchBar 6 theme Bijou (previously called El Capitan Small).","image":null,"banner_image":null,"date_published":"2018-09-30 12:00:00 -0700","date_modified":"2018-09-30 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb6f8d48>","#<Lifer::Tag:0x00007fffdb6f8b68>"],"language":"en","content_html":"<p>I updated my <a href=\"https://www.obdev.at/products/launchbar/index.html\">LaunchBar 6</a> theme Bijou (previously called <a href=\"/weblog/el-capitan-small\">El Capitan\nSmall</a>). Now, the theme has a dark variant to match macOS Mojave’s new dark\nmode. It also got its new name and features some small tweaks that make\nit more visually consistent.</p>\n\n<p><a href=\"https://github.com/benjaminwil/bijou\">See the GitHub repo</a> for more information and installation instructions.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/public-access-unix-servers-as-a-service","url":"https://benjaminwil.info/weblog/public-access-unix-servers-as-a-service","external_url":null,"title":"Public access Unix servers as a service","summary":"A public access Unix (or Unix-like) server is just a computer.","image":null,"banner_image":null,"date_published":"2018-07-21 12:07:00 -0700","date_modified":"2018-07-21 12:07:00 -0700","tags":["#<Lifer::Tag:0x00007fffdbc28598>","#<Lifer::Tag:0x00007fffdbc26ec8>"],"language":"en","content_html":"<p>A public access Unix (or Unix-like) server is just a computer. What makes it\nspecial is that anybody can sign up for a user account and use the computer.</p>\n\n<p>I would consider these servers proto-social networks: no matter what activities\nyou participate in on the server (message boards, chat, blogging, personal\nprojects, shared application development), you’re contributing to the server\ncommunity.</p>\n\n<p>The most famous public access server is <a href=\"https://en.wikipedia.org/wiki/SDF_Public_Access_Unix_System\">SDF</a>. It has existed\nsince 1987 and still has a growing user base. From 1987-era <a href=\"https://en.wikipedia.org/wiki/Gopher_%28protocol%29\">Gopher sites</a>,\nto traditional web forums, to multi-user Minecraft, SDF hosts a wide-range of\nservices for—and by—its users.</p>\n\n<p>Currently, on the homepage of this site, I call myself a “public access Unix\nserver enthusiast.” I began my journey with public access servers as a member of\n<a href=\"http://tilde.club\">tilde.club</a><sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup> (unfortunately inactive these days), and I now contribute to\n<a href=\"http://tilde.town\">tilde.town</a>.</p>\n\n<p>I understand that intentionally accessing a server via the command line, and\nknowing how to do that, is not something that every person can do or would want\nto do. However, I hope you consider the ways that these servers can offer\nspaces for social experimentation that can pave the way for future, more refined\nnetworks and online spaces:</p>\n\n<ul>\n  <li>These servers are fundamentally non-commercial. They operate on personal\ntrust.</li>\n  <li>These servers promote technical literacy and offer the potential of education\nand mentorship.</li>\n  <li>Server information infrastructure is flexible and “designed” by active users.\nUsers are the primary stakeholders, investors, and feature-implementers in\ntheir community.</li>\n  <li>Users intentionally create and have control over their own data.</li>\n  <li>These servers provide the opportunity for users to host their own\nunconventional websites, blogs, and web apps, for free (or some reasonable\nmembership fee).</li>\n</ul>\n\n<p>There is also talk of federating some tilde-named servers. You can see the\nbeginnings of this at <a href=\"https://tilde.chat\">tilde.chat</a>. Currently, tilde.chat connects four\ntilde-named servers via IRC.</p>\n\n<p>For me, these are just a few reasons that make public access servers compelling.\nAnd seeing <a href=\"https://medium.com/@NotBrunoAgain/mastodon-the-obligatory-explainer-3c8a63467828\">the recent success of Mastodon</a>, and how it seemingly shares\nsome of the same values, specifically around ownership, identity, and privacy.\nIt validates my belief that these servers are forerunners in an emerging web\nculture, not just hobby spots for outsider tech nerds.</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>See Paul Ford’s article <a href=\"https://medium.com/message/tilde-club-i-had-a-couple-drinks-and-woke-up-with-1-000-nerds-a8904f0a2ebf\">Tilde.Club: I had a couple drinks and woke up with 1,000 nerds</a> for more information about tilde.club. <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/weblog/site-update","url":"https://benjaminwil.info/weblog/site-update","external_url":null,"title":"Site update","summary":"I just updated benjaminwil.info to use a new layout.","image":null,"banner_image":null,"date_published":"2018-07-08 12:00:00 -0700","date_modified":"2018-07-08 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb908070>","#<Lifer::Tag:0x00007fffdb906ec8>"],"language":"en","content_html":"<p>I just updated <a href=\"https://benjaminwil.info\">benjaminwil.info</a> to use a new layout. It’s still built with\n<a href=\"https://jekyllrb.com\">Jekyll</a>, and it’s still hosted on <a href=\"https://m.do.co/c/4b641d12a82b\">a DigitalOcean droplet</a>—but I cut\nout fifty percent of the CSS and made site maintenance <em>much</em> easier for myself.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/2017-film","url":"https://benjaminwil.info/weblog/2017-film","external_url":null,"title":"The best films I saw: 2017 edition","summary":"I am sharing with you thirty films that I saw this year, that I liked.","image":null,"banner_image":null,"date_published":"2017-12-31 12:00:00 -0700","date_modified":"2017-12-31 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb713850>"],"language":"en","content_html":"<p>I am sharing with you thirty films that I saw this year, that I liked. They\ndefinitely did not all come out this year, or even recently. They are listed\nbelow in a definite order.</p>\n\n<ul>\n  <li>Maren Ade: <em><a href=\"https://www.bfi.org.uk/news-opinion/sight-sound-magazine/reviews-recommendations/toni-erdmann-maren-ade-shaggy-dad-comedy\">Toni Erdmann</a></em>, 2016</li>\n  <li>Nanni Moretti: <em>Sweet Dreams</em>, 1981</li>\n  <li>Huang Ya-Li: <em><a href=\"https://www.cinema.ucla.edu/events/2017/11/05/moulin\">Le Moulin</a></em>, 2015</li>\n  <li>Jordan Peele: <em>Get Out</em>, 2017</li>\n  <li>James N. Kienitz Wilkins: <em>Public Hearing</em>, 2012 <a href=\"https://vimeo.com/ondemand/publichearing\">🎥</a></li>\n  <li>Jay Rosenblatt: <em>Restricted</em>, 1999</li>\n  <li>Ai Weiwei: <em><a href=\"https://en.wikipedia.org/wiki/Human_Flow\">Human Flow</a></em>, 2017</li>\n  <li><a href=\"https://mubi.com/notebook/posts/ghosts-of-time-and-light-the-experimental-cinema-of-ito-takashi\">Takashi Ito</a>: <em>Double</em>, 2001</li>\n  <li>James N. Kienitz Wilkins: <em><a href=\"https://mubi.com/notebook/posts/e-uno-plura-close-up-on-james-n-kienitz-wilkins-the-republic\">The Republic</a></em>, 2017</li>\n  <li>Arthur Lipsett: <em>21-87</em>, 1963 <a href=\"https://vimeo.com/29432400\">🎥</a></li>\n  <li>Casimir Nozkowski: <em>IDAC</em>, 2016 <a href=\"https://www.youtube.com/watch?v=OvCum88STm8\">🎥</a></li>\n  <li>Michael Winterbottom: <em>The Trip</em>, 2010</li>\n  <li>Olivier Assayas: <em><a href=\"http://cinema-scope.com/cinema-scope-online/personal-shopper-olivier-assayas-france-masters/\">Personal Shopper</a></em>, 2016</li>\n  <li>Kevan Funk: <em><a href=\"https://www.cbc.ca/news/entertainment/kevan-funk-hello-destroyer-1.4019785\">Hello Destroyer</a></em>, 2016</li>\n  <li>Ousmane Sembene: <em>Black Girl</em>, 1966</li>\n  <li>Sofia Coppola: <em>The Beguiled</em>, 2017</li>\n  <li>Takashi Ito: <em>December Hide-and-Go-Seek</em>, 1993</li>\n  <li>Laura Poitras: <em>Risk</em>, 2016</li>\n  <li>Dana Berman Duff: <em>Catalogue Vol. 6</em>, 2016 <a href=\"https://vimeo.com/204550609\">🎥</a></li>\n  <li>Chris King: <em>Wipe Poem</em>, 2017 <a href=\"https://vimeo.com/62649373\">🎥</a></li>\n  <li>David Leitch: <em>Atomic Blonde</em>, 2017</li>\n  <li>Jeffrey Chong: <em>Kingsway</em>, 2017</li>\n  <li>Alabart, Cros, Verheyen, Rius: <em><a href=\"https://www.hollywoodreporter.com/review/agata-s-friends-les-amigues-909581\">Agata’s Friends</a></em>, 2015</li>\n  <li>Chris Marker: <em>La Jetée</em>, 1962 <a href=\"https://www.youtube.com/watch?v=6anMLFwHFqs\">🎥</a></li>\n  <li>Jodie Mack: <em>Wasteland No. 1: Ardent, Verdant</em>, 2017</li>\n  <li>Maurice Pialat: <em><a href=\"https://lwlies.com/articles/a-nos-amours-maurice-pialat-greatest-teen-movie/\">À Nos Amours</a></em>, 1983</li>\n  <li>Hayao Miyazaki: <em>Kiki’s Delivery Service</em>, 1989</li>\n  <li>Tom McCarthy: <em>Spotlight</em>, 2015</li>\n  <li>Tim Sutton: <em><a href=\"https://www.theguardian.com/film/2017/aug/18/dark-night-review-tim-sutton-aurora-massacre\">Dark Night</a></em>, 2016</li>\n  <li>Peter Weir: <em>Picnic at Hanging Rock</em>, 1975</li>\n</ul>\n\n"},{"id":"https://benjaminwil.info/weblog/the-republic-2017","url":"https://benjaminwil.info/weblog/the-republic-2017","external_url":null,"title":"The Republic (2017)","summary":"The Republic meets my threshold for something that is a movie, despite there being almost nothing to see.","image":null,"banner_image":null,"date_published":"2017-07-30 12:00:00 -0700","date_modified":"2017-07-30 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb706880>","#<Lifer::Tag:0x00007fffdb706538>"],"language":"en","content_html":"<p><em>The Republic</em> meets my threshold for something that is a movie,\ndespite there being almost nothing to see. If you don’t already know: <em>The\nRepublic</em> doesn’t utilize a camera. It presents solid colours only… and\nquite slowly. You could call it a gimmick, but be aware that it is one entry\ninto a category of films that do the exact same thing—notably Derek Jarman’s\n<em>Blue</em>—and still manage to do a new thing. This entry holds interest\nby grounding the viewer in  uncomplicated radioplay storytelIing, relieving us\nof the genuinely uncomfortable, OLED-destroying, static abstraction on screen.</p>\n\n<p>Since you won’t be seeing much, pay attention to the warmth of the\noccasional flourishes that create sound-images in a mostly barren\n(apocalyptic?) sound-world. Most memorably, there is a doorbell effect that\nprovides additional relief from what’s on screen, and from the detached,\nminimal presentation of sound stage and many of the vocal performances. I\ndon’t have 7.1 surround at home and don’t believe this medium-fidelity\nproduction would have benefited from it anyway.</p>\n\n<p>The story describes a group of libertarian outsiders (and e-cigarette\nenthusiasts) delicately. Here, in 2010s North America, the libertarians that\nget clipped are either loud or dangerous, and so I urge you to take a breath\nand reframe before watching, so you can “get behind” an extended scenario\nfollowing the downfall of this sovereign of (very serious) libertarians who\nwant deeply for their society to function.</p>\n\n<p>Of all the performances, Nour Mobarak’s performance stands out.</p>\n"},{"id":"https://benjaminwil.info/weblog/sleep-when-exhausted-revisited","url":"https://benjaminwil.info/weblog/sleep-when-exhausted-revisited","external_url":null,"title":"Sleep when exhausted, revisited","summary":"Three years after first presenting Sleep when exhausted, I was invited back to the University of Victoria to give a short...","image":null,"banner_image":null,"date_published":"2017-02-02 00:00:00 +0000","date_modified":"2017-02-02 00:00:00 +0000","tags":["#<Lifer::Tag:0x00007fffdb6f1ac0>"],"language":"en","content_html":"<p>Three years after first presenting <a href=\"https://sleepwhen.benjaminwil.info\"><em>Sleep when\nexhausted</em></a>, I was invited back to the\nUniversity of Victoria to give a short talk about it in <a href=\"http://davidleach.ca\">David\nLeach</a>’s WRIT 324 class.<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup> It turns out that giving a\ntalk is the best possible excuse to revisit old work, especially when you’re a\nlittle embarrassed about it.</p>\n\n<p>This post is based on that talk. It also attempts to extrapolate on the jokey,\ncryptic stuff that appears in <a href=\"/weblog/sleep-when-exhausted\">the essay that accompanied the\nproject</a>.</p>\n\n<h2 id=\"what-is-this-thing\">What is this thing?</h2>\n\n<p><em>Sleep when exhausted</em> is a looping visual poem.<sup id=\"fnref:2\"><a href=\"#fn:2\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">2</a></sup> That means that it begs to\nbe read over and over again. If you choose to go through it more than once,\nyou’ll notice that the poem changes depending on the lines you pick out. But the\npremise of <em>Sleep when exhausted</em>, at its simplest, is that it’s a poem.</p>\n\n<p>For me, re-reading poetry is a necessary part of reading poetry. Every time I\nread a poem, I’ll linger on slightly different details, or the same singular\ndetail with some other cadence. This project formalizes that re-reading process.\nUnless you’re mapping out the lines that you’re picking, you probably won’t go\nthrough <em>Sleep when exhausted</em> the same way twice.</p>\n\n<p>Even now, as I’ve been going through it again, I get surprised by certain things\nthat I don’t even remember writing. Like the clock that reads <code>99:99</code> on the\npiano in the living room.</p>\n\n<h2 id=\"why-make-a-poem-out-of-a-website\">Why make a poem out of a website?</h2>\n\n<p>I received something that the University of Victoria calls a <a href=\"https://www.uvic.ca/learningandteaching/students/scholarships/jcura/\">Jamie Cassels\nUndergraduate Research\nAward</a>.\nIt’s given to two students from every department each year.</p>\n\n<p>In addition to $1,500 toward tuition, recipients get a $50 stipend to spend on\nposter materials for the eventual JCURA year-end fair. If you’ve ever been to a\nhigh school science fair or a college job fair, just picture that, but with a\nwider array of disciplines represented.</p>\n\n<p>Because I was not required to use my $50 stipend on printing materials\nspecifically, I didn’t. My favourite science fair projects, as a kid, were the\nones where you didn’t just read a poster. I figured I’d make something a little\nmore interactive for my visitors to deal with. So, “Why make a poem out of a\nwebsite?” That’s why.</p>\n\n<h2 id=\"whats-with-the-accompanying-essay\">What’s with the accompanying essay?</h2>\n\n<p>It’s a poemy, tongue-in-cheek window into the nature of my research. While I\nthink there’s overlap between “creative research” and “academic research,”\ncreative research doesn’t follow the same rules.</p>\n\n<p>The academic research that I’m most familiar with as a university graduate\nfeigns uncontaminatedness and objectivity toward its subject. Although academics\nmight start research out of a place of curiousity or passion, they may need to\nsquelch some enthusiasm, or their research may stay unpublished. Rightly so.\nThere’s value to that system.</p>\n\n<p>Meanwhile, creative search can start in the same place—a place of passion—but\nsprawl across disciplines and styles and remain unsquelched. See Jordan Abel’s\nbook <a href=\"http://www.jordanabel.ca/uninhabited/\"><em>Un/inhabited</em></a>, which documents\nthe colonialist language used in copyright-lapsed (read: very old) western\nnovels about land and land ownership.</p>\n\n<p>The “creative thesis” is getting more and more popular, but it still doesn’t\nhave the same clout that an “academic” thesis has. I don’t want to say that a\ncreative thesis is less legitimate, than a “non-creative” thesis, but they do\nhave a way of making uninteresting subject matter more interesting.</p>\n\n<p>My own creative research here, and the way I present that research, has less to\ndo with deep dives into external materials or studies and more to do with sleepy\nreflections on the loss of personal motivation, focus, and feeling like life\nsure is boring. I don’t want to say that my research is less legitimate, but I’d\nagree with you that it’s less interesting.</p>\n\n<h2 id=\"are-you-one-of-those-video-games-arent-art-people\">Are you one of those “video games aren’t art” people?</h2>\n\n<p>It sounds like you’re referring to the section in the essay about “gameness.” In\nit, I say that <em>Sleep when exhausted</em> falls outside of what I’d normally\nconsider a game.</p>\n\n<p>I’m not a “video games aren’t art” person. I just don’t think this is a video\ngame. You can’t really win, and the poem’s mechanics aren’t skill-based in any\nway. The mechanics—clicking through a line to get a new set of lines—are barely\neven narrative. I see the forward motion of the poem the same way that I see my\nown thought process: not focused, only somewhat linear, and attention-averse.</p>\n\n<h2 id=\"is-this-work-scrappy\">Is this work scrappy?</h2>\n\n<p>Yeah. When I started this, I had no idea how to build a branching narrative for\nthe web, and I had no idea what the poem’s content would be. I did outline some\nof it, to gauge the general trajectory, but as I was implementing the trees I\nveered quickly into doing whatever I felt like at that moment.</p>\n\n<p>I experimented with doing the whole thing in <a href=\"http://twinery.org\">Twine</a>, but I had a hard time\ngetting the non-linear, wrap-around, lost feeling using that system.</p>\n\n<p>Please, please, please don’t look at the source code for this effing thing.</p>\n\n<h2 id=\"does-this-thing-have-a-structure\">Does this thing have a structure?</h2>\n\n<p>I guess so, but I’m still not able to parse it completely. Or, making a perfect\nmap of this poem (by hand) would be quite difficult. There are <em>a lot</em> of\n“potential poems” in here, and while I’d love to see them all extracted into a\nseries of separated poems—there would be a lot of them.</p>\n\n<p>However, this thing does have a system. There are three types of states:</p>\n\n<ul>\n  <li>Observation trees (I went to the kitchen / I went to the bathroom / etc.)</li>\n  <li>Streams of consciousness (I / love / Maria)</li>\n  <li>Clarities (I was bored / /)</li>\n</ul>\n\n<p>It’s nice to have system language for what this thing is, but I don’t think it\nmakes the work any more interesting. Just jump in and see how it makes you feel.</p>\n\n<h2 id=\"wheres-this-source-code-im-not-supposed-to-look-at\">Where’s this source code I’m not supposed to look at?</h2>\n\n<p>You can find the source code <a href=\"https://github.com/benjaminwil/sleepwhen\">at this GitHub repository</a>.</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>The class is called Writing Interactive Narrative: “A workshop/seminar in writing for digital media, hyper-literature, video games, interactive installations and experiences.” <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:2\">\n      <p>I call it a “visual poem” because the white space, three-column layout, and the nature of content-forking are very central to the piece. Although I can see why someone would argue that it’s not <a href=\"https://en.wikipedia.org/wiki/Visual_poetry\">visual poetry according to the definition</a>. <a href=\"#fnref:2\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/weblog/el-capitan-small","url":"https://benjaminwil.info/weblog/el-capitan-small","external_url":null,"title":"El Capitan Small","summary":"I made a theme for LaunchBar 6, a Mac OS X-based launcher and automation tool.","image":null,"banner_image":null,"date_published":"2015-12-26 12:00:00 -0700","date_modified":"2015-12-26 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb6f8d48>","#<Lifer::Tag:0x00007fffdb6f8b68>"],"language":"en","content_html":"<p>I made a theme for <a href=\"https://www.obdev.at/products/launchbar/index.html\">LaunchBar 6</a>, a Mac OS X-based launcher and\nautomation tool. It’s inspired by Small, the default theme for LaunchBar 5.</p>\n\n<p>It’s called El Capitan Small. <a href=\"https://github.com/benjaminwil/el-capitan-small\">See the GitHub repo</a> for more information\nand installation instructions.</p>\n\n"},{"id":"https://benjaminwil.info/weblog/sleep-when-exhausted","url":"https://benjaminwil.info/weblog/sleep-when-exhausted","external_url":null,"title":"Sleep when exhausted","summary":"The technical content of Sleep when exhausted, to anyone viewing its page source, is not by any means impressive and is c...","image":null,"banner_image":null,"date_published":"2014-03-05 12:00:00 -0700","date_modified":"2014-03-05 12:00:00 -0700","tags":["#<Lifer::Tag:0x00007fffdb5d2928>","#<Lifer::Tag:0x00007fffdb5d26a8>"],"language":"en","content_html":"<p>The technical content of <em>Sleep when exhausted</em>, to anyone viewing its\npage source, is not by any means impressive and is crudely constructed.\nStill, as a product I would label foremost as poetry, I will offer here\nthat the amateurish build quality adds to the final product.</p>\n\n<h2 id=\"process\">Process</h2>\n\n<p>What I created for this project records my coming to the web browser\nas an outsider. I spoke colloquially, as a poet, using JavaScript to\nspeak to the client’s web browser in a language that the browser\nunderstands. I utilized the browser’s ability to calculate the unfolding\nnarrative efficiently, in a way that readers need not understand.</p>\n\n<p>And so, because I am a barely self-taught web developer, and still\nwanted to see the poem laid out somehow on the backend, I created much\nunnecessary work for myself. I often had to backtrack.</p>\n\n<p>This became a contemplative act in the same way that prayer is a\ncontemplative act: instead of humbling myself before the greatness and\nnonhumanness of <em>other</em>, I approached <em>other</em> as though <em>other</em> wanted\nto be spoken to as if it were humanlike. The only communicative\nbenefits, as far as I understand them, that can be observed from an act\nof prayer are in oneself; <em>other</em>’s involvement in the conversation was\nnot observable.</p>\n\n<p>A practiced web developer could find more efficient ways of creating\n<em>Sleep when exhausted</em>. Instead of inputting each state<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">1</a></sup> by hand, I\ncould have created a collection of data that, with simple keywords,\nwould grab any input data and automate the output. Instead I chose to\napproach the JavaScript like I do any analogue writing project:</p>\n\n<ul>\n  <li>I assume that I understand the language I will be working in well\nenough to communicate something.</li>\n  <li>I research in isolation, without input from mentors or peers until\nlater in the process.</li>\n  <li>I work linearly, one minuscule task after another.</li>\n  <li>I check for errors and mistakes and inconsistencies.</li>\n  <li>I repeat.</li>\n  <li>I disregard orthodox form and structure,</li>\n  <li>which might also mean disregarding common sense, readability, and\nusability.</li>\n  <li>I embrace the long hours and unpaid nature of my project.</li>\n  <li>I stop eating, sleeping, et cetera.</li>\n  <li>I take long walks in the middle of the night when restless.</li>\n</ul>\n\n<p>I do not mean to say that conventional web development cannot be a\ncontemplative or transcendental act. I only mean to distinguish between\nconventional web development, which I know little about, and my own\nemulation of web development as a poet in a culture of poetry steeped in\nprinted matter.<sup id=\"fnref:2\"><a href=\"#fn:2\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">2</a></sup> I also understand that many web designers,\ndevelopers, students, and other creatives work in a similar, albeit\nunhealthy, way—working more than eighty hours per week, losing sleep,\neating poorly, being obsessed, or whatever.</p>\n\n<h2 id=\"gameness\">Gameness</h2>\n\n<p>Because the reader generates new information to consume as they navigate\nthrough the speaker’s world, <em>Sleep when exhausted</em> could be closely\ncompared to <em>Choose Your Own Adventure</em>-style gamebooks, other branching\nnarrative systems, graphical point-and-click adventure games, visual\nnovels, or whatever.</p>\n\n<p>The major difference would be that <em>Sleep when exhausted</em> excludes\nactual choice, plot, and gameness.<sup id=\"fnref:3\"><a href=\"#fn:3\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">3</a></sup> Readers might view themselves as\n“players” when interacting with it, but more than usual, their choices\nhave no effect on this work’s outcome. Readers pick the details that\nthey pick, and details unveil further details as I have prescribed. The\ncontinuity is not narrative, or, because it is looping, chronological.\nIt is just a visual artifact of the speaker’s consciousness, much like\nother poems.</p>\n\n<h2 id=\"reading\">Reading</h2>\n\n<p>In avoiding gameness, I knew that my project would withdraw further into\nthe territory of poetry—a region that seems to exclude the majority of\npeople—and even the majority of writers. I wanted poets and nonpoets to\nbe able to approach this work. I created an <em>imaginary general\naudience</em>. So I worked to cater to a diverse set of readers, who have\nshort attention spans, or read more or less in the context of video\ngames, or who more or less read links acquired from their Facebook\nfeeds.</p>\n\n<p>Similarly, I did not want to alienate the “average reader”<sup id=\"fnref:4\"><a href=\"#fn:4\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">4</a></sup> or the\n“average reader of poetry” any more than usual and decided to make\n<em>Sleep when exhausted</em> seem book-like. This is my tiny attempt to trick\nthem into interacting with the work.<sup id=\"fnref:5\"><a href=\"#fn:5\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">5</a></sup></p>\n\n<p>If I ever wanted this imaginary general audience to enjoy, let alone\ninteract at all with this work, it would need to be completable in under\na minute and absorbing enough to invite readers interested in the work\nfor another read.</p>\n\n<h2 id=\"literariness\">Literariness</h2>\n\n<p>There is a girl seated in front of me, sitting next to her mother. She\nis twenty-three-ish years old. Our flight attendant passes her a glass\nof water. I watch her watching Jeremy Renner fight a wolf with his bare\nhands.</p>\n\n<p>I’ve already seen <em>The Bourne Legacy</em>, but it seems different now. I am\ntrying to scrub through my memory of the flick, figure out what events\nhave already occurred. I view this now without audio, through the crack\nbetween two airline seats. I attempt to measure the viewer’s pleasure,\nfiltered through her blonde, shoulder-length hair.</p>\n\n<p>Our flight attendant passes me a glass of orange juice with ice in it.\nIt takes a few minutes, but I finally find the dimmer to turn off my own\nin-flight multimedia station. I admit there is something about watching\na movie you have no intention of finishing because the duration of your\nflight just isn’t long enough, but today I want to just be on this\nairplane and do nothing.</p>\n\n<h2 id=\"obsolescence\">Obsolescence</h2>\n\n<p>As web browsers are perpetually modernized, support for <em>Sleep when\nexhausted</em> will likely drop, at least partially. This type of problem\naffects all digital works and will impair us from interacting with\ncontent as it was intended—at least until content creators adopt plain\ntext as <em>the</em> standard method of digitally storing and/or documenting\nhuman-readable information<sup id=\"fnref:6\"><a href=\"#fn:6\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">6</a></sup> or move back to paper.</p>\n\n<p><em>Sleep when exhausted</em> will also become visually obsolete as it ages,\nand is probably ugly already. I regret aesthetic choices that I have\nmade. That said, I do not intend to continue support for this work, and\nI welcome any obsolescence gratefully.</p>\n\n<h2>Reading list</h2>\n\n<ul>\n\t<li><a href=\"http://www.kyoolee.net/From_Modernism_to_Hypermodernism_and_Beyond_-_Interview_with_Paul_Virilio.pdf\">From Modernism to Hypermodernism and Beyond</a>. Armitage, John; Virilio, Paul</li>\n\t<li><a href=\"http://tm-resource.projects.cavi.au.dk/?page_id=1291\">Post-digital Research, vol. 3, issue 1</a>.</li>\n\t<li><a href=\"http://www.ubu.com/papers/fahlstrom01.html\">Manifesto for Concrete Poetry</a>. Fahlström, Öyvind </li>\n\t<li><a href=\"http://www.gauss-pdf.com/post/77921584015/gpdf101-matthew-fee-instructions-for-lightning\">Instructions for Lightning Avoidance</a>. Fee, Matthew</li>\n\t<li><a href=\"http://ubu.com/vp/Typewriter_Poems.html\">Typewriter Poems</a>. Finch, Peter (ed.)</li>\n\t<li><a href=\"http://raley.english.ucsb.edu/wp-content2/uploads/234/Mak.pdf\">How the Page Matters</a>. Mak, Bonnie</li>\n\t<li><a href=\"http://vispo.com/bp/introduction.htm\">First Screening</a>. bpNichol</li>\n\t<li><a href=\"http://kairos.technorhetoric.net/12.3/topoi/stolley/\">The Lo-Fi Manifesto</a>. Stolley, Karl</li>\n\t<li><a href=\"http://www.zeldman.com/2012/05/18/web-design-manifesto-2012/\">Web Design Manifesto 2012</a>. Zeldman, Jeffrey</li>\n</ul>\n\n<h2>Resources</h2>\n\n<ul>\n\t<li><a href=\"http://dash.generalassemb.ly\">Dash</a></li>\n\t<li><a href=\"http://jquery.com\">jQuery</a></li>\n\t<li><a href=\"https://github.com/lucaong/jquery-machine\">jQuery-Machine</a></li>\n\t<li><a href=\"https://daneden.me/toast/\">Toast</a></li>\n\t<li><a href=\"http://www.dafont.com/liquid-crystal.font\" title=\"Liquid Crystal\">Liquid Crystal</a></li>\n\t<li><a href=\"http://www.dafont.com/weblysleek-ui.font\" title=\"Webly Sleek\">Webly Sleek</a></li>\n</ul>\n\n<h2 id=\"acknowledgements\">Acknowledgements</h2>\n\n<p>This work was developed for and funded by the Jamie Cassels\nUndergraduate Research Awards program at the University of Victoria.\nThis project would not have been as cool without the support and\nencouragement of Tim Lilburn and Karolinka Zuzalek, with special thanks\nto Patrick Close, Matthew Hooton, Megan Jones, David Leach, Courtney\nLøberg, Garth Martens, Helen Marzolf, Jordan Soles, Valerie Tenning, and\nUVic’s personal web space.</p>\n\n<div class=\"footnotes\" role=\"doc-endnotes\">\n  <ol>\n    <li id=\"fn:1\">\n      <p>By “state,” I mean any three lines that you can see at once. <a href=\"#fnref:1\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:2\">\n      <p>This is a generalization about the literary culture in Victoria,\nBritish Columbia. I do not mean you any offence! <a href=\"#fnref:2\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:3\">\n      <p>I define games as objective- and choice-oriented systems, which\nare primarily unlike to the arts. I find nothing about gameness\ndistasteful, but <em>Sleep when exhausted</em> is not intended to be a\ngame. <a href=\"#fnref:3\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:4\">\n      <p>who deeply hates those awful slideshow-based articles and prefers\nto just scroll down a single webpage. <a href=\"#fnref:4\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:5\">\n      <p>For the JCURA installation, I presented the poem on an Asus Nexus\n7 as a fullscreen application generated by Google Chrome. <a href=\"#fnref:5\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n    <li id=\"fn:6\">\n      <p><em>The Lo-Fi Manifesto</em>. Stolley, Karl. <a href=\"#fnref:6\" class=\"reversefootnote\" role=\"doc-backlink\">&#8617;</a></p>\n    </li>\n  </ol>\n</div>\n"},{"id":"https://benjaminwil.info/antisocial/05","url":"https://benjaminwil.info/antisocial/05","external_url":null,"title":"backfilling my weblog?","summary":"how do you feel about this idea? this is something i did today: i ported all of the reviews from my letterboxd account to...","image":null,"banner_image":null,"date_published":"2010-03-20 19:25:00 -0700","date_modified":"2010-03-20 19:25:00 -0700","tags":[],"language":"en","content_html":"<p>how do you feel about this idea? this is something i did today: i ported all of\nthe reviews from <a href=\"https://letterboxd.com/benjaminwil\">my letterboxd account</a> to\nmy main weblog, here, on benjaminwil.info.</p>\n\n<p>it’s something i’ll continue to think about: it kinda looks like i changed\nhistory, after all. that said… it is content that i wrote on those dates. i\ncould add notes to the posts to contextualize? but my blog isn’t important or\nwidely read anyway.</p>\n"}]}
