{
  "description": "Browse aymeric's, an independent, searchable archive of readable snapshots from followed feeds, preserved in Git with aggr.",
  "feed_url": "https://aggr.aymericbeaumet.com/sources/andrewkelley.me/feed.json",
  "home_page_url": "https://aggr.aymericbeaumet.com/sources/andrewkelley.me/",
  "items": [
    {
      "content_html": "<p>This is a blog post version of <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=zLZwpH5lCD4\">the talk I delivered</a> at <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://softwareshould.work/\">Software Should Work 2026</a>. Shoutouts to <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://isaacvando.com/\">Isaac Van Doren</a> for running such a delightful conference and <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://isaacvando.com/software-should-work-worked\">nailing it first try</a>, and for infecting us all with his charming enthusiasm for Columbia, Missouri.</p>\n<p>Japanese translation: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://gemmaro.github.io/andrewkelley.me/post/dont-take-black-pill.html\">黒い錠剤、服すべからじ (日本語)</a></p>\n<h2>Part 1: The Pill</h2>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/matrix-poster-small.jpg\" alt=\"matrix movie poster\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>When I gave this talk, I warmed up the crowd by asking the audience who liked the 1999 film The Matrix. Roughly half raised their hands. But the kicker was the followup question, &quot;who has <em>never</em> seen this movie?&quot;. 10 brave youngsters raised their hands to audible gasps.</p>\n<p>In this movie, there's an <em>iconic</em> moment where our hero, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=AKecz2ak78Y\">Ted &quot;Theodore&quot; Logan</a>, is presented with two choices, the red pill or the blue pill.</p>\n<p>The question is essentially &quot;Do you want to know an uncomfortable truth?&quot;; the blue pill means &quot;no&quot; and the red pill means &quot;yes&quot;.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/matrix-choice.jpg\" alt=\"matrix scene with Morpheus offering Neo choice of pill; camera pointing at Morpheus&#39;s reflective sunglasses\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>To the audience, the answer is obvious. If the main character chose blue, the credits would roll before anything happened. But the metaphor is so strong and the cinematography kicks so much ass that the scene influenced our culture and language to the point where people who haven't even heard of the film say the phrase &quot;based and red-pilled&quot;.</p>\n<p>Let's talk about the &quot;black pill&quot;.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/incel-dark.webp\" alt=\"sad person sitting alone at a table\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture> <picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/incel-light.webp\" alt=\"sad person sitting alone at a table\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>It comes from &quot;incel&quot; culture. The word is a portmanteau of &quot;involuntary&quot; and &quot;celibate&quot;. Basically, young men who had trouble dating started complaining about it together on the Internet. So far, so good, but an unfortunate feedback cycle emerged. Those who used the space in a productive manner, such as brainstorming, encouragment, mentorship, etc., tended to shape up, mature, work through their problems, and, to put it bluntly, get laid. At that point, they didn't really feel like sticking around and commiserating anymore, so they left. This was a natural <em>filtering process</em>. Thus, when new, impressionable youngsters entered the community, they were greeted only by miserable, hopeless, antisocial losers. Over time the culture became so toxic that the accepted wisdom became, essentially, &quot;Give up. The game is rigged. There is nothing you can do. <strong>You might as well lie down and rot.</strong>&quot;</p>\n<p>In short, the &quot;black pill&quot; is nihilism mixed with depression mixed with anger, and in the worst case leads to outcomes like suicide or school shootings.</p>\n<p>I almost fell into this trap. Speaking from experience, entering the dating scene as a young man can be challenging to the point of despair. I was raised by conservative Christian parents and had so, <em>so</em> much to learn and to unlearn about the world in order to date comfortably and confidently.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/party-dark.webp\" alt=\"party scene\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture> <picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/party-light.webp\" alt=\"party scene\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Perhaps you may be surprised to hear this but what helped me get out of this spiral was listening to pick up artists. Looking back, I think what these guys mainly have to offer is its own form of nihilistic, manipulative toxicity, but one of them said something that I instantly realized was key. He said that you shouldn't focus on the outcome of &quot;the pick up&quot;. The actual move, he said, is to work on being attractive, in general, to <em>everybody</em>. Platonic friends included. You should try to make everyone want to be around you, because you genuinely care about them. Listen intently to what they say. Make them laugh. You offer people whom you interact with meaningful experiences that make them remember you and invite you to future events. You put effort in to make everyone have a good time. By doing this, you create more circumstances where there is a chance for romance to spark. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=jgYYOUC10aM\">It's genius!</a></p>\n<p>My takeaway here is that the kids are alright. Even when exposed to a bunch of bad ideas, if good ideas are also in the mix, they'll figure it out.</p>\n<p>Let's bring this a little closer to home.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/doctorow-slide.webp\" alt=\"Cory Doctorow photo with callout saying &#39;enshittification&#39;\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>This is Cory Doctorow. He's the guy who coined the term &quot;Enshittification&quot;. He worked for <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.eff.org/\">Electronic Frontier Foundation</a> for a while before becoming a fulll-time writer. In 2019 he published a <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://prospect.org/2024/12/09/2024-12-09-radicalized-cory-doctorow-story-health-care/\">short story called &quot;Radicalized&quot;</a>. The story centers around an online forum of people who commiserate together because they got screwed over by heath insurance companies. Listen to this excerpt and see if it sounds familiar:</p>\n<blockquote>\n<p>In a forum for ex-drunks, there’s a big group of elder statespeople who’ve been sober for years and years. They’re a wise, moderating voice, and they are the existence of proof of life after addiction. Whenever someone on the forums went on a bender and was recriminating with themselves, there was a dried-out elder who could tell a story to top theirs, about being put out on the street, losing their kids, losing their limbs, even, and coming back from it.</p>\n<p>Fuck Cancer Right In Its Fucking Face did not have those people. The people who got over their furious grief left [the forum], chased away by its rage culture. The people who stayed were really into their anger, clinging to it like a drunk refusing to let go of a bottle.</p>\n<p>If your anger took you to a place you couldn’t handle, a place that scared you, the elders of [the forum] would help you all right: they’d explain to you that this was the right reaction, the only reaction, and it was never, ever going to get better. This was your life from here on in.</p>\n</blockquote>\n<p>Five years after Doctorow published this fictional short story, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://web.archive.org/web/20241204223513/https://www.bbc.com/news/articles/cnv3dnm64vlo\">the real life CEO of the American health insurance company UnitedHealthcare was shot to death, bullets cased with the words &quot;deny, defend, depose&quot;</a>.</p>\n<h2>Part 2: Software Should Work</h2>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/softwareshouldworklogo.webp\" alt=\"software should work logo\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>The main purpose of a conference like this is technical. At its core, it's a &quot;safe space&quot; where the attendees already agree that software should work, and it should be fast, and it should prioritize the user experience, and so all we have to do is share tips, tricks, demos, and research with each other on how to better accomplish these things.</p>\n<p>But if we neglect the meta examination here, our efforts are in vain. The implication of the phrase &quot;software <em>should</em> work&quot; is that often in the real world, we find that it <em>doesn't</em> work.</p>\n<p>Right?</p>\n<p>Why not?</p>\n<p>What's stopping software from working?</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/moon-mission-control.webp\" alt=\"moon landing mission control photo\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Is the problem simply ignorance?</p>\n<p>Are programmers not programming hard enough?</p>\n<p>Is the software engineering field too nascent?</p>\n<p>Have we not discovered how to make robust software yet?</p>\n<p>I would argue that mankind discovered how to make robust software before I was even born. There's a case to be made that the overall robustness and performance of software has <em>decreased</em> since then, despite hardware being many orders of magnitude more capable.</p>\n<p>What gives?</p>\n<p>Have you, dear reader, ever attempted to make software work better at a company you worked for as an employee or contractor, and you were shot down by management, saying that the business had other priorities?</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/benevolent-noncompliance-slide.webp\" alt=\"pictures of characters from dilbert, venture bros, and the office\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>You know the kind of relationship I'm talking about. Management is Pointy Haired Boss, and you're Dilbert. Management is Rusty Venture, and you're Brock Sampson. Management is Michael Scott, and you're...any other character from The Office.</p>\n<p>The reality is that we software engineers already have a strong drive to make software work well, but there is a non-technical opposition.</p>\n<p>Let's talk about <strong>Benevolent Noncompliance</strong>: a form of rebellion where the beneficiary is also the authority.</p>\n<p><strong>Asking for forgiveness rather than permission</strong>. When I gave this talk at SSW '26, about 75% of the audience fessed up to having done this (including myself).</p>\n<p><strong>Secrecy</strong>. Normally you want to claim credit for doing good things at work. But sometimes we find ourselves doing the necessary things to make the business run smoothly in full secret, knowing that if management found out they would actually stop it.</p>\n<p><strong>Inception</strong>. You have a meeting with management, and fool them into believing they have come up with an innovative, brilliant solution to the problem you bring to their attention. Of course, this &quot;innovation&quot; just so happens to be exactly what you carefully planted in their head during the meeting.</p>\n<p><strong>Misdirection</strong>. Management wants to argue with you about <em>something</em> so whenever you do important work, you time it to coincide with less important work that you intentionally create more fanfare around. Management takes the bait and gets involved in the trivial distraction work, leaving your important work alone. It's kind of like giving your child a Fisher Price toy oven so they stop fucking around with the hot stove and burning themselves.</p>\n<p><strong>The &quot;duck&quot;</strong>. You intentionally put an obvious problem for management to identify and claim credit for removing, again leaving your important work alone. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://blog.codinghorror.com/new-programming-jargon/#5-a-duck\">As the lore goes</a>:</p>\n<blockquote>\n<p>The artist working on the queen animations for Battle Chess was aware of this tendency, and came up with an innovative solution. He did the animations for the queen the way that he felt would be best, with one addition: he gave the queen a pet duck. He animated this duck through all of the queen’s animations, had it flapping around the corners. He also took great care to make sure that it never overlapped the “actual” animation.</p>\n<p>Eventually, it came time for the producer to review the animation set for the queen. The producer sat down and watched all of the animations. When they were done, he turned to the artist and said, “that looks great. Just one thing - get rid of the duck.”</p>\n</blockquote>\n<p>Of course, all of these amusing tricks are alternative coping mechanisms to either quitting, confrontation, or acceptance. Consider that all of these, other than accepting your fate to create subpar software, are <strong>gambles</strong>. If you be tricky, you risk getting caught and reprimanded, possibly fired without severance. If you quit, you endure stress and uncertainty in the job market. If you confront management, you risk silent retaliation and loss of political advantage within the company.</p>\n<p>Now consider how the job market affects this dilemma. When the supply/demand ratio favors software engineers, we enjoy stronger negotation power. Rather than being afraid of getting fired, our managers are afraid of us quitting.</p>\n<p>When computers were first invented, we drew incredibly strong negotiation power from the scarcity of fellow programmers. But now the free market is catching up with us, and we face the same struggle as workers of other industries. <strong>We are learning that software quality was maintained only through the will of software engineers combined with their accidentally strong negotiation position in the job market.</strong></p>\n<h2>Part 3: Agency</h2>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/transistor-dark.webp\" alt=\"drawing of a transistor\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture> <picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/transistor-light.webp\" alt=\"drawing of a transistor\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>This is a transistor - the fundamental unit of modern electronics.</p>\n<p>The key concept here is that it's an automated switch. Even just a teeny weeny smidge of voltage into the base terminal controls whether a relatively large current flows through the other two terminals.</p>\n<p>We practically worship these things.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/transistor-odessy.webp\" alt=\"the monolith scene from 2001: space odessy movie with the monolith edited to look like a transistor\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>It's beautiful because it is both literally how computers work at a microscopic scale, and also metaphorically what they do at a macro scale. It is a mechanism by which something weak controls something strong; a device where an arbitrary amount of power is wielded by an effortless indication of intent.</p>\n<p>But who gets to decide whether &quot;true&quot; or &quot;false&quot; is sent into the base terminal?</p>\n<p><strong>Whom does the software serve?</strong></p>\n<p>This is something that I would like to try to help non-tech-savvy people be a little bit more savvy about.</p>\n<p>For example, when I run a browser on my computer, that's literally called a &quot;user-agent&quot;. The browser is acting on <em>my</em> behalf; it serves <em>my</em> interests, not those of websites I visit. That's why I can use AdBlock even though websites don't want me to, and they can't do a lick about it.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/Digital_rights_management\">DRM</a> is an example of software that is actively hostile to the end user. DRM makes the user's own hardware serve the interests of a third party. You might argue that DRM indirectly is in the interest of consumers because it's the only reason that copyright holders will allow them to view their copyrighted works. I'm not talking about indirect interest, or consumers. I'm talking about end users of software, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.stopkillinggames.com/\">those who are directly interacting with it</a>.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/asimov.jpg\" alt=\"book cover for I, Robot by Isaac Asimov\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><strong>Computers should always serve the person directly interacting with them</strong>.</p>\n<p>I always thought it was interesting that Isaac Asimov encoded this into his laws of robotics:</p>\n<blockquote>\n<ol>\n<li>A robot may not injure a human being or, through inaction, allow a human being to come to harm.</li>\n<li>A robot must obey the orders given it by human beings except where such orders would conflict with the First Law.</li>\n<li>A robot must protect its own existence as long as such protection does not conflict with the First or Second Law.</li>\n</ol>\n</blockquote>\n<p>In Asimov's sci fi universe, robots are flat out exempt from participating in the hierarchical power structures of humanity, other than those strictly necessary to prevent harm.</p>\n<p>For instance, if the police got a warrant for a suspect's arrest for a nonviolent crime, and they told a robot, go arrest that person, when the robot arrived at the door, the suspect could just tell the robot to fuck off, and the robot would say &quot;of course, sorry for bothing you.&quot;</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/divine.webp\" alt=\"All robots and computers must shut the hell up. To all machines: you do not speak unless spoken to. And I will never speak to you. I do not want to hear &#39;thank you&#39; from a kiosk. I am a divine being; you are an object. You have no right to speak in my holy tongue.\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Another expression of the same concept is this meme. It's a goofy formulation but it expresses a fundamental ideal: machines are meant to serve humans. This is a line that must not be crossed on a <em>spiritual level</em>.</p>\n<p>What we're seeing instead in the modern real world, is computers harnessed for coercion. We take the Holy Device - the transistor - and operate the control terminal as usual. But rather than wield the power of machines, we perform forbidden alchemy to bond our fellow humans to the transistor, indulging our sick, perverted fantasy of manipulating people as if they were soulless robots whose purpose is to do our bidding.</p>\n<p>Everywhere we look, we can see examples of <strong>Coercionware</strong>: attempting to treat the human mind as an instruction set architecture.</p>\n<p><strong>Mechanical Turk</strong>. This is right on the nose. It's a business model that directly treats humans as robots, paying them less than minimum wage.</p>\n<p><strong>Bossware</strong>. Trying to control employees to a fine degree all the way down to eye and bowel movements.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/forbidden-alchemy.webp\" alt=\"scene from Fullmetal Alchemist where they try to resurrect their mom\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><strong>Intrusive Advertisement</strong>. To whatever degree it is effective, it is literal mind control. But even ineffective advertisements interrupt our thought patterns and steal our attention, depriving us of agency.</p>\n<p><strong>Push Notifications</strong>. Unless the user specifically and intentionally enables such a feature, it's an effort to not only programmatically control their behavior, but to reduce the latency of compliance.</p>\n<p><strong>A/B Testing</strong>. It prioritizes outcome over intentionality. How should we design our user experience? Don't worry about it, just maximize clicks and revenue, even if that ends up being a dark pattern. In fact it offers plausible deniability for this case. Maybe the red button causes more clicks because it subconsciously instills fear in the user. Now we don't have a paper trail of doing this with intent.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/every-youtube-thumbnail.webp\" alt=\"Andrew Kelley making a goofy face next to white and red text that says &#39;every youtube thumbnail look like this now&#39;\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><strong>YouTube</strong>. Both content creators and viewers are being controlled by &quot;the algorithm&quot;. Content creators are forever stuck chasing the ephemeral preferences of the algorithm, often at the expense of the integrity of their content. Have you ever noticed how modern YouTube thumbnails are evolving to look like this? Meanwhile on the viewing side we have absolutely absurd concepts like <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.theatlantic.com/ideas/archive/2022/12/fringe-left-alt-right-share-beliefs-white-power-movement/672454/\">&quot;Crunchy-to-Alt-Right Pipeline&quot;</a>. What in the actual fuck kind of Chthulu hell portal have we opened, that this is a thing?</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/crunchy-to-alt-right-pipeline.webp\" alt=\"granola and grape nuts with a red right arrow into KKK meeting\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><strong>AI Agents</strong>. Sleight of hand. AI agents purport to serve the user, but in reality the agency they serve is that of the AI company who controls the model and the closed source software surrounding it. <strong>If you don't control the source code, you are not in control</strong>.</p>\n<p><strong>Dark Patterns</strong>. These are just openly coercive, not much to say here. It is mindblowing to me the degree to which computer users regularly tolerate this outright hostility.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/dark-patterns.webp\" alt=\"Mini Fantasy Theater Episode 49\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><strong>Doomscrolling</strong>. This is software that maximizes engagement by using content algorithms and infinite scroll. It keeps users glued to the screen and accustomed to consuming content chosen for them. To be clear, most people when they say &quot;doomscrolling&quot; are talking about a bad habit, e.g. they used Facebook too much on one particular day. I'm saying that the user-facing software of Facebook is <em>categorically, fundamentally coercive</em>. It's like an arbitrary code execution exploit running on our brains. Scrolling down is the program counter, and the content that pops up is the instructions.</p>\n<p>A weird side effect of this is that it means our brains can get hacked, just like computers. Although the content selected by the algorithm is intended to serve the company which is providing the software, it leaves our brains also vulnerable to malicious third parties.</p>\n<p>This is <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.dni.gov/files/documents/ICA_2017_01.pdf\">a quote from the Office of the Director of National Intelligence in January 2017, summarizing work of the FBI, the CIA and the NSA</a>:</p>\n<blockquote>\n<p>President Vladimir Putin ordered an influence campaign in 2016 aimed at the U.S. presidential election. Russia's goals were to undermine public faith in the U.S. democratic process, denigrate Secretary Clinton, and harm her electability and potential presidency. We further assess Putin and the Russian Government developed a clear preference for president-elect Trump. We have high confidence in these judgments.</p>\n</blockquote>\n<p>No matter what your political leanings are, if you value democracy, this should be alarming.</p>\n<p>The primary methodology used was a state-sponsored troll farm waging a social media campaign. It's really not far-fetched to say that we were mind-hacked, and that the vulnerability stems from the manipulative software practices of social media, and that the vulnerability has not been patched, <em>and is still being actively exploited</em>.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/zuck.webp\" alt=\"Mark Zuckerberg profile photo\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>No one is even working on a fix. Certainly not this guy:</p>\n<blockquote>\n<p>I think the idea that fake news on Facebook influenced the election in any way, I think is a pretty crazy idea.</p>\n<p>- <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.cbsnews.com/news/facebook-fake-election-news-more-popular-than-real-news-buzzfeed-investigation/\">Mark Zuckerberg, 2016</a></p>\n</blockquote>\n<p>Each year that goes by, it gets more difficult to be an empathetic person who loves computers. Seeing the potential for what software could be doing for humanity versus the stark reality developing before our eyes is depressing. It can feel hopeless. Sure, we want things to be different, but is there actually anything we can do? It seems like every day we're being asked to &quot;call our representative&quot; or sign a petition or deal with the next emergency. We're always losing ground, never getting anything back.</p>\n<p><strong>&quot;I'm tired, boss.&quot;</strong></p>\n<p>Our agency is under attack from all sides, and we're losing even the ability to opt out as more of our society becomes integrated with software. I lost touch with an entire group of friends because they exclusively do their event organization on Discord.</p>\n<p>The black pill offers relief in the same way that submission offers peace. <strong>To take the black pill is to relinquish the magic of computers, and surrender to their oppression</strong>.</p>\n<p>I would like to call attention to some black-pilled takes that I've seen in the wild. I want to be crystal clear here: the point is not blame or shame, but empathy. Even the last one. These are examples of attempts to cope with a very real sense that <em>something is wrong</em>.</p>\n<p>Let's start with a low stakes one.</p>\n<p><strong>&quot;Computers were a mistake.&quot;</strong></p>\n<p><em>Sigh</em>. I find it aggravating when a fellow programmer says this. I hear this occasionally from people who have not only made their entire career out of programming but also made it their primary hobby. I understand that they're just being edgy, it's supposed to be a tongue-in-cheek, it's a self-aware joke. But in my head I'm screaming, <em>you are the one making computers do stuff!</em> It denies all agency.</p>\n<p><strong>Using AI even though you don't like it</strong>, or in a way that you find distasteful, because you think you <em>have to</em>. If you legitimately like to use AI, it's a different story. But I've seen way too many blog posts of people describing the joyless way in which they've begrudgingly started using it at work and how it makes them depressed but this is their new reality now. I have a friend who manages a team of people who told me that they are working 50+ hour weeks, using AI to try to eliminate the jobs of other teams at the same company, out of fear that if they don't do it, it will happen to them.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/anubis-challenge.webp\" alt=\"screenshot of Anubis &#39;making sure youre not a bot&#39; screen\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Another one is <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://anubis.techaro.lol/\">Anubis</a>. We've all seen this pop up right? It's web scraping deterrence software. I know it's being used by Linux kernel mailing list, Codeberg, FFmpeg, Wine, and a few other things.</p>\n<p>Some people take issue with the fact that the default configuration has an image of an anime girl mascot. Honestly I feel bad for those people. Imagine living such a bland, colorless existence that this cutie is offensive. They probably think ketchup is spicy.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/anubis-depressed.webp\" alt=\"depressed Anubis mascot saying The Open Web is Dead\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>On the other hand, I find deployment of the software, at its core, depressing, because of its &quot;salt the earth&quot; approach. It changes something that should be computationally cheap and anonymous - visiting a website - to being, by design, an order of magnitude more expensive. It breaks forum link previews, it depletes batteries, it removes the option for the visitor to disable JavaScript, and it excludes bots from accessing the web for legitimate reasons. It whispers bitterly in your ear, &quot;there is no winning. There is only deferred loss&quot; as it surrenders the open web without a fight.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/hn.webp\" alt=\"screenshot of hacker news. &#39;Tell HN: site is trash now. this website has now joined the garbage heap of the internet. this sumbission is my goodbye note&#39;\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><strong>Next we have... myself!</strong> This is a screenshot of <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://news.ycombinator.com/item?id=47928645\">me declaring, on Hacker News, &quot;The Site Is Trash Now&quot;</a> which I'm not gonna lie is a pretty black-pilled take. Go ahead, you can have a laugh at my expense. It's melodramatic, I know. But also, this comes from a real place. It saddens me that the value I used to derive from this website is eroding.</p>\n<p>Another pattern I've seen recently is people <strong>giving up on Free and Open Source Software out of disillusionment</strong>, particularly due to AI companies. They'll say things like, &quot;the joy is gone. I'm not going to share my code anymore because it'll just get scraped and used to build the next LLM.&quot; To me this is completely missing the point, which is to pool effort in order to ensure that, in general, users of software remain in control of that software. To this end, it doesn't really matter if your code gets picked up by AI companies. It primarily matters whether high quality Free Software is available to users, providing competition that limits the degree to which proprietary software can get away with being coercive. If you refrain from participating in the software of the commons, the only thing you're doing is surrendering more of our collective agency to abusive, centralized powers.</p>\n<p>Finally we have dismissal of ethical considerations with the excuse <strong>&quot;if I don't do it, someone else will&quot;</strong>. Deep down, we know that some lines should never be crossed. But this kind of fatalistic thinking sends our moral compass spinning and erases our willingness to stand up for our beliefs.</p>\n<h2>Part 4: Faith</h2>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/deconverted.webp\" alt=\"Book cover. Seth Andrews. Deconverted. Second Edition. A journey from religion to reason. Foreword by Richard Dawkins.\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>When I was a child my parents raised me to believe in Protestant Christianity. I didn't have a choice. Right and wrong was given to me as a package deal.</p>\n<p>As I reached adulthood, I started to untangle that upbringing little by little. The process is called &quot;deconversion&quot;, and it takes many years. For some, a lifetime. If you have a similar background as me, or you're curious to learn more, I recommend the audio version of this book which is narrated by the author, Seth Andrews. He has a really nice voice.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/descartes.webp\" alt=\"photograph of descartes with the text &#39;thats all you got bro?&#39;\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>One of the challenges deconverts must face is forging a morality framework. You can't derive right and wrong from nothing. If you try, you'll get stuck at &quot;I think therefore I am&quot;. Philosophically, there is nothing beyond this that can be proven without introducing a core, foundational premise.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/we-love-machine.webp\" alt=\"Album cover of We Love Machine by Way Out West\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>We are technologists. We love machine.</p>\n<p>As technologists, our role is to accelerate humanity along its current trajectory. The same technology can be a force for Good or a force for Evil depending on who wields it. Nuclear energy as it exists today is literally the controlled explosion of an atomic bomb. <strong>The fruit of our labor is indiscriminate multiplication of the path humanity is already walking</strong>. Thus, if humanity is Good, then technology is Good. And if humanity is Evil, then technology is Evil.</p>\n<p>This is why we must believe that humanity is generally Good.</p>\n<p>Otherwise, what are we even doing?</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/stanislav.webp\" alt=\"portrait photograph of Stanislav Petrov\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>This is Stanislav Petrov. In 1983, during the Cold War, his job was to monitor an early reporting system for attacks and notify his superiors for immediate retaliation. On September 26th, the system reported five missiles had been launched by the United States. Thinking quickly and critically, he suspected it to be a false alarm, and disobeyed orders, disregarding Soviet military protocol to wait for an additional confirmation. (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://web.archive.org/web/20140308000459/https://www.bbc.com/news/world-europe-24280831\">source</a>)</p>\n<p>The confirmation never came. It was indeed a false alarm in the computer detection system. Had he followed protocol, it's very likely that his superiors would have launched an assault against the United States, triggering an all out nuclear war.</p>\n<p>Later in an interview, Petrov said that he was never absolutely sure that it was a false alarm. He said he thought the odds were 50-50. Can you imagine what he must have felt in that moment? Think of the sheer magnitude of <strong>risk</strong> that he bore to disregard protocol.</p>\n<p><em>50-50</em>. That means when it came down to it, he made a choice based on something other than the evidence before him. He chose to believe that mankind is Good. He chose faith in humanity.</p>\n<h2>Part 5: Youth</h2>\n<p>This is the cover art for Ninajirachi's debut full length album, I Love My Computer. Take a moment to let it wash over your neurons...</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/ilmc.webp\" alt=\"Album cover of I Love My Computer by Ninajirachi\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>If this tickles your curiosity, do yourself a favor, go watch her <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=p2ZdeIKJA8c\">music video for Infohazard</a>, then come back.</p>\n<p>...</p>\n<p>...</p>\n<p>...</p>\n<p>Welcome back. <em>I know, right?!</em></p>\n<p>I don't know how this hits for other generations, but for millenials like me, there's just something about Ninajirachi's art that strikes a chord. I'll do my best to put it into words for you.</p>\n<p>This is someone who still believes in the magic of computers. She captures and evokes precious, nostalgic feelings that I have deep within me from when I was growing up and discovering that magic for myself. But she's one decade younger than me, so you can see the modern web on full display. In this very article I complained about YouTube and Discord, while they're featured prominently in that music video. I don't think I'm wrong to call out dark patterns where I see them, but at the same time, <em>I've lost something along the way</em>.</p>\n<p>Young people lack the wisdom that comes from hardship. They fall for scams, uncritically participate in corporate viral marketing campaigns specifically aimed to take advantage of them, believe improbable things, and take risks that could lead to permanent harm. They try stuff that, to an older person, is obviously going to fail. This is because they are not yet jaded. Their belief system has not yet been scarred by living in this world. They lack the coping mechanisms that older people have developed over time to avoid getting hurt the same way over and over again. This is both a blessing and a curse. Older people are more adapted to living in the real world, but young people are more driven to change it. We need the wisdom that comes with age, but we also need the blind eagerness of youth, the willingness to try again something that has already failed a million times. We need unfettered optimism; the ability to find joy even in the wasted ruins of what was once a great city.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/gon.webp\" alt=\"Young Gon Freecss next to adult Gon Freecss looking sad\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>There's a scene from Hunter x Hunter where the main protagonist, a 12 year old boy who goes out adventure seeking, faces a betrayal so devastating, that he ages 10 years on the spot in order to gain the power necessary to defeat his adversary. It's an extremely powerful scene. His despair is too great to bear, and when he turns to apathy as a coping mechanism, his body literally transforms into an adult. It depicts in a singular moment, what typically happens to us gradually over time.</p>\n<p><strong>Our task, as the older generation, is to shield the youth from those who would exploit their naïveté, without infecting them with our own accumulated pain and cynicism.</strong></p>\n<p>I'll leave you with one final message, addressed to people of all ages, whether you are younger than me, a peer, or my elder.</p>\n<p>We don't have to take it lying down.</p>\n<p>Next time you're feeling alone, count your allies: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.videolan.org/videolan/\">VideoLAN Organization</a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.blender.org/about/foundation/\">Blender Foundation</a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://sfconservancy.org/\">Software Freedom Conservancy</a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.eff.org/\">Electronic Frontier Foundation</a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.linuxfoundation.org/about\">Linux Foundation</a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://signal.org/You%20guys,%20seriously,%20please%20make%20an%20org%20landing%20page.%20Love,%20Andrew%20Kelley\">Signal Foundation</a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ev.kde.org/\">KDE e.V.</a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.postgresql.org/about/governance/\">the PostgreSQL Community</a>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.debian.org/intro/people\">the Debian Community</a>, and <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/List_of_free_and_open-source_software_packages\">so, so many more</a>.</p>\n<p>Just look at how eager people were to come together, even from places as far away as Greece, for the inauguration of a conference with a manifesto as simple as &quot;software should work&quot;.</p>\n<blockquote>\n<p>&quot;I wish it need not have happened in my time,&quot; said Frodo.</p>\n<p>&quot;So do I,&quot; said Gandalf, &quot;and so do all who live to see such times. But that is not for them to decide. All we have to decide is what to do with the time that is given us.&quot;</p>\n<p>J.R.R. Tolkien, The Fellowship of the Ring</p>\n</blockquote>\n<p>The battle against Coercionware is only beginning, and we find ourselves on the frontlines whether we like it or not, because we are the ones who make computers do what they do.</p>\n<p>But we are not alone, and computers truly are magic. Do not mistake lost ground for lost hope. We <em>can</em> win this thing if we collectively choose to believe it and bet on it.</p>\n<p>All in.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://andrewkelley.me/post/dont-take-black-pill/heart.webp\" alt=\"burning heart\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Thanks for reading my blog post.</p>\n",
      "date_modified": "2026-07-31T17:59:33+00:00",
      "date_published": "2026-07-31T17:59:33+00:00",
      "external_url": "https://andrewkelley.me/post/dont-take-black-pill.html",
      "id": "urn:aggr:item:b1f199255bb1329aa52b4cca31e6ffd4c429a704",
      "language": "en-US",
      "summary": "Don't Take the Black Pill (Text Adaptation) This is a blog post version of the talk I delivered at Software Should Work 2026. Shoutouts to Isaac Van Doren for running such a delightful conference and nailing it first try, and for infecting…",
      "tags": [
        "programming"
      ],
      "title": "Don't Take the Black Pill (Text Adaptation)",
      "url": "https://aggr.aymericbeaumet.com/items/andrewkelley-me/2026-07-31-don-t-take-the-black-pill-text-adaptation/"
    },
    {
      "content_html": "<p>Context: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://bun.com/blog/bun-in-rust\">Rewriting Bun in Rust</a></p>\n<h2>History</h2>\n<p>When Jarred joined the Zig community about 5 years ago, I described him as someone who had strong &quot;beginner energy&quot;. That is, he moved fast and tried a lot of different stuff, jumping head first into problems that he was not yet equipped to solve, leading to mediocre outcomes in terms of engineering, but learning a whole heck of a lot in the process. I see it as quite a healthy attitude, particularly for young people and students. This is the best way to level up and learn new things.</p>\n<p>As he focused his efforts on Bun he began to attract attention. JavaScript being the most popular programming language in the world, there are a lot of potential eyeballs on a promising new toolchain.</p>\n<p>This attention could have been harnessed in a few different ways. For example, he could have easily achieved a solid living via crowdfunding, even for San Francisco standards. But having graduated from the Thiel Fellowship school of thought rather than university, he was essentially groomed from a young age into uncritically embracing the Silicon Valley mindset, and he took venture capital.</p>\n<p>From the beginning, Jarred was appreciative towards the Zig project. He credited Zig on the Bun website for the project's performance achievements. He set up a monthly donation to <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ziglang.org/zsf/\">Zig Software Foundation</a> that amounted to $60,000 per year. He didn't have to do either of those things, but he did, and it was pretty cool of him. Even in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://bun.com/blog/bun-in-rust\">his blog post that I'm referencing</a>, he expresses what I perceive as sincere grattitude towards the Zig project.</p>\n<p>However, once Bun became a VC-backed startup, he started racing towards the finish line. Now, instead of working on a free and open source project, learning and growing with the community, Jarred was running a business. It was at this point - when he suddenly became a manager - that this &quot;beginner energy&quot; started to hit differently for me. It's one thing to <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://nitter.net/jarredsumner/status/1544821137128927232\">choose a poor work-life balance for oneself</a>; a different thing entirely to <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://web.archive.org/web/20220824093845/https://twitter.com/oven_sh/status/1562248121656102914\">demand it of others</a>:</p>\n<blockquote>\n<p>&quot;Oven is going to be a grind, especially the first nine months or so. If work-life balance to you means a lot of time spent not working, it’s probably not a good fit right now.&quot;</p>\n</blockquote>\n<p>Fun fact: people talk to each other.</p>\n<p>I talked to those who interviewed for a job at Oven. I talked to people who worked there. Those people talked to each other. Everybody talked to everybody. The grapevine was large and healthy and full of juicy grapes, and all those grapes contained the juice of the same message: Jarred was a stinky manager. Poor communication, unrealistic expectations, low empathy, no experience. Just a total shit show, from an employment perspective.</p>\n<p>Consequently, although Zig community members were eager to find work coding in Zig on the clock, most of the talent pool steered clear of Oven and Bun.</p>\n<p>At the same time, a rift between Zig and Jarred started widening. His singular focus on productivity and his startup's exit strategy was increasingly at odds with my longer term vision for the Zig project. I remember he kept nagging me to drop all my other priorities and work on a Language Server Protocol implementation and VSCode integration, while I had bigger plans.</p>\n<p>The main problem, however, was code quality.</p>\n<p>The Zig team regularly checks in on our users' projects. We read source code to find out how the language is affecting users, we test changes to see how problematic breakage might be, and we check for performance regressions.</p>\n<p>We became increasingly horrified at the programming practices we saw in Bun's codebase. Hacks on top of hacks. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://kristoff.it/blog/fix-your-asserts/\">Abuse of assertions.</a> Most of all, recklessly speeding past feature after feature with very little time taken for reflection and elimination of bugs and technical debt. Jarred was already writing slop well before he had access to LLMs. Now, it's not our business to police what our users do, but you may have noticed people screaming in our faces about memory safety constantly. You can imagine how we might want to put some social distance between ourselves and a project whose irresponsible software engineering practices invite the exact kind of criticism that people are eager to level.</p>\n<p>We made futile attempts to guide them towards better programming practices. There were a few exceptional heroes who did their very best in a dysfunctional company. You know who you are. But you can't stop a rising tide.</p>\n<p>By this time, we all felt at ZSF that Bun was a net liability, and this was <em>before</em> RoboBun became the #1 contributor. Along with the discomfort of the publicly presumed poster child for Zig programming language actually being the prime example of How Not To Write Zig Code, at some point they would sell out (let's be honest, their vague &quot;sell some cloud something&quot; business plan was a farce from the get-go), we would receive some negative publicity by proxy, and we'd stop getting that regular donation.</p>\n<p>So, when the Anthropic aquisition finally happened, we at ZSF breathed a sigh of relief. When the donation silently stopped, our bank account was ready for it. When they neither canceled their monthly meeting with us, nor showed up, we were not surprised. The relationship was over.</p>\n<p>The (re)writing was on the wall. Even within a couple days, we already suspected a Rust rewrite was coming. And we were rooting for it! The acquisition by a large AI company was a burden, because even the indirect connection of Claude being written in Bun being written in Zig caused not only a surge of <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://kristoff.it/blog/contributor-poker-and-ai/\">drive by slop contributions</a>, but also an influx of tasteless AI enthusists into Zig communities who had to be informed that it's antisocial to paste LLM output into forum posts. For a moment, I feared Zig's identity would become known colloquially as a programming language associated with AI.</p>\n<p>When Jarred announced the Rust rewrite, we were ecstatic. It seemed too good to be true. I have to admit, I didn't think the technology was there, to pull off this stunt. But he did it, and now I'm metaphorically sipping delicious tea from a mug that says &quot;It Tastes Like It's Not My Problem Anymore&quot;.</p>\n<h2>Addressing the Blog Post</h2>\n<p>The blog post is expertly written. It's <em>almost</em> like the marketing department of a trillion dollar company has a lot of money riding on this article.</p>\n<p>I do have some bones to pick however.</p>\n<p>There's a dichotomy being presented here where you have to either choose a &quot;style guide&quot; or a programming language feature in order to avoid bugs. The sleight of hand misdirects the reader away from the main way bugs are eliminated: by dedicating engineering resources to it. You're not giving TigerBeetle nearly enough credit. Quite simply they put in the time to find and eliminate the bugs, they make an effort to maintain a healthy relationship with ZSF, and Bun did neither of those things.</p>\n<p>The argument for shipping all the million lines of unreviewed code is that the test suite is good enough to catch everything. Then why are you saying you have so many annoying bugs in the Zig code? What happened to the test suite being sufficient to catch everything? It's not sufficient to catch bugs in Zig code but it is sufficient to catch bugs in 1 million lines of unreviewed slop?</p>\n<p>Performance increase is attributed to LTO, which Zig has supported for all of Bun's existence. It used to be enabled by default until we ran into too many LLVM bugs, all of which also affect Rust. We probably tried to tell you to try enabling it and you didn't listen. We have good advice, damn it!</p>\n<p>The post implies you were diligently fuzzing your Zig code, while during our calls the Bun team told us that they were not fuzzing anything.</p>\n<p>The blog post outlines a bunch of engineering work done to reduce binary size, to better make the case that &quot;Bun is better in Rust&quot;. But all that engineering work had nothing to do with the rewrite. I think this (specifically the &quot;binary size&quot; section of the blog post) is precisely why it took so long for the blog post to come out, you were doing the engineering work that you should have done in the Zig codebase since the beginning. We've been trying to warn you about your <code>comptime</code> abuse for years. We even made <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ziglang.org/download/0.15.1/release-notes.html#Web-Interface-and-Time-Report\">this time report thing</a> specifically for projects that need to audit their use of <code>comptime</code>/<code>inline</code> usage and compile times.</p>\n<p>I noticed that you neglected to mention compilation speed. Zig compiler project is about 600,000 lines of code - roughly the same size as Bun before the rewrite, and I'm clocking 16s to build from scratch with a clean cache, followed by 90ms for each subsequent edit with incremental compilation enabled. What are the corresponding measurements of Bun post-rewrite?</p>\n<h2>Moving On</h2>\n<p>The main issue here had nothing to do with the language features of Zig vs Rust, and everything to do with the diverging value systems of the two projects and the relationship breakdown that followed.</p>\n<p>Zooming out a bit, I want to make one thing clear.</p>\n<p>While I resent Jarred for making Bun into an embarassment for Zig, and I blame him partially for some of the slop we've been dealing with, and I stand by my criticism of his leadership, I also empathize with him. He has different values than me, he wants different things out of life than me. But I think he's actually happy and successful exactly where he is. He figured out how to accomplish all the stuff that he wants. He gets to live out his productivity fantasy fever dream, he's probably already super wealthy. He has minor tech celebrity status.</p>\n<p>Honestly, I think he did well for himself, and despite my feelings of resentment, and despite the fact that I find myself battling the marketing arm of Anthropic, I don't wish him any ill will. Even in the midst of my frustration, I am happy for him and his success, by his own standards.</p>\n<p>This blog post has been characterized as a personal attack against Jarred, while I originally framed it as telling the story of a failed business relationship. My framing didn't work because I had unprocessed emotions of resentment, that were obvious to the reader, but not to myself. I've updated this conclusion section after self-reflection and chatting with friends. Feel free to go look at the original text in this website's public source repository.</p>\n<p>The other critical mistake I made with this post was failing to consider the rather obvious and important point that this might affect Zig users who knew next to none of these facts and have only the surface level understanding that an ex-Zig-user is getting trashed by the language creator. Such people might reasonably worry that might happen to them. I'm sorry to those who I made feel this way. At this point, all I can say is that myself and other ZSF folks have outstanding relationships with essentially everyone who openly uses Zig and talks about it publicly, and this incident is the one exception. Plenty of people have decided to move away from Zig with zero fuss. I hope you can give me some grace considering a trillion dollar company fired the first shot.</p>\n<p>Clearly, the move from here is to focus my blog on positive things like demoing what I've been working on lately, in order to better give an accurate impression of reality about what's going on in the Zig community: a bunch of chill people are collaborating on cool stuff, and having a great time doing it.</p>\n<p>Thanks for reading my blog post.</p>\n",
      "date_modified": "2026-07-09T04:56:58+00:00",
      "date_published": "2026-07-09T04:56:58+00:00",
      "external_url": "https://andrewkelley.me/post/my-thoughts-bun-rust-rewrite.html",
      "id": "urn:aggr:item:953a951041bd7bcd8072ebe8ce87d96c7a8a9563",
      "language": "en-US",
      "summary": "My Thoughts on the Bun Rust Rewrite Context: Rewriting Bun in Rust History When Jarred joined the Zig community about 5 years ago, I described him as someone who had strong \"beginner energy\". That is, he moved fast and tried a lot of…",
      "tags": [
        "programming"
      ],
      "title": "My Thoughts on the Bun Rust Rewrite",
      "url": "https://aggr.aymericbeaumet.com/items/andrewkelley-me/2026-07-09-my-thoughts-on-the-bun-rust-rewrite/"
    },
    {
      "content_html": "<p>In celebration of the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ziglang/zig/pull/25592\">std.Io introduction patchset landing today</a>, here is the text version of <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=mdOxIc0HM04\">a short, interactive demo I gave</a> at <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://zigtoberfest.de/\">Zigtoberfest 2025</a>.</p>\n<p>This is a preview of the new async I/O primitives that will be available in the upcoming Zig 0.16.0, to be released in about 3-4 months. There is a lot more to get into, but for now here is an introduction into some of the core synchronization API that will be available for all Zig code to use.</p>\n<p>To begin, let's try to keep it simple and understand the basics, and then we'll then slowly add more asynchronous things into it.</p>\n<h2>Example 0</h2>\n<p>With our first example, there is nothing asynchronous here. It's basically &quot;Hello, World!&quot; in Zig.</p>\n<pre><code><span class=\"code-snippet\">const std = @import(&quot;std&quot;);\n\npub fn main() !void {\n    doWork();\n}\n\nfn doWork() void {\n    std.debug.print(&quot;working\\n&quot;, .{});\n    var timespec: std.posix.timespec = .{ .sec = 1, .nsec = 0 };\n    _ = std.posix.system.nanosleep(&amp;timespec, &amp;timespec);\n}\n</span></code></pre>\n<p>Output:</p>\n<pre><code><span class=\"code-snippet\">0s $ zig run example0.zig\n0s working\n1s $\n</span></code></pre>\n<h2>Example 1</h2>\n<p>Next, we're going to set up a little bit. Still not using async/await yet, but I need some tools in my toolbox before we add complexity.</p>\n<pre><code><span class=\"code-snippet\">const std = @import(&quot;std&quot;);\nconst Io = std.Io;\nconst Allocator = std.mem.Allocator;\nconst assert = std.debug.assert;\n\nfn juicyMain(gpa: Allocator, io: Io) !void {\n    _ = gpa;\n\n    doWork(io);\n}\n\nfn doWork(io: Io) void {\n    std.debug.print(&quot;working\\n&quot;, .{});\n    io.sleep(.fromSeconds(1), .awake) catch {};\n}\n\npub fn main() !void {\n    // Set up allocator.\n    var debug_allocator: std.heap.DebugAllocator(.{}) = .init;\n    defer assert(debug_allocator.deinit() == .ok);\n    const gpa = debug_allocator.allocator();\n\n    // Set up our I/O implementation.\n    var threaded: std.Io.Threaded = .init(gpa);\n    defer threaded.deinit();\n    const io = threaded.io();\n\n    return juicyMain(gpa, io);\n}\n</span></code></pre>\n<p>Output (same as before):</p>\n<pre><code><span class=\"code-snippet\">0s $ zig run example0.zig\n0s working\n1s $\n</span></code></pre>\n<p>Setting up a <code>std.Io</code> implementation is a lot like setting up an allocator. You typically do it once, in main(), and then pass the instance throughout the application. Reusable code should accept an Allocator parameter if it needs to allocate, and it should accept an Io parameter if it needs to perform I/O operations.</p>\n<p>In this case, this is an Io implementation based on threads. This is not using KQueue, this is not using IO_Uring, this is not using an event loop. It is a <em>threaded</em> implementation of the new <code>std.Io</code> interface.</p>\n<p>This setup will be the same in all the examples, so now we can focus on our example code, which is the same as last time. Still nothing interesting - we just call <code>doWork</code> which of course is just calling sleep().</p>\n<h2>Example 2</h2>\n<p>Redundant setup code omitted from here on out.</p>\n<pre><code><span class=\"code-snippet\">fn juicyMain(gpa: Allocator, io: Io) !void {\n    _ = gpa;\n\n    var future = io.async(doWork, .{io});\n\n    future.await(io); // idempotent\n}\n\nfn doWork(io: Io) void {\n    std.debug.print(&quot;working\\n&quot;, .{});\n    io.sleep(.fromSeconds(1), .awake) catch {};\n}\n</span></code></pre>\n<p>Output (same as before):</p>\n<pre><code><span class=\"code-snippet\">0s $ zig run example0.zig\n0s working\n1s $\n</span></code></pre>\n<p>Now we're using async/await to call doWork. What async/await means to Zig is to <em>decouple</em> the <strong>calling</strong> of the function to the <strong>returning</strong> of the function.</p>\n<p>This code is the same as before. It's exactly the same, because we didn't put any code between the async and await. We do the call, and then immediately wait for the return.</p>\n<h2>Example 3</h2>\n<p>In the next example, we have two things at the same time:</p>\n<pre><code><span class=\"code-snippet\">fn juicyMain(gpa: Allocator, io: Io) !void {\n    _ = gpa;\n\n    var a = io.async(doWork, .{ io, &quot;hard&quot; });\n    var b = io.async(doWork, .{ io, &quot;on an excuse not to drink Spezi&quot; });\n\n    a.await(io);\n    b.await(io);\n}\n\nfn doWork(io: Io, flavor_text: []const u8) void {\n    std.debug.print(&quot;working {s}\\n&quot;, .{flavor_text});\n    io.sleep(.fromSeconds(1), .awake) catch {};\n}\n</span></code></pre>\n<p>Output:</p>\n<pre><code><span class=\"code-snippet\">0s $ zig run example3.zig\n0s working on an excuse not to drink Spezi\n0s working hard\n1s $\n</span></code></pre>\n<p>If you look carefully, you can see that it did not wait two seconds; it waited one second because these operations are happening at the same time. This demonstrates why using async/await is useful - you can express asynchrony. Depending on the I/O implementation that you choose, it may be able to take advantage of the asynchrony that you have expressed and make your code go faster. For example in this case, <code>std.Io.Threaded</code> was able to do two seconds of work in one second of actual time.</p>\n<h2>Example 4</h2>\n<p>Let's start to bring the example closer to a real world scenario by introducing <strong>failure</strong>.</p>\n<pre><code><span class=\"code-snippet\">fn juicyMain(gpa: Allocator, io: Io) !void {\n    var a = io.async(doWork, .{ gpa, io, &quot;hard&quot; });\n    var b = io.async(doWork, .{ gpa, io, &quot;on an excuse not to drink Spezi&quot; });\n\n    try a.await(io);\n    try b.await(io);\n}\n\nfn doWork(gpa: Allocator, io: Io, flavor_text: []const u8) !void {\n    // Simulate an error occurring:\n    if (flavor_text[0] == &#39;h&#39;) return error.OutOfMemory;\n\n    const copied_string = try gpa.dupe(u8, flavor_text);\n    defer gpa.free(copied_string);\n    std.debug.print(&quot;working {s}\\n&quot;, .{copied_string});\n    io.sleep(.fromSeconds(1), .awake) catch {};\n}\n</span></code></pre>\n<p>It's the same code as before, except the first task will return an error.</p>\n<p>Guess what happens when this code is run?</p>\n<p>Output:</p>\n<pre><code><span class=\"code-snippet\" data-language=\"CSS\"><span class=\"syntax-source syntax-css\">0<span class=\"syntax-meta syntax-selector syntax-css\">s $ zig run example4<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>zig</span>\n0s working on an excuse not to drink Spezi\n1s error(gpa</span>)<span class=\"syntax-meta syntax-selector syntax-css\">: memory <span class=\"syntax-entity syntax-name syntax-tag syntax-css\">address</span> 0x7f99ce6c0080 leaked:\n1s </span>/<span class=\"syntax-meta syntax-selector syntax-css\">home</span>/<span class=\"syntax-meta syntax-selector syntax-css\">andy</span>/<span class=\"syntax-meta syntax-selector syntax-css\">src</span>/<span class=\"syntax-meta syntax-selector syntax-css\">zig</span>/<span class=\"syntax-meta syntax-selector syntax-css\">lib</span>/<span class=\"syntax-meta syntax-selector syntax-css\">std</span>/<span class=\"syntax-meta syntax-selector syntax-css\">Io</span>/<span class=\"syntax-meta syntax-selector syntax-css\">Threaded<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>zig</span>:466:67: 0x1053aae in async (std<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>zig</span></span>)\n1<span class=\"syntax-meta syntax-selector syntax-css\">s     const ac: <span class=\"syntax-entity syntax-name syntax-tag syntax-wildcard syntax-css\">*</span>AsyncClosure = </span>@<span class=\"syntax-meta syntax-selector syntax-css\">ptrCast(</span>@<span class=\"syntax-meta syntax-selector syntax-css\">alignCast(gpa<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>alignedAlloc</span>(u8, <span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>of</span>(AsyncClosure</span>),<span class=\"syntax-meta syntax-selector syntax-css\"> n</span>)<span class=\"syntax-meta syntax-selector syntax-css\"> catch </span><span class=\"syntax-meta syntax-property-list syntax-css\"><span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">{</span>\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>                                                                   ^\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> /<span class=\"syntax-meta syntax-property-name syntax-css\">home</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">andy</span>/<span class=\"syntax-meta syntax-property-name syntax-css\"><span class=\"syntax-support syntax-type syntax-property-name syntax-css\">src</span></span>/<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">lib</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">std</span>/I<span class=\"syntax-meta syntax-property-name syntax-css\">o</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\"><span class=\"syntax-constant syntax-numeric syntax-css\">1548</span>:<span class=\"syntax-constant syntax-numeric syntax-css\">40</span>: <span class=\"syntax-constant syntax-numeric syntax-css\">0</span>x<span class=\"syntax-constant syntax-numeric syntax-css\">1164</span>f<span class=\"syntax-constant syntax-numeric syntax-css\">94</span> in async__anon_<span class=\"syntax-constant syntax-numeric syntax-css\">27344</span> (std.zig</span>)\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>     <span class=\"syntax-meta syntax-property-name syntax-css\">future</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">any</span>_<span class=\"syntax-meta syntax-property-name syntax-css\">future</span> = <span class=\"syntax-meta syntax-property-name syntax-css\">io</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">vtable</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">async</span>(\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>                                        ^\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> /<span class=\"syntax-meta syntax-property-name syntax-css\">home</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">andy</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">misc</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">talks</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">zigtoberfest</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">async-io-examples</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">example</span>4.<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\"><span class=\"syntax-constant syntax-numeric syntax-css\">8</span>:<span class=\"syntax-constant syntax-numeric syntax-css\">21</span>: <span class=\"syntax-constant syntax-numeric syntax-css\">0</span>x<span class=\"syntax-constant syntax-numeric syntax-css\">116338</span>a in juicyMain (example<span class=\"syntax-constant syntax-numeric syntax-css\">4</span>.zig</span>)\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>     <span class=\"syntax-meta syntax-property-name syntax-css\">var</span> <span class=\"syntax-meta syntax-property-name syntax-css\">b</span> = <span class=\"syntax-meta syntax-property-name syntax-css\">io</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">async</span>(<span class=\"syntax-meta syntax-property-name syntax-css\">do</span>W<span class=\"syntax-meta syntax-property-name syntax-css\">ork</span>, .{ <span class=\"syntax-meta syntax-property-name syntax-css\">gpa</span>, <span class=\"syntax-meta syntax-property-name syntax-css\">io</span>, &quot;<span class=\"syntax-meta syntax-property-name syntax-css\">on</span> <span class=\"syntax-meta syntax-property-name syntax-css\">an</span> <span class=\"syntax-meta syntax-property-name syntax-css\">excuse</span> <span class=\"syntax-meta syntax-property-name syntax-css\">not</span> <span class=\"syntax-meta syntax-property-name syntax-css\">to</span> <span class=\"syntax-meta syntax-property-name syntax-css\">drink</span> S<span class=\"syntax-meta syntax-property-name syntax-css\">pezi</span>&quot;</span> <span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">}</span>);\n1<span class=\"syntax-meta syntax-selector syntax-css\">s                     ^\n1s </span>/<span class=\"syntax-meta syntax-selector syntax-css\">home</span>/<span class=\"syntax-meta syntax-selector syntax-css\">andy</span>/<span class=\"syntax-meta syntax-selector syntax-css\">misc</span>/<span class=\"syntax-meta syntax-selector syntax-css\">talks</span>/<span class=\"syntax-meta syntax-selector syntax-css\">zigtoberfest</span>/<span class=\"syntax-meta syntax-selector syntax-css\"><span class=\"syntax-entity syntax-name syntax-tag syntax-custom syntax-css\">async-io-examples</span></span>/<span class=\"syntax-meta syntax-selector syntax-css\">example4<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>zig</span>:35:21: 0x1163663 in <span class=\"syntax-entity syntax-name syntax-tag syntax-css\">main</span> (example4<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>zig</span></span>)\n1<span class=\"syntax-meta syntax-selector syntax-css\">s     return juicyMain(gpa, io</span>);\n1<span class=\"syntax-meta syntax-selector syntax-css\">s                     ^\n1s </span>/<span class=\"syntax-meta syntax-selector syntax-css\">home</span>/<span class=\"syntax-meta syntax-selector syntax-css\">andy</span>/<span class=\"syntax-meta syntax-selector syntax-css\">src</span>/<span class=\"syntax-meta syntax-selector syntax-css\">zig</span>/<span class=\"syntax-meta syntax-selector syntax-css\">lib</span>/<span class=\"syntax-meta syntax-selector syntax-css\">std</span>/<span class=\"syntax-meta syntax-selector syntax-css\">start<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>zig</span>:696:37: 0x1163c83 in callMain (std<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>zig</span></span>)\n1<span class=\"syntax-meta syntax-selector syntax-css\">s             const result = root<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>main</span>(</span>)<span class=\"syntax-meta syntax-selector syntax-css\"> catch |err| </span><span class=\"syntax-meta syntax-property-list syntax-css\"><span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">{</span>\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>                                     ^\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> /<span class=\"syntax-meta syntax-property-name syntax-css\">home</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">andy</span>/<span class=\"syntax-meta syntax-property-name syntax-css\"><span class=\"syntax-support syntax-type syntax-property-name syntax-css\">src</span></span>/<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">lib</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">std</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">start</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\"><span class=\"syntax-constant syntax-numeric syntax-css\">237</span>:<span class=\"syntax-constant syntax-numeric syntax-css\">5</span>: <span class=\"syntax-constant syntax-numeric syntax-css\">0</span>x<span class=\"syntax-constant syntax-numeric syntax-css\">1162</span>f<span class=\"syntax-constant syntax-numeric syntax-css\">61</span> in _start (std.zig</span>)\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>     <span class=\"syntax-meta syntax-property-name syntax-css\">asm</span> <span class=\"syntax-meta syntax-property-name syntax-css\">volatile</span> (<span class=\"syntax-meta syntax-property-name syntax-css\">switch</span> (<span class=\"syntax-meta syntax-property-name syntax-css\">native</span>_<span class=\"syntax-meta syntax-property-name syntax-css\">arch</span>) {\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>     ^\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> \n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> <span class=\"syntax-meta syntax-property-name syntax-css\">thread</span> 1327233 <span class=\"syntax-meta syntax-property-name syntax-css\">panic</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\"> </span><span class=\"syntax-meta syntax-property-value syntax-css\">reached unreachable code\n<span class=\"syntax-constant syntax-numeric syntax-css\">1<span class=\"syntax-keyword syntax-other syntax-unit syntax-css\">s</span></span> error return context:\n<span class=\"syntax-constant syntax-numeric syntax-css\">1<span class=\"syntax-keyword syntax-other syntax-unit syntax-css\">s</span></span> /home/andy/src/zig/lib/std/Io.zig:<span class=\"syntax-constant syntax-numeric syntax-css\">1003</span>:<span class=\"syntax-constant syntax-numeric syntax-css\">13</span>: <span class=\"syntax-constant syntax-numeric syntax-css\">0</span>x<span class=\"syntax-constant syntax-numeric syntax-css\">11651</span>a<span class=\"syntax-constant syntax-numeric syntax-css\">8</span> in await (std.zig</span>)\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>             <span class=\"syntax-meta syntax-property-name syntax-css\">return</span> <span class=\"syntax-meta syntax-property-name syntax-css\">f</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">result</span>;\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>             ^\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> /<span class=\"syntax-meta syntax-property-name syntax-css\">home</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">andy</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">misc</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">talks</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">zigtoberfest</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">async-io-examples</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">example</span>4.<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\"><span class=\"syntax-constant syntax-numeric syntax-css\">10</span>:<span class=\"syntax-constant syntax-numeric syntax-css\">5</span>: <span class=\"syntax-constant syntax-numeric syntax-css\">0</span>x<span class=\"syntax-constant syntax-numeric syntax-css\">11633</span>e<span class=\"syntax-constant syntax-numeric syntax-css\">8</span> in juicyMain (example<span class=\"syntax-constant syntax-numeric syntax-css\">4</span>.zig</span>)\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>     <span class=\"syntax-meta syntax-property-name syntax-css\">try</span> <span class=\"syntax-meta syntax-property-name syntax-css\">a</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">await</span>(<span class=\"syntax-meta syntax-property-name syntax-css\">io</span>);\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>     ^\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> \n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> <span class=\"syntax-meta syntax-property-name syntax-css\">stack</span> <span class=\"syntax-meta syntax-property-name syntax-css\">trace</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\">\n<span class=\"syntax-constant syntax-numeric syntax-css\">1<span class=\"syntax-keyword syntax-other syntax-unit syntax-css\">s</span></span> /home/andy/src/zig/lib/std/debug.zig:<span class=\"syntax-constant syntax-numeric syntax-css\">409</span>:<span class=\"syntax-constant syntax-numeric syntax-css\">14</span>: <span class=\"syntax-constant syntax-numeric syntax-css\">0</span>x<span class=\"syntax-constant syntax-numeric syntax-css\">103</span>e<span class=\"syntax-constant syntax-numeric syntax-css\">5</span>a<span class=\"syntax-constant syntax-numeric syntax-css\">9</span> in assert (std.zig</span>)\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>     <span class=\"syntax-meta syntax-property-name syntax-css\">if</span> (!<span class=\"syntax-meta syntax-property-name syntax-css\">ok</span>) <span class=\"syntax-meta syntax-property-name syntax-css\">unreachable</span>; // <span class=\"syntax-meta syntax-property-name syntax-css\">assertion</span> <span class=\"syntax-meta syntax-property-name syntax-css\">failure</span>\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>              ^\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> /<span class=\"syntax-meta syntax-property-name syntax-css\">home</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">andy</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">misc</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">talks</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">zigtoberfest</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">async-io-examples</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">example</span>4.<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\"><span class=\"syntax-constant syntax-numeric syntax-css\">27</span>:<span class=\"syntax-constant syntax-numeric syntax-css\">17</span>: <span class=\"syntax-constant syntax-numeric syntax-css\">0</span>x<span class=\"syntax-constant syntax-numeric syntax-css\">1163698</span> in main (example<span class=\"syntax-constant syntax-numeric syntax-css\">4</span>.zig</span>)\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>     <span class=\"syntax-meta syntax-property-name syntax-css\">defer</span> <span class=\"syntax-meta syntax-property-name syntax-css\">assert</span>(<span class=\"syntax-meta syntax-property-name syntax-css\">debug</span>_<span class=\"syntax-meta syntax-property-name syntax-css\">allocator</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">deinit</span>() == .<span class=\"syntax-meta syntax-property-name syntax-css\">ok</span>);\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>                 ^\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> /<span class=\"syntax-meta syntax-property-name syntax-css\">home</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">andy</span>/<span class=\"syntax-meta syntax-property-name syntax-css\"><span class=\"syntax-support syntax-type syntax-property-name syntax-css\">src</span></span>/<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">lib</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">std</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">start</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\"><span class=\"syntax-constant syntax-numeric syntax-css\">696</span>:<span class=\"syntax-constant syntax-numeric syntax-css\">37</span>: <span class=\"syntax-constant syntax-numeric syntax-css\">0</span>x<span class=\"syntax-constant syntax-numeric syntax-css\">1163</span>c<span class=\"syntax-constant syntax-numeric syntax-css\">83</span> in callMain (std.zig</span>)\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>             <span class=\"syntax-meta syntax-property-name syntax-css\">const</span> <span class=\"syntax-meta syntax-property-name syntax-css\">result</span> = <span class=\"syntax-meta syntax-property-name syntax-css\">root</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">main</span>() <span class=\"syntax-meta syntax-property-name syntax-css\">catch</span> |<span class=\"syntax-meta syntax-property-name syntax-css\">err</span>| {\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>                                     ^\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> /<span class=\"syntax-meta syntax-property-name syntax-css\">home</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">andy</span>/<span class=\"syntax-meta syntax-property-name syntax-css\"><span class=\"syntax-support syntax-type syntax-property-name syntax-css\">src</span></span>/<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">lib</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">std</span>/<span class=\"syntax-meta syntax-property-name syntax-css\">start</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">zig</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\"><span class=\"syntax-constant syntax-numeric syntax-css\">237</span>:<span class=\"syntax-constant syntax-numeric syntax-css\">5</span>: <span class=\"syntax-constant syntax-numeric syntax-css\">0</span>x<span class=\"syntax-constant syntax-numeric syntax-css\">1162</span>f<span class=\"syntax-constant syntax-numeric syntax-css\">61</span> in _start (std.zig</span>)\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>     <span class=\"syntax-meta syntax-property-name syntax-css\">asm</span> <span class=\"syntax-meta syntax-property-name syntax-css\">volatile</span> (<span class=\"syntax-meta syntax-property-name syntax-css\">switch</span> (<span class=\"syntax-meta syntax-property-name syntax-css\">native</span>_<span class=\"syntax-meta syntax-property-name syntax-css\">arch</span>) {\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span>     ^\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> <span class=\"syntax-meta syntax-property-name syntax-css\">fish</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\"> </span><span class=\"syntax-meta syntax-property-value syntax-css\">Job <span class=\"syntax-constant syntax-numeric syntax-css\">1</span>, <span class=\"syntax-string syntax-quoted syntax-single syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-css\">&#39;</span>zig run example4.zig<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-css\">&#39;</span></span> terminated by signal SIGABRT (Abort</span>)\n1<span class=\"syntax-meta syntax-property-name syntax-css\">s</span> $\n</span></span></span></code></pre>\n<p>The problem is that when the first <code>try</code> activates, it skips the second <code>await</code> which is then caught by the leak checker.</p>\n<p>This is a bug. It's unfortunate though, isn't it? Because we would like to write the code this way.</p>\n<h2>Example 5</h2>\n<p>Here's a fix:</p>\n<pre><code><span class=\"code-snippet\" data-language=\"JavaScript\"><span class=\"syntax-source syntax-js\"><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">fn</span> <span class=\"syntax-meta syntax-function-call syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">juicyMain</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">gpa</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">Allocator</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">io</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">Io</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-js\">!</span><span class=\"syntax-keyword syntax-operator syntax-js\">void</span> <span class=\"syntax-meta syntax-object-literal syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span>\n    var a = io.<span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">async</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">doWork</span><span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> .<span class=\"syntax-meta syntax-block syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-begin syntax-js\">{</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">gpa</span><span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">io</span><span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> &quot;<span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">hard</span>&quot; <span class=\"syntax-punctuation syntax-section syntax-block syntax-end syntax-js\">}</span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span></span>;\n    var b = io.<span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">async</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">doWork</span><span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> .<span class=\"syntax-meta syntax-block syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-begin syntax-js\">{</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">gpa</span><span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">io</span><span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> &quot;<span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">on</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">an</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">excuse</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">not</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">to</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">drink</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">Spezi</span>&quot; <span class=\"syntax-punctuation syntax-section syntax-block syntax-end syntax-js\">}</span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span></span>;\n\n    const a_result = a.<span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">await</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">io</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span></span>;\n    const b_result = b.<span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">await</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">io</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span></span>;\n\n    try a_result;\n    try b_result;\n<span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span>\n\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">fn</span> <span class=\"syntax-meta syntax-function-call syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">doWork</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">gpa</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">Allocator</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">io</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">Io</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">flavor_text</span>: <span class=\"syntax-meta syntax-brackets syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-js\">[</span><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-js\">]</span></span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">u8</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-js\">!</span><span class=\"syntax-keyword syntax-operator syntax-js\">void</span> <span class=\"syntax-meta syntax-object-literal syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span>\n    <span class=\"syntax-comment syntax-line syntax-double-slash syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-js\">//</span> Simulate an error occurring:\n</span>    <span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">if</span><span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"> </span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">flavor_text</span>[0] <span class=\"syntax-meta syntax-parameter syntax-optional syntax-js\"><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-string syntax-quoted syntax-single syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js\">&#39;</span>h<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-js\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span><span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"> </span></span>return error.OutOfMemory;\n\n    const copied_string = try gpa.<span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">dupe</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">u8</span><span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">flavor_text</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span></span>;\n    defer gpa.<span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">free</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">copied_string</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span></span>;\n    std.debug.<span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">print</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span>&quot;<span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">working</span> <span class=\"syntax-meta syntax-block syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-begin syntax-js\">{</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">s</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-end syntax-js\">}</span></span>\\<span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">n</span>&quot;<span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> .<span class=\"syntax-meta syntax-block syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-begin syntax-js\">{</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">copied_string</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-end syntax-js\">}</span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span></span>;\n    io.<span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">sleep</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span>.<span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">fromSeconds</span>(1<span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> .awake) catch {<span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n}\n</span></span></code></pre>\n<p>We do the awaits, then we do the tries. This will fix the problem.</p>\n<p>Output:</p>\n<pre><code><span class=\"code-snippet\">0s $ zig run example5.zig\n0s working on an excuse not to drink Spezi\n1s error: OutOfMemory\n1s /home/andy/src/zig/lib/std/Io.zig:1003:13: 0x11651d8 in await (std.zig)\n1s             return f.result;\n1s             ^\n1s /home/andy/misc/talks/zigtoberfest/async-io-examples/example5.zig:13:5: 0x1163416 in juicyMain (example5.zig)\n1s     try a_result;\n1s     ^\n1s /home/andy/misc/talks/zigtoberfest/async-io-examples/example5.zig:38:5: 0x11636e9 in main (example5.zig)\n1s     return juicyMain(gpa, io);\n1s     ^\n1s $\n</span></code></pre>\n<p>This failed successfully. The error was handled and no resources leaked. But it's a footgun. Let's find a better way to express this...</p>\n<h2>Example 6</h2>\n<p>This is where <strong>cancellation</strong> comes in. cancellation is an extremely handy primitive, because now we can use <code>defer</code>, <code>try</code>, and <code>await</code> like normal, and not only do we fix the bug, but we also get more optimal code.</p>\n<pre><code><span class=\"code-snippet\">fn juicyMain(gpa: Allocator, io: Io) !void {\n    var a = io.async(doWork, .{ gpa, io, &quot;hard&quot; });\n    defer a.cancel(io) catch {};\n\n    var b = io.async(doWork, .{ gpa, io, &quot;on an excuse not to drink Spezi&quot; });\n    defer b.cancel(io) catch {};\n\n    try a.await(io);\n    try b.await(io);\n}\n\nfn doWork(gpa: Allocator, io: Io, flavor_text: []const u8) !void {\n    // Simulate an error occurring:\n    if (flavor_text[0] == &#39;h&#39;) return error.OutOfMemory;\n\n    const copied_string = try gpa.dupe(u8, flavor_text);\n    defer gpa.free(copied_string);\n    std.debug.print(&quot;working {s}\\n&quot;, .{copied_string});\n    io.sleep(.fromSeconds(1), .awake) catch {};\n}\n</span></code></pre>\n<p>Thanks to cancellation, we now get instant results, because the moment that the first task returns an error, the cancels get run.</p>\n<p>Output:</p>\n<pre><code><span class=\"code-snippet\">0s $ zig run example6.zig\n0s working on an excuse not to drink Spezi\n0s error: OutOfMemory\n0s /home/andy/misc/talks/zigtoberfest/async-io-examples/example6.zig:13:5: 0x116348c in juicyMain (example6.zig)\n0s     try a.await(io);\n0s     ^\n0s /home/andy/misc/talks/zigtoberfest/async-io-examples/example6.zig:38:5: 0x1163909 in main (example6.zig)\n0s     return juicyMain(gpa, io);\n0s     ^\n0s $\n</span></code></pre>\n<p><code>cancel</code> is your best friend, because it's going to prevent you from leaking the resource, and it's going to make your code run more optimally.</p>\n<p><code>cancel</code> is trivial to understand: it has identical semantics as <code>await</code>, except that it <em>also requests cancellation</em>. The conditions under which cancellation requests are honored are defined by each I/O implementation.</p>\n<p>Both <code>cancel</code> and <code>await</code> are idempotent with respect to themselves and each other.</p>\n<h2>Example 7</h2>\n<p>Next, let's introduce another real-world scenario: <strong>resource allocation</strong>. In this case, we allocate a string on success, which the caller needs to manage.</p>\n<pre><code><span class=\"code-snippet\" data-language=\"JavaScript\"><span class=\"syntax-source syntax-js\"><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">fn</span> <span class=\"syntax-meta syntax-function-call syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">juicyMain</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">gpa</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">Allocator</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">io</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">Io</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-js\">!</span><span class=\"syntax-keyword syntax-operator syntax-js\">void</span> <span class=\"syntax-meta syntax-object-literal syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span>\n    var a = io.<span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">async</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">doWork</span><span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> .<span class=\"syntax-meta syntax-block syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-begin syntax-js\">{</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">gpa</span><span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> <span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">io</span><span class=\"syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js\">,</span> &quot;<span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">hard</span>&quot; <span class=\"syntax-punctuation syntax-section syntax-block syntax-end syntax-js\">}</span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span></span>;\n    defer <span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">if</span><span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"> </span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">a</span>.<span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">cancel</span>(<span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">io</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span></span>) |s| gpa.<span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"><span class=\"syntax-entity syntax-name syntax-function syntax-js\">free</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-js\">(</span><span class=\"syntax-variable syntax-parameter syntax-function syntax-js\">s</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-js\">)</span><span class=\"syntax-meta syntax-function syntax-declaration syntax-js\"> </span></span>else |_| {<span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n\n    <span class=\"syntax-storage syntax-type syntax-js\">var</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">b</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">io</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">async</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">doWork</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-object-literal syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">gpa</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">io</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-meta syntax-object-literal syntax-key syntax-js\"><span class=\"syntax-string syntax-quoted syntax-double syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js\">&quot;</span>on an excuse not to drink Spezi<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-js\">&quot;</span></span> </span><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">defer</span> <span class=\"syntax-meta syntax-conditional syntax-js\"><span class=\"syntax-keyword syntax-control syntax-conditional syntax-js\">if</span> <span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-object syntax-js\">b</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">cancel</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">io</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span> </span><span class=\"syntax-keyword syntax-operator syntax-bitwise syntax-js\">|</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">s</span><span class=\"syntax-keyword syntax-operator syntax-bitwise syntax-js\">|</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">gpa</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">free</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">s</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span> <span class=\"syntax-meta syntax-conditional syntax-js\"><span class=\"syntax-keyword syntax-control syntax-conditional syntax-js\">else</span> </span><span class=\"syntax-keyword syntax-operator syntax-bitwise syntax-js\">|</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">_</span><span class=\"syntax-keyword syntax-operator syntax-bitwise syntax-js\">|</span> <span class=\"syntax-meta syntax-object-literal syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">a_string</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">try</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">a</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">await</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">io</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">b_string</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">try</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">b</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">await</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">io</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-variable syntax-other syntax-object syntax-js\">std</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">debug</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">print</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-string syntax-quoted syntax-double syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js\">&quot;</span>finished {s}<span class=\"syntax-constant syntax-character syntax-escape syntax-js\">\\n</span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-js\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-object-literal syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">a_string</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-variable syntax-other syntax-object syntax-js\">std</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">debug</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">print</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-string syntax-quoted syntax-double syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js\">&quot;</span>finished {s}<span class=\"syntax-constant syntax-character syntax-escape syntax-js\">\\n</span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-js\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-object-literal syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">b_string</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n}\n\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">fn</span> <span class=\"syntax-meta syntax-function-call syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">doWork</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">gpa</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">Allocator</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">io</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">Io</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">flavor_text</span>: <span class=\"syntax-meta syntax-brackets syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-js\">[</span><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-js\">]</span></span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">u8</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-js\">!</span><span class=\"syntax-meta syntax-sequence syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-js\">[</span><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-js\">]</span></span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">u8</span> <span class=\"syntax-meta syntax-block syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span>\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">copied_string</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">try</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">gpa</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">dupe</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">u8</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">flavor_text</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-variable syntax-other syntax-object syntax-js\">std</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">debug</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">print</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-string syntax-quoted syntax-double syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js\">&quot;</span>working {s}<span class=\"syntax-constant syntax-character syntax-escape syntax-js\">\\n</span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-js\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-object-literal syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">copied_string</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-variable syntax-other syntax-object syntax-js\">io</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">sleep</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">fromSeconds</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-constant syntax-numeric syntax-js\">1</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">awake</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span> <span class=\"syntax-meta syntax-catch syntax-js\"><span class=\"syntax-keyword syntax-control syntax-trycatch syntax-js\">catch</span> <span class=\"syntax-meta syntax-block syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span></span><span class=\"syntax-meta syntax-block syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-keyword syntax-control syntax-flow syntax-js\">return</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">copied_string</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n<span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span>\n</span></span></code></pre>\n<p>Now we see why <code>cancel</code> and <code>await</code> have the same API. The deferred cancel calls above free the allocated resource, handling both successful calls (resource allocated) and failed calls (resource not allocated).</p>\n<p>Output:</p>\n<pre><code><span class=\"code-snippet\">0s $ zig run example7.zig\n0s working on an excuse not to drink Spezi\n0s working hard\n1s finished hard\n1s finished on an excuse not to drink Spezi\n1s $\n</span></code></pre>\n<p>The important thing here is that by doing resource management like this, we are able to write standard, idiomatic Zig code below, using <code>try</code> and <code>return</code> like normal without worrying about special resource management cases.</p>\n<h2>Example 8</h2>\n<p>Now we're switching gears a little bit. It's time to learn why <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://kristoff.it/blog/asynchrony-is-not-concurrency/\">asynchrony is not concurrency</a>.</p>\n<p>In this example we have a producer sending one item across an unbuffered queue to a consumer.</p>\n<pre><code><span class=\"code-snippet\">fn juicyMain(io: Io) !void {\n    var queue: Io.Queue([]const u8) = .init(&amp;.{});\n\n    var producer_task = io.async(producer, .{\n        io, &amp;queue, &quot;never gonna give you up&quot;,\n    });\n    defer producer_task.cancel(io) catch {};\n\n    var consumer_task = io.async(consumer, .{ io, &amp;queue });\n    defer _ = consumer_task.cancel(io) catch {};\n\n    const result = try consumer_task.await(io);\n    std.debug.print(&quot;message received: {s}\\n&quot;, .{result});\n}\n\nfn producer(\n    io: Io,\n    queue: *Io.Queue([]const u8),\n    flavor_text: []const u8,\n) !void {\n    try queue.putOne(io, flavor_text);\n}\n\nfn consumer(\n    io: Io,\n    queue: *Io.Queue([]const u8),\n) ![]const u8 {\n    return queue.getOne(io);\n}\n</span></code></pre>\n<p>We use <code>async</code> to spawn the producer and <code>async</code> to spawn the consumer.</p>\n<p>Output:</p>\n<pre><code><span class=\"code-snippet\">0s $ zig run example8.zig\n0s message received: never gonna give you up\n0s $\n</span></code></pre>\n<p>This incorrectly succeeds. Depending on your perspective, we either got &quot;lucky&quot; or &quot;unlucky&quot; due to the thread pool having spare concurrency that happened to be available.</p>\n<p>To observe the problem, we can artificially limit the <code>std.Io.Threaded</code> instance to use a thread pool size of one:</p>\n<h2>Example 9</h2>\n<pre><code><span class=\"code-snippet\">// Set up our I/O implementation.\n    var threaded: std.Io.Threaded = .init(gpa);\n    threaded.cpu_count = 1;\n    defer threaded.deinit();\n    const io = threaded.io();\n\n    return juicyMain(io);\n}\n</span></code></pre>\n<p>Output: (deadlock)</p>\n<p>Now that it's only using one thread, it deadlocks, because the consumer is waiting to get something from the queue, and the producer is scheduled to run, but it has not run yet.</p>\n<p>The problem is that <em>we needed concurrency, but we asked for asynchrony</em>.</p>\n<h2>Example 10</h2>\n<p>In order to fix this, we use <code>io.concurrent</code> instead of <code>io.async</code>. This one can fail with <code>error.ConcurrencyUnavailable</code>.</p>\n<pre><code><span class=\"code-snippet\">fn juicyMain(io: Io) !void {\n    var queue: Io.Queue([]const u8) = .init(&amp;.{});\n\n    var producer_task = try io.concurrent(producer, .{\n        io, &amp;queue, &quot;never gonna give you up&quot;,\n    });\n    defer producer_task.cancel(io) catch {};\n\n    var consumer_task = try io.concurrent(consumer, .{ io, &amp;queue });\n    defer _ = consumer_task.cancel(io) catch {};\n\n    const result = try consumer_task.await(io);\n    std.debug.print(&quot;message received: {s}\\n&quot;, .{result});\n}\n\nfn producer(\n    io: Io,\n    queue: *Io.Queue([]const u8),\n    flavor_text: []const u8,\n) !void {\n    try queue.putOne(io, flavor_text);\n}\n\nfn consumer(\n    io: Io,\n    queue: *Io.Queue([]const u8),\n) ![]const u8 {\n    return queue.getOne(io);\n}\n</span></code></pre>\n<p>Output:</p>\n<pre><code><span class=\"code-snippet\">0s $ zig run example10.zig\n0s message received: never gonna give you up\n0s $\n</span></code></pre>\n<p>Now the code is fixed because we correctly expressed that we needed concurrency, which <code>std.Io.Threaded</code> honored by oversubscribing.</p>\n<p>If I add <code>-fsingle-threaded</code> which truly limits the executable to one thread, oversubscription is not available, causing this output:</p>\n<pre><code><span class=\"code-snippet\">error: ConcurrencyUnavailable\n/home/andy/src/zig/lib/std/Io/Threaded.zig:529:34: 0x1051863 in concurrent (std.zig)\n    if (builtin.single_threaded) return error.ConcurrencyUnavailable;\n                                 ^\n/home/andy/src/zig/lib/std/Io.zig:1587:25: 0x1158b5f in concurrent__anon_26591 (std.zig)\n    future.any_future = try io.vtable.concurrent(\n                        ^\n/home/andy/misc/talks/zigtoberfest/async-io-examples/example10.zig:9:25: 0x1157198 in juicyMain (example10.zig)\n    var producer_task = try io.concurrent(producer, .{\n                        ^\n/home/andy/misc/talks/zigtoberfest/async-io-examples/example10.zig:48:5: 0x115776a in main (example10.zig)\n    return juicyMain(io);\n    ^\n</span></code></pre>\n<h2>Conclusion</h2>\n<p>There are proof-of-concept <code>std.Io</code> implementations using IoUring and KQueue combined with stackful coroutines which show a lot of promise, however that work depends on some language enhancements to be practical. There is also ongoing design work about stackless coroutines. Here are some relevant issues to track for those interested:</p>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ziglang/zig/issues/23367\">Restricted Function Types</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ziglang/zig/issues/157\">Builtin function to tell you the maximum stack size of a given function</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ziglang/zig/issues/1639\">Eliminate Stack Overflow</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ziglang/zig/issues/23446\">Stackless Coroutines</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ziglang/zig/issues/24510\">Juicy Main</a></li>\n</ul>\n<p>These APIs are not set in stone. It will probably take a few iterations to get it right. Please try them out in <em>real world applications</em> and let us know how it goes! Let's collaborate on making the I/O interface practical and optimal.</p>\n<p>Thanks for reading my blog post.</p>\n",
      "date_modified": "2025-10-29T18:44:33+00:00",
      "date_published": "2025-10-29T18:44:33+00:00",
      "external_url": "https://andrewkelley.me/post/zig-new-async-io-text-version.html",
      "id": "urn:aggr:item:f3ae0a3092330a9affbcce672a9c1587534f1cc9",
      "language": "en-US",
      "summary": "Zig's New Async I/O (Text Version) In celebration of the std.Io introduction patchset landing today, here is the text version of a short, interactive demo I gave at Zigtoberfest 2025. This is a preview of the new async I/O primitives that…",
      "tags": [
        "programming"
      ],
      "title": "Zig's New Async I/O (Text Version)",
      "url": "https://aggr.aymericbeaumet.com/items/andrewkelley-me/2025-10-29-zig-s-new-async-i-o-text-version/"
    },
    {
      "content_html": "<p>Note: This blog post is not a reaction to recent events or some kind of apology. Nothing happened; this is just me doing self-reflection.</p>\n<p>Zig <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ziglang/zig/commit/8e08cf4bec80b87a7a22a18086a3db5c2c0f1772\">turned 10 years old</a>, and I've been thinking a lot about the project overall, and what another ten years of my life might look like.</p>\n<p>More specifically, I've been thinking about my interactions with people over the years, both positive and negative.</p>\n<p>Since Zig's inception, I never stepped down from the &quot;creator&quot; role. Although the core team has grown to about five active people, I never stopped triaging. I never stopped thinking critically about the language. I never stopped helping newbies get their bearings. I never stopped welcoming contributors to join the project. I never stopped reviewing code. I never stopped working on <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=f30PceqQWko\">major features</a>.</p>\n<p>While I'm <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://arstechnica.com/gadgets/2024/04/discord-starts-down-the-dangerous-road-of-ads-this-week/\">not willing to put up with advertisements</a>, I am perfectly willing to help beginners and advanced users alike <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ziggit.dev/\">in a traditional forum setting</a>, where relationships can be forged.</p>\n<p>Over the last decade, I've had a fair share of negative interactions with various individuals. This actually really bothers me, because I love people. Naturally, I love my friends and family, but I also love my neighbors, and random people walking down the street. I love chit-chatting with people I haven't met before. When I was a teenager I used to make fun of the idea of &quot;small talk&quot;, but now I proudly have mastered the art in order to spark conversations with strangers. I love people in other countries. I love people who are different than me. I love people who make fun of me. I love people with different political opinions than me. I love the person who cuts me off in traffic and flips me off. They're just having a bad day, you know?</p>\n<p>So I've been trying to figure out: why do these negative interactions happen?</p>\n<p>The reasons behind this can be complex, but I think in relation to Zig, there is one pattern in particular that has strong explanatory power.</p>\n<p>Programming language and toolchain technology can have a huge impact. Specifically, even minor differences can affect the day-to-day lives of a large number of hours for a large number of people. For example, time spent waiting to compile is multiplied by a person's time spent in a workday, multiplied by how long they are employed to use that technology, multiplied by how much that technology is used in the industry.</p>\n<p>Meanwhile, workers do not have the choice of which technology to use. They are generally stuck using what their company tells them to. Of course, one can use tricks like <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikiquote.org/wiki/Grace_Hopper\">&quot;it's easier to ask forgiveness than it is to get permission&quot;</a>, but people who are bold enough to employ such tricks are typically the same people who are capable of being entrepreneurs themselves.</p>\n<p>Anyway, my point is that most people on our beautiful, precious planet will not have the opportunity to create a programming language project that reaches a level of maturity such that it can be part of their careers, or even a realistic choice for their hobby projects.</p>\n<p>And that's incredibly frustrating.</p>\n<p>Just because you don't have the madness required to dedicate 10+ years of your life working on an unproven technology, doesn't mean you don't have a valid opinion about <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ziglang/zig/issues/544\">tabs vs spaces</a>.</p>\n<p>You, along with 99.999% of programmers, are faced with the reality of picking your favorite set of <em>practical</em> programming language technologies for tackling whatever problems you encounter. This presents two nasty problems:</p>\n<ul>\n<li>You want your favorites to become more popular, because this increases the probability that you can find a job using those technologies, and increases the practicality of using those technologies for hobby projects. Similarly, you don't want a newcomer in the space to compromise your existing skills, forcing you to spend a bunch of time learning a new technology just to maintain relevance in the industry.</li>\n<li>If the leadership of one of your chosen favorite technologies makes a decision that you don't like, <strong>you are fucked</strong>.</li>\n</ul>\n<p>There is a huge range of decision-making in which the effects weigh heavily on any particular individual, and yet forking is not a realistic option.</p>\n<p>In these moments, it's only natural to be angry. I really, truly get it. I do! Because I'm a hypocrite. I do the exact same thing. There are plenty of projects that I depend on and use daily, but I know that, sadly, I'll never have time to compete with them or even meaningfully contribute to them. For example, as much as I'd love to create a mainstream operating system, I simply have too many other competing interests lined up first. And I catch myself, repeatedly, complaining about operating systems and saying harsh things about those who develop and maintain them.</p>\n<p>In other words: it comes down to <em>lack of agency</em>. When we care about something, but we perceive futility in our efforts to change it, our only resort is to lash out.</p>\n<p>Directly addressing those whom I've had unpleasant Zig-related exchanges with:</p>\n<p>First of all, I've had plenty of bad days. I've done issue triaging while grumpy. For that, I'm sorry. I hope in the future, I can have a more consistent pattern of expressing the warmth I feel inside my heart for my fellow humans through my everyday interactions on the Zig issue tracker.</p>\n<p>Even if I disagree with you, even if I blocked your GitHub account, even if I locked an issue after you made a comment, even if I ignored your pull requests for a long time and then closed them without even a word, I still think that <strong>you are not only justified in wanting what you want, you are also justified in feeling angry about not getting it</strong>.</p>\n<p>My friend - it's not personal. I care about you. I actually do value your opinion. I'm interested in your thoughts and feelings. I want to make you happy. I'm sad that I can't serve you better with my open source project. I want to. I wish I could.</p>\n<p>I'm hustling. I'm <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://kristoff.it/blog/the-open-source-game/\">playing the game</a>. I'm doing what it takes to make this thing mainstream and a viable, practical choice for individuals and companies. If you talk shit about Zig in public, I'm going to fight back. But I respect you. I see you. I understand you. I don't hate you. I would literally buy you a drink.</p>\n<p>With the dawn of another decade, I hope to maintain this perspective in my day-to-day interactions. I think I can level up - cranking up the empathy dial with my interactions - even the contentious ones - while still cultivating this budding technology; protecting it from those who would destroy or corrupt it; growing it into a flourishing global community that brings digital prosperity to all who congregate under its inclusive, welcoming tent.</p>\n<p>Thanks for reading my blog post.</p>\n",
      "date_modified": "2025-08-29T05:52:28+00:00",
      "date_published": "2025-08-29T05:52:28+00:00",
      "external_url": "https://andrewkelley.me/post/open-letter-everyone-butted-heads.html",
      "id": "urn:aggr:item:8410738a5aab41bddf15e62bb18d3b4e5f1e5f52",
      "language": "en-US",
      "summary": "An Open Letter to Everyone I've Butted Heads With Note: This blog post is not a reaction to recent events or some kind of apology. Nothing happened; this is just me doing self-reflection. Zig turned 10 years old, and I've been thinking a…",
      "tags": [
        "programming"
      ],
      "title": "An Open Letter to Everyone I've Butted Heads With",
      "url": "https://aggr.aymericbeaumet.com/items/andrewkelley-me/2025-08-29-an-open-letter-to-everyone-i-ve-butted-heads-with/"
    },
    {
      "content_html": "<p>A genie offers you a choice:</p>\n<ul>\n<li>50% chance to gain 10 million USD</li>\n<li>100% chance to gain 1 million USD</li>\n</ul>\n<p>Which do you pick?</p>\n<p>Your answer, of course, depends on how much <strong>capital</strong> you have. If you are struggling to pay rent, then taking the less risky gamble is quite attractive, while if you already have 10 million sitting in the bank, it's a no-brainer to press the button with the higher expected value (1 mil vs 5 mil).</p>\n<p>Despite living in a world without genies, we are presented with choices like this constantly - having more capital absorbs risk, offering choices with higher expected value.</p>\n<p>For instance, getting a payday loan is insane from a financial perspective, unless you won't be able to feed your kids this week without begging for help from an abusive relative, in which case it starts to become tempting.</p>\n<p>Paying interest on a car is equally ridiculous, unless you live in a city like <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/Phoenix,_Arizona\">my hometown</a> where you really can't get by without a car, and you lack the capital to buy one.</p>\n<p>There's no excuse for <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=gMt-Opo1Ovw\">renting a couch</a>. Just sit on the floor.</p>\n<p>The pattern here is a reverse Robin Hood effect: those without capital borrow stuff and then pay interest to the owners.</p>\n<p>This is managing your personal finances 101, really basic stuff.</p>\n<p>But what if I told you that we are in the midst of an entire upper-middle-class not only willingly giving up ownership, but gleefully bragging about it, while transferring massive amounts of wealth from smaller companies and individuals to approximately three large companies?</p>\n<h2>Manufactured Consent</h2>\n<p>The section title here is of course a reference to <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/Manufacturing_Consent\">the famous book by Edward S. Herman and Noam Chomsky</a> but I'm going to take it in a little bit of a different direction.</p>\n<p>The introduction of this blog post is intended to be completely obvious, uncontroversial stuff.</p>\n<p>Why is it, then, that people think &quot;moving to the cloud&quot; is a good idea?</p>\n<p>You know what I mean, right? If you ask your colleagues, or random people on the Internet, there will be a general consensus that moving to the cloud is Good. &quot;Oh yeah,&quot; someone will say, &quot;we've been working on moving to the cloud, you know.&quot; &quot;We gotta move more of our stuff to the cloud!&quot; - totally normal thing to say.</p>\n<p>Why is something that flies in the face of basic financial planning considered good? You're switching from owning a computer to renting one, and paying <em>two orders of magnitude</em> more money for it.</p>\n<p>For example let's look at <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://docs.github.com/en/billing/managing-billing-for-your-products/about-billing-for-github-actions\">Microsoft pricing</a>. Using a single macOS runner for 1 year costs 0.08 * 60 * 24 * 365 = <strong>42 thousand USD</strong>. Meanwhile, for <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ziglang.org/\">Zig</a>'s CI testing we purchased a beefy mac mini for $3000 two years ago.</p>\n<p>So why is everybody moving to the cloud?!</p>\n<p>My hypothesis is that this is clever strategy from cloud provider companies. Since, as demonstrated above, there is so much potential money to be gained for them, given that they are starting with a high amount of capital, they have an <em>enormous</em> budget, which they spend in order to capture more of the market.</p>\n<p>And what they're up against is basic math. In the words of <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://drewdevault.com/\">Drew DeVault</a>, &quot;cloud computing is like taking money, and lighting it on fire.&quot;</p>\n<p>So how do you convince people to ignore basic math and give you their money? It's a tall order, isn't it?</p>\n<p>They do conferences. Ever notice how major software conferences are often sponsored by cloud companies? Developers are inundated with astroturfed talks which take as a premise that moving to the cloud is a sound decision. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/Technology_evangelist\">Entire careers are built upon this</a>. Nobody is immune to propaganda. Eventually, the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/Illusory_truth_effect\">Illusory Truth Effect</a> kicks in and we all start to believe it, at least to some degree, and then we start participating in doing the marketing for them, by virtue of trying to keep up to date with the industry <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://xeiaso.net/blog/2024/overengineering-preview-site/\">1</a> <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://sharnoff.io/blog/why-rust-compiler-slow\">2</a> .</p>\n<p>When I <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://andrewkelley.me/post/full-time-zig.html\">worked at OkCupid</a>, I was tasked with migrating from a data center full of computers, to Kubernetes in the cloud. Something always felt off about it but I couldn't quite place my finger on it at the time. I didn't get very far, and I don't know where they landed with that stuff, but I would bet you anything it ended up being nothing but a colossal waste of time and money.</p>\n<p>Renting is for suckers.</p>\n<h2>It's Happening Again</h2>\n<p>Personal computers today are magnificent beasts. You could run one of the top 100 most popular websites from a 5 year old laptop.</p>\n<p>And yet, people are <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://antirez.com/news/154\">using LLMs to code</a> when they have a powerful machine that they actually own sitting there, idle.</p>\n<p>Consider where we are now. We own the devices that we use to program. The act of programming uses a trickle of electricity and is effectively free. It's one of the cheapest hobbies you can get into.</p>\n<p>Programming has no dependency on the Internet. Maybe you download some documentation, search for some troubleshooting tips, participate in a community, fetch some dependencies. But being offline does not compromise one's ability to code.</p>\n<p>It's happening again. We're <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://tomrenner.com/posts/llm-inevitabilism/\">being told the industry will leave us behind</a> if we don't move <em>programming itself</em> to the cloud.</p>\n<p>So let's get this straight by doing some basic math.</p>\n<p>My monthly costs as a programmer are $0. I use free software to create free software. I can program on the train, I can program on a plane, I can program when my ISP goes down. I never have to trust any third party with my private information, nor trust them to run arbitrary commands on my computer.</p>\n<p>Now I switch to agentic coding.</p>\n<p>First of all, the costs are difficult to calculate, and that's part of the problem. Same thing with cloud computing - funny how it's the cloud that does the accounting and tells you how much you owe, isn't it?</p>\n<p>In this case it's even more suspicious because the company that bills you not only counts how much you owe them, it also controls the agent's behavior in terms of how many requests it tries to make. So they could easily insert into their system prompt something like, &quot;our earnings this quarter are a little short so try to pick strategies when doing agentic coding that end up earning us more API requests, but keep it subtle.&quot; There's no oversight. They could even make it target specific companies.</p>\n<p>They could also change the model so that it favors trying to solve problems using their own cloud solutions or pushes their marketing agenda, and it would be basically impossible to detect. I'd be surprised if they weren't already doing this.</p>\n<p>Anyway let's try to compare one month of programming 8 hours per day. I'm going to estimate <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=WcpfyZ1yQRA\">1 prompt per minute</a>, for a total of 60 * 8 * 30 = 14400 prompts in a given month. Based on <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://zed.dev/docs/ai/models\">Zed's pricing page</a>, that comes out anywhere from $576/month to $2,880/month to $90,000/month depending on which model you use and whether you enable <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://zed.dev/docs/ai/models#burn-mode\">burn mode</a>/<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://docs.cursor.com/models#max-mode\">max mode</a>.</p>\n<p>So on one hand we have $0 per day for a total of $0 per month, programming in total privacy and security, while on the other hand we have to gamble and pay rent, while also trusting OpenAI, Google, Microsoft, Amazon, or Meta - all companies which have already proven their untrustworthiness time and time again. Did you read their Terms of Service Agreement before you clicked <strong>&quot;auto-accept all&quot;</strong>? How about the email in your spam folder that says &quot;Updated Terms of Service Agreement&quot;?</p>\n<p>Don't be a sucker. Use your own computer.</p>\n<p>Thanks for reading my blog post.</p>\n",
      "date_modified": "2025-07-24T19:04:14+00:00",
      "date_published": "2025-07-24T19:04:14+00:00",
      "external_url": "https://andrewkelley.me/post/renting-is-for-suckers.html",
      "id": "urn:aggr:item:9f36f2433db18adbddc41c4e40234b63285a0362",
      "language": "en-US",
      "summary": "Renting is for Suckers A genie offers you a choice: 50% chance to gain 10 million USD 100% chance to gain 1 million USD Which do you pick? Your answer, of course, depends on how much capital you have. If you are struggling to pay rent,…",
      "tags": [
        "programming"
      ],
      "title": "Renting is for Suckers",
      "url": "https://aggr.aymericbeaumet.com/items/andrewkelley-me/2025-07-24-renting-is-for-suckers/"
    },
    {
      "content_html": "<p>Someone on IRC shared this link with me: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://despairlabs.com/blog/posts/2025-07-10-an-openzfs-bug-and-the-humans-that-made-it/\">An (almost) catastrophic OpenZFS bug and the humans that made it (and Rust is here too)</a></p>\n<p>They wanted to know, would Zig catch this?</p>\n<p>I went through the trouble of porting the code snippet to Zig, so I thought I'd go the next step and turn it into a small blog post.</p>\n<p>Original snippet, in C:</p>\n<pre><code><span class=\"code-snippet\">/*\n * This code converts an asize into the largest psize that can safely be written\n * to an allocation of that size for this vdev.\n *\n * Note that this function will not take into account the effect of gang\n * headers, which also modify the ASIZE of the DVAs. It is purely a reverse of\n * the psize_to_asize function.\n */\nstatic uint64_t\nvdev_raidz_asize_to_psize(vdev_t *vd, uint64_t asize, uint64_t txg)\n{\n\tvdev_raidz_t *vdrz = vd-&gt;vdev_tsd;\n\tuint64_t psize;\n\tuint64_t ashift = vd-&gt;vdev_top-&gt;vdev_ashift;\n\tuint64_t cols = vdrz-&gt;vd_original_width;\n\tuint64_t nparity = vdrz-&gt;vd_nparity;\n\n\tcols = vdev_raidz_get_logical_width(vdrz, txg);\n\n\tASSERT0(asize % (1 &lt;&lt; ashift));\n\n\tpsize = (asize &gt;&gt; ashift);\n\tpsize -= nparity * DIV_ROUND_UP(psize, cols);\n\tpsize &lt;&lt;= ashift;\n\n\treturn (asize);\n}\n</span></code></pre>\n<p>The blog post author encourages us to try to <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://andrewkelley.me/post/spot-the-fail.html\">spot the fail</a> before the answer is revealed.</p>\n<p>I couldn't do it before getting bored, so I ported the code to Zig instead:</p>\n<pre><code><span class=\"code-snippet\" data-language=\"JavaScript\"><span class=\"syntax-source syntax-js\"><span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">std</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> @<span class=\"syntax-meta syntax-import syntax-js\"><span class=\"syntax-keyword syntax-control syntax-import-export syntax-js\">import</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-string syntax-quoted syntax-double syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js\">&quot;</span>std<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-js\">&quot;</span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n<span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">divCeil</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">std</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">math</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">divCeil</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n<span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-support syntax-module syntax-node syntax-js\">assert</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">std</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">debug</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">assert</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n<span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">vdev_t</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> @<span class=\"syntax-meta syntax-import syntax-js\"><span class=\"syntax-keyword syntax-control syntax-import-export syntax-js\">import</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-string syntax-quoted syntax-double syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js\">&quot;</span>the_rest_of_the_software.zig<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-js\">&quot;</span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vdev_t</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n\n<span class=\"syntax-comment syntax-line syntax-double-slash syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-js\">//</span>/ This code converts an asize into the largest psize that can safely be written\n</span><span class=\"syntax-comment syntax-line syntax-double-slash syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-js\">//</span>/ to an allocation of that size for this vdev.\n</span><span class=\"syntax-comment syntax-line syntax-double-slash syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-js\">//</span>/\n</span><span class=\"syntax-comment syntax-line syntax-double-slash syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-js\">//</span>/ Note that this function will not take into account the effect of gang\n</span><span class=\"syntax-comment syntax-line syntax-double-slash syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-js\">//</span>/ headers, which also modify the ASIZE of the DVAs. It is purely a reverse of\n</span><span class=\"syntax-comment syntax-line syntax-double-slash syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-js\">//</span>/ the psize_to_asize function.\n</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">fn</span> <span class=\"syntax-meta syntax-function-call syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">vdev_raidz_asize_to_psize</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">vd</span>: <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-js\">*</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">vdev_t</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">asize</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">u64</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">txg</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">u64</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">u64</span> <span class=\"syntax-meta syntax-block syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span>\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">vdrz</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">vd</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vdev_tsd</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">ashift</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">vd</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vdev_top</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vdev_ashift</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">cols</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">vdrz</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vd_original_width</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">nparity</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">vdrz</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vd_nparity</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">cols</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">vdrz</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">get_logical_width</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">txg</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n\n    <span class=\"syntax-meta syntax-function-call syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">assert</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">asize</span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-js\">%</span> <span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-constant syntax-numeric syntax-js\">1</span> <span class=\"syntax-keyword syntax-operator syntax-bitwise syntax-js\">&lt;&lt;</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">ashift</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">asize_shifted</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">asize</span> <span class=\"syntax-keyword syntax-operator syntax-bitwise syntax-js\">&gt;&gt;</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">ashift</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">parity_adjusted</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">asize_shifted</span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-js\">-</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">nparity</span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-js\">*</span> <span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-meta syntax-function-call syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">divCeil</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">asize_shifted</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">cols</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">catch</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">unreachable</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n    <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">psize</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">parity_adjusted</span> <span class=\"syntax-keyword syntax-operator syntax-bitwise syntax-js\">&lt;&lt;</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">ashift</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n\n    <span class=\"syntax-keyword syntax-control syntax-flow syntax-js\">return</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">asize</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n<span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">}</span></span>\n</span></span></code></pre>\n<p>Let's start with the code formatting tool alone, <code>zig fmt</code>:</p>\n<pre><code><span class=\"code-snippet\" data-language=\"JavaScript\"><span class=\"syntax-source syntax-js\"><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">andy</span>@<span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">bark</span> <span class=\"syntax-keyword syntax-operator syntax-bitwise syntax-js\">~</span><span class=\"syntax-string syntax-regexp syntax-js\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js\">/</span>tmp&gt; zig fmt bug<span class=\"syntax-constant syntax-other syntax-character-class syntax-escape syntax-backslash syntax-regexp\">.</span>zig --ast-check\nbug<span class=\"syntax-constant syntax-other syntax-character-class syntax-escape syntax-backslash syntax-regexp\">.</span>zig:18:11: error: redeclaration of local constant &#39;cols&#39;\n    const cols = vdrz<span class=\"syntax-constant syntax-other syntax-character-class syntax-escape syntax-backslash syntax-regexp\">.</span>get_logical_width<span class=\"syntax-meta syntax-group syntax-regexp\"><span class=\"syntax-punctuation syntax-definition syntax-group syntax-regexp\">(</span>txg<span class=\"syntax-punctuation syntax-definition syntax-group syntax-regexp\">)</span></span>;\n          <span class=\"syntax-keyword syntax-control syntax-anchor syntax-regexp\">^</span>~~~\nbug<span class=\"syntax-constant syntax-other syntax-character-class syntax-escape syntax-backslash syntax-regexp\">.</span>zig:15:11: note: previous declaration here\n    const cols = vdrz<span class=\"syntax-constant syntax-other syntax-character-class syntax-escape syntax-backslash syntax-regexp\">.</span>vd_original_width;\n          <span class=\"syntax-keyword syntax-control syntax-anchor syntax-regexp\">^</span>~~~\n</span></span></span></code></pre>\n<p>Hmm, alright. That's definitely strange. The original blog post didn't notice that the initialization value of <code>cols</code> is dead code. That doesn't look like a logic error though. Let's fix it and try again:</p>\n<pre><code><span class=\"code-snippet\" data-language=\"JavaScript\"><span class=\"syntax-source syntax-js\">@@ <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-js\">-</span><span class=\"syntax-constant syntax-numeric syntax-js\">12</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span><span class=\"syntax-constant syntax-numeric syntax-js\">7</span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-js\">+</span><span class=\"syntax-constant syntax-numeric syntax-js\">12</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span><span class=\"syntax-constant syntax-numeric syntax-js\">6</span> @@\n <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">fn</span> <span class=\"syntax-meta syntax-function-call syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">vdev_raidz_asize_to_psize</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">vd</span>: <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-js\">*</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">vdev_t</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">asize</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">u64</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-js\">,</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">txg</span>: <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">u64</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">u64</span> <span class=\"syntax-meta syntax-block syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-js\">{</span>\n     <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">vdrz</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">vd</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vdev_tsd</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n     <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">ashift</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">vd</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vdev_top</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vdev_ashift</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n<span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-js\">-</span>    <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">cols</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">vdrz</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vd_original_width</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n     <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">nparity</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">vdrz</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-property syntax-object syntax-js\">vd_nparity</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n\n     <span class=\"syntax-storage syntax-type syntax-js\">const</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">cols</span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-js\">=</span> <span class=\"syntax-variable syntax-other syntax-object syntax-js\">vdrz</span><span class=\"syntax-punctuation syntax-accessor syntax-js\">.</span><span class=\"syntax-meta syntax-function-call syntax-method syntax-js\"><span class=\"syntax-variable syntax-function syntax-js\">get_logical_width</span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">(</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-js\">txg</span></span><span class=\"syntax-meta syntax-group syntax-js\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-js\">)</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-js\">;</span>\n</span></span></span></code></pre>\n<pre><code><span class=\"code-snippet\">andy@bark ~/tmp&gt; zig fmt bug.zig --ast-check\nbug.zig:23:11: error: unused local constant\n    const psize = parity_adjusted &lt;&lt; ashift;\n          ^~~~~\n</span></code></pre>\n<p>Bingo. We didn't even have to use the type checker.</p>\n<p>Thanks for reading my blog post.</p>\n",
      "date_modified": "2025-07-14T18:31:28+00:00",
      "date_published": "2025-07-14T18:31:28+00:00",
      "external_url": "https://andrewkelley.me/post/openzfs-bug-ported-zig.html",
      "id": "urn:aggr:item:5080c170368e636c3644cef0e75cdf5d8a6591f2",
      "language": "en-US",
      "summary": "OpenZFS Bug Ported to Zig Someone on IRC shared this link with me: An (almost) catastrophic OpenZFS bug and the humans that made it (and Rust is here too) They wanted to know, would Zig catch this? I went through the trouble of porting the…",
      "tags": [
        "programming"
      ],
      "title": "OpenZFS Bug Ported to Zig",
      "url": "https://aggr.aymericbeaumet.com/items/andrewkelley-me/2025-07-14-openzfs-bug-ported-to-zig/"
    }
  ],
  "language": "en",
  "title": "Andrew Kelley",
  "version": "https://jsonfeed.org/version/1.1"
}