Skip to content

John Lam's Blog


Today was talk day in Las Vegas. I will have a lot more details to write about the talk later, but giving this (non-recorded) talk was a super-fun experience both for me, and my co-presenter Alon Bochman. We had a great conversation afterwards, and among the many things we talked about was the importance of Beer Mode to me. I was reminiscing about the early days of the Ruby community that I was so fortunate to have been a part of and how the serendipitous conversations I had at those early RubyConfs forever changed my life.

Speaking of serendipity, Hacker News is one of my best sources for random Beer Mode input. I saw Rockstar: a language for programs that are also hair metal power ballads tonight on HN and in the comments (unlike YouTube, always read the comments on HN), I discovered this incredible talk by Dylan Beattie the guy who spec'd, implemented and performed a program written in Rockstar.

This instantly became one of my favorite talks of all time. It looks at programming as an art form - especially given that all his examples which range from Conway's Game of Life through to the mathematics behind Mendelbrot plots, the esoteric world of programming quines (programs that print themselves as output) and polyquines which are beyond incredible, and finally his performance of a program written in Rockstar.

Watching this reminded me of Giles Bowkett's incredible Archaeopteryx talk that I was fortunate enough to have watched live at RubyConf Salt Lake City almost a decade ago. He was featured recently in another book that I love called So Good They Can't Ignore You by Cal Newport. This is a masterful talk that was also a piece of performance art.

This sent me down memory lane thinking about incredible talks that I have seen in the past. This talk by Guy Steele Jr. was and remains at the top of my list of most incredible performance art talks that I have seen. This also relates somewhat to Ruby as I attended my one and only OOSPLA in 2005 just before I attended my first RubyConf in 2005 as part of a "learning vacation" that I took back then. So good - it starts off super weird but I promise you it's worth sticking through to the end.


I finished implementing the zola serve preview in my vscode-zola VS Code extension. It contains everything that I know (which isn't very much) about writing extensions, JavaScript and TypeScript. I also learned how to package my extension into a VSIX using the vsce tool so now I can write using VS Code and not have to first build and run my extension from another VS Code! If I find that I like how I use it over the next few days, I'll publish it to the VS Code Marketplace and post a link to the zola community. #


I'm getting ready to fly to Las Vegas for my first talk in ages: Train a Kaggle Winner Under $50 on Azure. One thing that I'm planning to share with my audience is this amazing Derek Sivers TED Talk on how to start a movement; it could just as easily be how to start an Open Source project as well!

At my talk, I'm going to be releasing a project that I've been working on for a while: ez that hopefully makes using Azure as a powerful personal computer much easier than it is today.



Beer mode is extremely important to me: it's how I discover new ideas serendipitously. Twitter is a great place for beer mode activities, but it's also a toxic cesspool full of shitposting and virtue signaling. It's entertaining, exhausting, and distracting.

Fortunately, there are a small number of users who consistently post great content focused on an area that I'm interested in. They are, essentially, "professional tweeters". Or, if you prefer terms from a bygone era, they are micro-bloggers.

You can configure tweetdeck, which is the only Twitter client you should use, as it lets you configure exactly how you want to view tweets and you can remove the algorithmic timeline (and ads) from it entirely. At first, I configured tweetdeck to follow individual users which worked great and cut down the noise considerably.

But I still saw replies from those users. While that isn't necessarily a bad thing, it's really random when you see it in a column as the context isn't really there. I really prefer starting from the top of a thread and then seeing any replies that they may be making to other users on their thread. The trick that I learned to do this is to create search columns instead of user columsn. You just need to use this format for the advanced search syntax:

from:user_name -filter:replies

That's it! Here's a screenshot of how this looks in tweetdeck #


Still thinking about how to optimize this blog by capturing screenshots of things like tweets, Instagram posts, or YouTube thumbnails. While it is certainly possible to do all of this manually with existing OS screenshotting tools, it would certainly be more efficient to remove the friction from the process by simply working with links.

An idea that I had this morning was to use a headless browser and some automation to capture tweets, YouTube videos etc. Ideally this is something that can be extensibile by other motivated contributors.

There is some prior art in this area, as this post discusses. There is also a Twitter screenshots Chrome extension by the same guy that created screenshot guru. GH Repo #

David Perell continues to deliver value to me. In this tweet, he advocates for studying debate as a way to better frame ideas. I've long thought about this as "not being mired in the details of an idea", but I can see how this is also about jumping to conclusions. For example focusing on a detail implies you know that the detail is somehow a foregone conclusion already, instead of exploring and convincing others about the problem. Framing the problem is something that I want to get better at, as, as David so concisely describes, "... the highest leverage thing to do".



Today's morning read is a wonderful essay that hit the top of HN titled 100 years of whatever this will be. The key thing that Avery Pennarun talks about is the importance of centralized regulation in distributed systems. He also talks about just how hard it is to build a reliable distributed system from his perspective of being the co-founder of TailScale. He also evokes (with lots of examples) the observation that decentralized markets trend towards chaos over time and why it's important to centrally regulate them.

The job of regulation is to stop distributed systems from going awry. Because distributed systems always go awry.

He references another essay The Tyranny of Structurelessness that says "if you don't have an explicit hierarchy you have an implicit one" and then brilliantly applies it to look at why your distributed system can fail.

The rant about technology at the start is awesome as well, an example:

IT security has become literally impossible: if you install all the patches, you get SolarWinds-style supply chain malware delivered to you automatically. If you don't install the patches, well, that's worse. Either way, enjoy your ransomware.

Worth noting that this is a thinly veiled takedown of the DeFi and crypto movements in general and he accuses them of making handwavy arguments around the reliability of those systems ("it's decentralized so it can't fail!")

Go read it. I'll wait. #

I'm really happy with rebooting this blog using Cloudflare Pages. In an attempt to build a more interesting site with interactive content (e.g., embedded YouTube videos, Twitter and Linked in blocks etc.) I've found that the size of the site (and the bloated-ness) of the site has increased dramatically. It's 100% due to how I'm using JavaScript to embed those external services. This is a report that I just ran this morning:

I think that in the future, I need to teach vscode-zola how to embed an image of, say the YouTube video, the Twitter post or the Instagram post with a link to the original instead of doing these crazy embeddings. The fact that my web page is 6.4MB is inconceivable. #


Continued to listen to Tim's interview with Andrew Chen today and learned about his new book. In the interview he talks about how he uses Twitter as a way to source writing ideas. Tim called it "his MVP for writing" which makes a ton of sense. I also learned that Andrew is writing a new book called the Cold Start Problem (which of course is why he's on Tim's podcast). It also explains why he started the podcast with a great story about how coupons solved the cold start problem from over 100 years ago!

I love how he's building viral promotional campaign for his book.

Step 1: canvas your audience to engage them on the content:

Step 2: publish excerpts on different types of social media to non-overlapping audiences. Update: I just realized that these are stories about companies and not where those excerpts are going to get published (to be fair, I only remembered LinkedIn and YouTube - publishing a chapter on Tinder would be ... interesting 😄). Regardless, I stand by the observation that publishing excerpts on different mediums would be an interesting experiment - YouTube would be interesting.

Step 3: profit! #

Trevor Bedford is one of the best academic sources for information on the SARS-CoV-2 virus on Twitter. Yesterday he published a thread that explains the difference between transmissibility (early results say that Omicron has 3-5X the transmissibility of Delta) and immune escape.

The interesting thing is, that in a heavily vaccinated population, a virus with high immune escape but low intrinsic (R0) transmissibility can out-compete a virus with higher intrinsic transmissibility. This seems to be the case with Omicron based on early data.

But all is not necessarily good here, as high immune escape viruses can target existing vaccinated populations more effectively. #


I like to listen to podcasts during my morning job as an Uber driver for my kids. Today was Andrew Chen being interviewed by Tim Ferris, and in the first 15 minutes there were two wonderful anecdotes from it.

The first is My Life in Advertising which describes some of the origins for common advertising techniques today. One I loved was the story around the invention of the coupon which helped to solve the chicken-and-egg problem that product people had at the turn of the century. Retailers wouldn't stock your product because customers were not asking for it. But customers wouldn't ask for it if they didn't see it on the store shelves. So Claude Hopkins invented the coupon - and ran ads in the local newspaper. Then he would go around to all the different retailers to stock the product and tell them that about the coupon in a future edition of the newspaper and how they would have angry customers trying to redeem the coupon if they didn't buy some stock of the product. Demand generation!

My Life in Advertising Book

The second was how Sean Ellis in the early days of SV startups would go around talking to young founders and explain how he could help them "with their marketing". The negative connotations around the word would invariably send the wrong impression about the work that he really did, which was helping companies grow. So he invented the term "growth hacking" to describe what he does. Brillaint. #

Feature idea: add an last updated (human readable time) byline to the top of the blog. #

Andrew Chen has a blog of sorts, which is now called a "newsletter" these days. For his job as a VC, it's all about the deal flow and writing content helps to attract deal flow. What's cool is that he's been doing it since 2005. A complete list of his essays. #

Shreyas Doshi is one of my favorite people on Twitter, and one that has earned a spot in my TweetDeck columns (I don't use algorithmic feeds for my own sanity). He recently started writing in public about his idea about different types of people in organizations, which led to this excellent summary by Sam Higham:

If I'm honest with myself, I've been in every one of these roles over my career. The other important observation is that a team needs a mix of these people too! #

I cannot resist a great Feynmann story, and this one by Paul Stenhardt on What Impossible Meant to Richard Feynmann was a great story! Impossible to Feynmann is a compliment. Stupid is something applied not just to others but to himself as well.


This is a new post for tomorrow. Placeholder to remind me to fix the timezone bug that let me create this on 11/28 😄 Update: fixed. #

While learning about Jack Twitter's retirement on HN today, I learned about Fenix which looks like a TweetDeck clone with better aesthetics. It's available for iOS iPadOS and MacOS. #

To implement the permalink feature in vscode-zola, I'll need to implement a stateful tera template as described by the docs. It looks pretty straightforward. Done! 😄 #

Nix looks like an interesting tool. I just heard about it from HN in this post by folks talking about Docker vs. Nix. HN comments are pretty critical and damning of the technology. I did not know that it predated Docker by a decade(!)

The claim is that Nix does a better job at reproducible builds. Crucially, Nix does not use containers, rather it does everything by isolating using environment variables. This might be an interesting way to avoid the whole "must install Docker" thing that holds people back from reproducible environments. The team seems focused on moving from Docker to Nix, and providing packages via Nix.

Here's an early post from the team describing how they've been migrating away from a single massive Docker image to using Nix. They make 30,000 packages available in a single 1TB share that is mounted into every container. Users define a shell.nix file that declares dependencies that are then satisfied by the nix-shell tool.

A quick look at this thing though and it appears to be another package system with packages (over 60K) provided by various maintainers. Not sure what the value would be, say, over the official Nvidia pytorch containers, for example. It seems like the risk is not worth it. #


Writing a VS Code extension requires understanding how activation works and where state is stored. The Activation Events page in the documentation has a good explanation of how it works. The default sample uses only the onCommand event binding which is not what I need for my extension (and actually caused me quite a lot of confusion).

Instead, I really need to have it activate when a workspace contains a zola blog. the workspaceContains event uses a glob pattern to look for a file of interest. I think that **/*.config.toml is probably good enough for now, and I could even not activate the extension if I find that it doesn't have the right parameters inside the file. #

vscode-zola now supports emitting shortcodes based on URIs copied from the clipboard. For most cases where I copy a URI for YouTube, Twitter, or Instagram content, the extension will emit the proper zola shortcodes and embed the content within the page, giving a much nicer rendering experience for the reader.

Here's a This Triathlon Life YouTube video that I watched earlier today. Eric and Laura are like characters in a TV show that I watch regularly, usually when I'm riding my bike on the trainer:

Charlie's moved on from Redmond and he's got a temporary home for his cars:

I didn't know this history of grep before - these kinds of stories are what make YouTube great:

Paula vs. Eric in a Specialized Tarmac vs. Epic showdown:


After running this blog on GitHub pages over the weekend, I decided to try something new and created a CloudFlare account. While I was having some troubles with GitHub pages occassionally not rendering correctly (something with the DNS entries not being happy with GitHub), I was more curious about CloudFlare and wanted to try being a customer. So I signed up for the free plan.

There's an interesting gateway drug effect with CloudFlare. After getting a free account and using it to protect this blog on GitHub pages, I learned that I could transfer my domain over to CloudFlare from GoDaddy, the registrar that I've been using for the past decade or so. I was attracted by the wholesale cost pricing of CloudFlare which worked out to less than $9/year to continue to manage my domain (which is now 24 years old!) So I went and initiated the transfer process tonight.

I was also curious about JamStack and CloudFlare Pages. It turns out that there's also built-in support for Zola as well. After some misadventures with version numbers (as of this writing, the only supported version is 0.14.0), I finally got builds up and running.

The experience is identical to GitHub Actions and GitHub Pages - I push to my main branch, and the installed CloudFlare Pages GitHub app handles the build and deployment process into the CloudFlare network. The only thing I noticed is that the container(?) that is used to build takes a long time to initialize compared to GitHub Actions. When I look at the logs, it seems like this container is used not just by zola but it installs other static web site generators like Hugo as well. #

I've got a working version of my first VS Code extension, vscode-zola. I'm using it to write this post now. So far, it supports:

  • Creating a new post
  • Pasting social media URIs and embedding them in the generated page
  • A sort-of working Preview Blog service

I'm a bit torn about how the Preview Blog service should behave - right now I'm imagining that it will work like the way VS Code Markdown Preview works - creating a new pane to the right of the editor that shows the preview with a hot-reload function that refreshes every time you save the markdown file. The existing zola serve command works and does auto-refresh in an external browser window too, and it already supports hot reloading.

Some future features that I want to add include:

  • Paste image functionality similar to how the Paste Image extension works today, but tailored to how my zola blog's needs (specially formed URIs and using the image shortcode).
  • Section permalink - another command that inserts some markdown into the post that generates a # (typically at the end of a logical section) which is also a permalink that users can use to link directly to that part of the post. This is how Scripting News works and I want to make it easy to do so using nothing more than plain-vanilla markdown.



Hello Zola supports the Tera templating engine. Today I'm going to update the way my blog renders by rendering in a continuous style much like how Dave Winer's site works. I like the layout, and I'm hoping to build something out that looks more like this.

I updated it to use two open source fonts from Google: Oswald for headings and Ubuntu for body text. #

This is what Oswald looks like:

This is what Ubuntu looks like:

To make this really work, it's going to need tooling, as there is quite a bit of friction today. The VS Code extension will need to preview output using zola. It will also need to analyze clipboard formats and generate appropriate markup as well. When using zola serve to render the page, the browser window does an auto-refresh of the page when the contents are re-rendered (not quite sure how this happens, but it's cool). Ideally what I do is render that instead of the Markdown Preview pane that VS Code uses today.

If there is an image on the clipboard, much like the Paste Image extension that I'm currently using, it will need to generate some appropriate markup that, roughly speaking looks like with the following escaped by the tera markup charcters:


The extension will also examine URIs pasted to the clipboard, e.g., from YouTube or Twitter, and paste the appropriate shortcodes for those URIs.

So there are a few things that I need to learn:

  1. How to examine the contents of the clipboard in a cross-platform way so that I can serialize binary data for an image into a file.
  2. Have a generic extension that understands how to expand templates based on pattern matches for URIs and uses a template engine to generate text that is pasted into the app.