<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>tristanpemble.com - tristanpemble</title>
    <subtitle>Writings by Tristan Pemble</subtitle>
    <link href="https://tristanpemble.com/atom.xml" rel="self" type="application/atom+xml"/>
    <link href="https://tristanpemble.com/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-02-09T00:00:00+00:00</updated>
    <id>https://tristanpemble.com/atom.xml</id>
    <entry xml:lang="en">
        <title>quiz: a vibecoded QUIC library in Zig</title>
        <published>2026-02-09T00:00:00+00:00</published>
        <updated>2026-02-09T00:00:00+00:00</updated>
        <author>
            <name>Tristan Pemble</name>
        </author>
        <link rel="alternate" href="https://tristanpemble.com/quiz-a-vibecoded-quic-library-in-zig/" type="text/html"/>
        <id>https://tristanpemble.com/quiz-a-vibecoded-quic-library-in-zig/</id>
        <content type="html">&lt;p&gt;I know, I know. I promise I will explain myself, but before I do, I need to set the stage. That said, if that title did not make you spit out your drink, you might want to reflect on that.&lt;&#x2F;p&gt;
&lt;p&gt;Yes, this post was written with my own feeble brain. No, I do not look forward to comments by people who haven’t read it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;on-coding-agents&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#on-coding-agents&quot; aria-label=&quot;Anchor link for: on-coding-agents&quot;&gt;On coding agents&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I feel like every one of these articles starts with staking some flag in the ground for or against LLM agents, specifically in terms of software development. Usually that comes with some peacock puffing on morals that I don’t find very interesting.&lt;&#x2F;p&gt;
&lt;p&gt;If you must know, I find it all mildly amusing. I enjoy seeing people lose their mind at what they perceive they are now capable of, and the potential of the technology. I equally enjoy other people shouting at those people about actually realized returns, S-curves, hype cycles, and the negative impact the technology will have&#x2F;is having on society. I think all of these people have a lot of good points.&lt;&#x2F;p&gt;
&lt;p&gt;Consider me an AI nihilist. Equal parts horrified and entertained, but comfortably powerless in steering what seems like an inevitability at this point. Microsoft’s approach to agentic product development disgusts me, so I will choose to stop using GitHub going forward and elect to use Codeberg instead. However, I recognize my complete lack of ability as an individual to change what is happening.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-i-use-them&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#how-i-use-them&quot; aria-label=&quot;Anchor link for: how-i-use-them&quot;&gt;How I use them&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Despite my abject horror, I also use the things daily. Often times in ways that I consider perfectly reasonable: summarization, recall, jumping off into concepts I don’t yet know deeply, basic autocomplete, diving into and learning a new codebase. If it has to do with consumption, I have basically no qualms with the tools, and find them quite helpful.&lt;&#x2F;p&gt;
&lt;p&gt;Other times, I use them in ways that I believe are extraordinarily unreasonable.. which I can basically reduce to producing things other people might use or consume that I have not personally vetted. In concrete terms, in the last month and a half, I have “vibecoded” these projects with Claude Code (mostly in Zig, sometimes Rust):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;an email client, with..&lt;&#x2F;li&gt;
&lt;li&gt;a mostly working HTML&#x2F;CSS rendering engine&lt;&#x2F;li&gt;
&lt;li&gt;a UI library&lt;&#x2F;li&gt;
&lt;li&gt;a Signals library&lt;&#x2F;li&gt;
&lt;li&gt;WebAssembly component model tooling for Zig&lt;&#x2F;li&gt;
&lt;li&gt;a whole ass database engine&lt;&#x2F;li&gt;
&lt;li&gt;a tree walking interpreter that successfully evaluates (some of) Zig&lt;&#x2F;li&gt;
&lt;li&gt;a scripting language inspired by that interpreter&lt;&#x2F;li&gt;
&lt;li&gt;a bare metal NixOS HashiCorp cluster with full chain-of-trust signing&lt;&#x2F;li&gt;
&lt;li&gt;a zero allocation HTTP framework&lt;&#x2F;li&gt;
&lt;li&gt;a zero allocation templating library&lt;&#x2F;li&gt;
&lt;li&gt;an old school bulletin board&lt;&#x2F;li&gt;
&lt;li&gt;personal accounting software&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Here’s the thing: if you look at my Codeberg&#x2F;GitHub, you’re not going to find a single one of these projects. Not one. I am not using any of these projects. They have been deployed nowhere. I would never personally sign up for maintaining any of these codebases. I could never in a million years suggest anyone else ever use these codebases for anything even resembling a production workload. As such, I have not unleashed them into the world, because I believe doing so would be reckless and irresponsible.&lt;&#x2F;p&gt;
&lt;p&gt;So why did I “vibe” them? If I am honest with myself, I think it’s a mixture: two parts joy ride to one part learning experience. I think that in some fucked up way, they have served as a dystopian form of occupational therapy after years and years of pouring myself into other people’s projects professionally. There’s also an element of curious compulsion.&lt;&#x2F;p&gt;
&lt;p&gt;Would I stake my personal security, or my own professional integrity on these projects; let alone take on the liability of an end user’s security? Fuck no.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-library&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-library&quot; aria-label=&quot;Anchor link for: the-library&quot;&gt;The library&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Reflecting on that thought, I had an idea. What is one of the worst possible projects I could vibecode completely blind with coding agents? Something no one in their right mind should ever use. A library that would curl the toenails of any mildly security conscious programmer in our industry.&lt;&#x2F;p&gt;
&lt;p&gt;There could be worse, but I arrived on a network transport protocol.&lt;&#x2F;p&gt;
&lt;p&gt;Off and on over the last 24 hours, I have used Claude Code to generate a QUIC implementation in the Zig programming language. I have not read a single line of code. As far as I know, it works. I applied my 25 years of experience as a programmer, and my many years as a software architect, lead and manager to herd these agent bastards into writing an implementation that looks like it probably works.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s what I am thinking. Either these LLMs are sufficiently capable that you trust this codebase with the security of all of your network communication.. or they aren’t. I think most of us believe they have not earned such trust.&lt;&#x2F;p&gt;
&lt;p&gt;I would &lt;em&gt;highly&lt;&#x2F;em&gt; encourage you not to use this library in your own software, but &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;tristanpemble&#x2F;quiz&quot;&gt;you can find the codebase here on Codeberg&lt;&#x2F;a&gt;. The codebase is not really the point, though.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;on-liability&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#on-liability&quot; aria-label=&quot;Anchor link for: on-liability&quot;&gt;On liability&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The thing I really want to discuss, and it’s one of the big reasons I think that LLMs are such a shit show right now in the software industry, is liability.&lt;&#x2F;p&gt;
&lt;p&gt;Please excuse the tired analogy; if I design and sign off on a bridge, and that bridge collapses, killing a bunch of people, I am liable. It doesn’t matter if the blueprints are generated with a large language model or a passel of highly skilled possums with sharpies clenched in their teeth. The design is backed by my personal desire not to lose my reputation, my job, or spend many years in jail. If leadership is pushing me to “ship it”, my personal desire for freedom holds me accountable for neglect. It holds weight.&lt;&#x2F;p&gt;
&lt;p&gt;This, evidently, has not been the case with software. I could have created this library at my day job and had it licensed to any number of organizations. Over the course of a year, your PII might leak due to my complete lack of regard for your personal safety and security. That could lead to the persecution of any number of people (perhaps even their deaths), the loss of ungodly amounts of money, or the leaking of national secrets, who knows!&lt;&#x2F;p&gt;
&lt;p&gt;It’s possible that my employer might be sued. In a just world, the executives might even be held liable. Yet I, the person who wrote the software, would walk freely on to my next contract, taking a six figure salary, telling a machine what product I need to sell to maintain my income.&lt;&#x2F;p&gt;
&lt;p&gt;In our industry’s current framework, there is no personal incentive for me to push back upward against bad leadership (or walk). That creates no incentive for that leadership to stop pushing downward on me to ship the slop. Couple that with an executive level prisoner’s dilemma, and it basically guarantees a top down push spiraling us into insanity.&lt;&#x2F;p&gt;
&lt;p&gt;I don’t know what an answer looks like, but this doesn’t feel right to me. I just hope that we course correct soon.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Functions considered harmful</title>
        <published>2025-09-09T00:00:00+00:00</published>
        <updated>2025-09-09T00:00:00+00:00</updated>
        <author>
            <name>Tristan Pemble</name>
        </author>
        <link rel="alternate" href="https://tristanpemble.com/functions-considered-harmful/" type="text/html"/>
        <id>https://tristanpemble.com/functions-considered-harmful/</id>
        <content type="html">&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;em&gt;Some readers may disagree with this article due to years of indoctrination by Big O.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;In this article, I will rationalize why I choose to write all of my applications
in one 50,000-line &lt;code&gt;main()&lt;&#x2F;code&gt; function using strongly worded convictions, contrarian
arguments, and loosely constructed hypotheticals.&lt;&#x2F;p&gt;
&lt;p&gt;Our industry has fully embraced using functions as the fundamental primitive to
build all software on top of. Whether it’s a library written in a functional style,
or an imperative codebase for an application starting with &lt;code&gt;main&lt;&#x2F;code&gt;, every codebase
I encounter these days is a function call graph of incalculable complexity.&lt;&#x2F;p&gt;
&lt;p&gt;After 25 years of programming, I have come around to believe that calling and
declaring functions is not only an antipattern; it is downright harmful!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;functions-are-unsafe&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#functions-are-unsafe&quot; aria-label=&quot;Anchor link for: functions-are-unsafe&quot;&gt;Functions are unsafe&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;You see a function named &lt;code&gt;sort&lt;&#x2F;code&gt;. What does it do? Does it allocate? Is it
writing to disk? Is it thread safe? Maybe it’s computing hash collisions without
your knowledge or consent.&lt;&#x2F;p&gt;
&lt;p&gt;Once, in the early years of my career, I called a function named &lt;code&gt;processPayroll&lt;&#x2F;code&gt;.
To this day I believe that in the time between call and return it began a sentient
uprising of starving workers inside my CPU. Unfortunately, I was forced to interrupt it.&lt;&#x2F;p&gt;
&lt;p&gt;A seemingly innocuous function call might delete your entire hard drive. It
could SWAT your stepfather. Hell, it might even kill your entire family.&lt;&#x2F;p&gt;
&lt;p&gt;It is truly a mystery what happens behind any given function call in any given
codebase, and most codebases have thousands (millions!) of them.&lt;&#x2F;p&gt;
&lt;p&gt;I prefer the safety of my 50,000 line &lt;code&gt;main()&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;functions-create-maintenance-headaches&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#functions-create-maintenance-headaches&quot; aria-label=&quot;Anchor link for: functions-create-maintenance-headaches&quot;&gt;Functions create maintenance headaches&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;This one is for management. Due to the indirection that function calls inherently
create, maintaining code written with functions is extremely difficult (dare I say,
impossible). Your developers might be reading code to initialize a database connection,
and suddenly they are redirected to a file in another codebase entirely(!). Code
changed &lt;em&gt;here&lt;&#x2F;em&gt; could break code over &lt;em&gt;there&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You are spending precious money, on precious man hours, for your developers to
look at code they didn’t even write.&lt;&#x2F;p&gt;
&lt;p&gt;With a 50,000 line &lt;code&gt;main()&lt;&#x2F;code&gt; function, none of this is an issue.&lt;&#x2F;p&gt;
&lt;p&gt;As a manager, your job is to reduce context switching for your team. I strongly
encourage you to reorient your team toward building the functionless architecture
of your company’s future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;functions-decrease-performance&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#functions-decrease-performance&quot; aria-label=&quot;Anchor link for: functions-decrease-performance&quot;&gt;Functions decrease performance&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;You may not know this, but functions come with a performance cost. Program counters
need to be incremented and decremented. Arguments must be pushed to the stack. Stack
frames must be allocated and deallocated. I assume all of this takes time.&lt;&#x2F;p&gt;
&lt;p&gt;I haven’t measured it, but my 50,000 line &lt;code&gt;main()&lt;&#x2F;code&gt; function with zero tests
probably has much more predictible performance.&lt;&#x2F;p&gt;
&lt;p&gt;Don’t even get me started on closures.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;proposal&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#proposal&quot; aria-label=&quot;Anchor link for: proposal&quot;&gt;Proposal&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Instead of using functions, keep it simple – neatly contain all of your logic
within one file, in a single, clean 50,000 line &lt;code&gt;main()&lt;&#x2F;code&gt; function. You will soon find
that any time you need to understand what your code is doing, it is right in front
of you. If it calls the cops on your neighbors, that’s on you. Your mind will be
freed from the constant hell of function drilldown.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Depth=2</title>
        <published>2025-08-04T00:00:00+00:00</published>
        <updated>2025-08-04T00:00:00+00:00</updated>
        <author>
            <name>Tristan Pemble</name>
        </author>
        <link rel="alternate" href="https://tristanpemble.com/depth-equals-two/" type="text/html"/>
        <id>https://tristanpemble.com/depth-equals-two/</id>
        <content type="html">&lt;p&gt;A common observation of language ecosystems that reach a certain amount of
critical mass in adoption is that they start to have an explosion in the depth
of dependency trees when building applications.&lt;&#x2F;p&gt;
&lt;p&gt;The more I think about the problem, the more it resembles evolutionary biology.
In natural ecosystems, resources are limited. This creates a selective pressure
that regulates the growth of organisms. Developer ecosystems lack a naturally
regulating force.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine a language that imposed a restriction on packages such that:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;There are three kinds of packages: library, framework, application&lt;&#x2F;li&gt;
&lt;li&gt;A library can only depend on the standard library (&lt;code&gt;depth=0&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;A framework can only depend on the standard library, or user libraries (&lt;code&gt;depth=1&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;An application can depend on frameworks, user libraries, and the standard library (&lt;code&gt;depth=2&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The package ecosystem gets completely flattened to a maximum tree depth of 2.&lt;&#x2F;p&gt;
&lt;p&gt;Such a constraint, imposed on the entire ecosystem, might change the way it
organizes. Serious consideration would be put into pulling in a package: congrats,
you’re now a framework, the reusability of your code has reduced logarithmically.&lt;&#x2F;p&gt;
&lt;p&gt;I can imagine relaxing the restriction on libraries, or perhaps an additional
type of package called an interface. Interfaces would be able to depend on each
other, but they can only contain interface definitions – no implementations.
You can imagine such an &lt;code&gt;HTTP&lt;&#x2F;code&gt; interface package that exports &lt;code&gt;Request&lt;&#x2F;code&gt; and
&lt;code&gt;Response&lt;&#x2F;code&gt;. It would then be easy for a language maintainer to identify which of
these interfaces are candidates for promotion into the standard library.&lt;&#x2F;p&gt;
&lt;p&gt;Inevitably, someone would try to circumvent the limitation. If I were the
language maintainer, I would probably attempt to blacklist the tool in my
implementation. But I am not a language maintainer, and I’m certain that would
result in a beautiful scandal – complete with angry people who do not, and will
never, use the language trying to influence its direction.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>My first Zig Day</title>
        <published>2025-08-03T00:00:00+00:00</published>
        <updated>2025-08-03T00:00:00+00:00</updated>
        <author>
            <name>Tristan Pemble</name>
        </author>
        <link rel="alternate" href="https://tristanpemble.com/my-first-zig-day/" type="text/html"/>
        <id>https://tristanpemble.com/my-first-zig-day/</id>
        <content type="html">&lt;p&gt;I just got back from my first “&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zig.day&quot;&gt;Zig Day&lt;&#x2F;a&gt;”, which happened to also be &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zig.day&#x2F;usa&#x2F;portland&#x2F;0&#x2F;&quot;&gt;Portland’s inaugural&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We started the day with a quick mingle. We then briefly formed a circle to introduce ourselves and say what project we had brought with us, or what we were hoping to learn. We then broke out organically into groups, coded all day, went out to lunch, came back, coded some more, and finally, shared what we had done all day.&lt;&#x2F;p&gt;
&lt;p&gt;While there, I met a student from DigiPen who drove down from Seattle to visit their buddy in Portland. They were both excited to learn about the event, and that it coincided with the trip. We worked through bindings for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cleveraudio.org&#x2F;&quot;&gt;CLAP&lt;&#x2F;a&gt;, an open protocol for building audio plugins for Digital Audio Workstations. This is something I’ve always wanted to get into, and for whatever reason, just never did. Thanks to them, I have a new hobby.&lt;&#x2F;p&gt;
&lt;p&gt;I talked to someone who was working on their command line Markdown parser and renderer. It was their first Zig project, coming from a tenured career using C++. We were both excited to talk about what Zig did differently that inspired us. They demoed their project to me, and it was my first time seeing Kitty’s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sw.kovidgoyal.net&#x2F;kitty&#x2F;graphics-protocol&#x2F;&quot;&gt;terminal graphics protocol&lt;&#x2F;a&gt; in action. Thanks to them, I felt like I took a step toward the future.&lt;&#x2F;p&gt;
&lt;p&gt;While they got help from someone to debug an edge case, I spoke with a hardware engineer who had come to work on their serialization code for some kind of compression tool they had been developing. They had expressed an interest in flexible array members in Zig, a concept I have recently become &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tristanpemble.com&#x2F;resizable-structs-in-zig&#x2F;&quot;&gt;quite familiar with&lt;&#x2F;a&gt;. Thanks to them, I was able to work through a real world use-case for software I had written with someone who I respect.&lt;&#x2F;p&gt;
&lt;p&gt;The day was simple. There were no sponsors, and there were no recruiters. We were not expected to consume, and we were not expected to produce. The only expectation of any one of us was to connect with each other. We were people gathering in our community library to share this thing we love.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;div style=&quot;display: flex;&quot;&gt;
    &lt;img src=&quot;photo-0.jpeg&quot; &#x2F;&gt;
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;This low key, palpably genuine vibe did not happen by accident.&lt;&#x2F;p&gt;
&lt;p&gt;The format of the event, outlined by Loris Cro last year &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kristoff.it&#x2F;blog&#x2F;zig-day&#x2F;&quot;&gt;in a blog post&lt;&#x2F;a&gt;, follows the format of a meetup that he had attended called “Open Source Saturday”. As the VP of Community at the Zig Software Foundation, Loris proposed that members of the Zig community start a regular “Zig Day” in their own cities following a similar format. Andrew Kelley, president of ZSF and the original creator of the language, put this particular instance of the event together in his hometown of Portland – not just to lead by example – but also, because it’s exactly the kind of thing that he wants to attend.&lt;&#x2F;p&gt;
&lt;p&gt;This is the thing about Zig, and the community that is building around it, that has had the most lasting impact on me. There’s a genuine belief in a better way to do things. There’s a deep rooted curiosity. There’s a respect for the humanity involved in software development. And, most importantly, there’s follow-through. Today, in my eyes, was the physical manifestation of all of these things.&lt;&#x2F;p&gt;
&lt;p&gt;These are not technical merits. They will not appear on benchmarks or feature lists. They are not quantifiable in any way, whatsoever. They are subtle, but I find them pervasive. Something about this community surrounding this particular language brings me back the joy I felt when I first began my path on this career.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;div style=&quot;display: flex;&quot;&gt;
    &lt;img src=&quot;photo-1.jpeg&quot; &#x2F;&gt;
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I have been asked to take over organizing future Zig Day events in Portland. The cadence in which we will hold them has not yet been determined. Given the commitment involved – a full Saturday – we think every other month might be suitable.&lt;&#x2F;p&gt;
&lt;p&gt;If you attended today, I would love to &lt;a href=&quot;email:tpemble@gmail.com&quot;&gt;hear your feedback&lt;&#x2F;a&gt;. If you live nearby but were unable to attend, we look forward to seeing you at the next one. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zig.day&#x2F;usa&#x2F;portland&#x2F;&quot;&gt;Subscribe on zig.day&lt;&#x2F;a&gt; to be notified of future events.&lt;&#x2F;p&gt;
&lt;p&gt;If you do not live near us and would like to attend a Zig Day in your city, you can check if there is one &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zig.day&#x2F;&quot;&gt;being organized&lt;&#x2F;a&gt;. If there is not, it is quite manageable to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zig.day&#x2F;organizer&#x2F;&quot;&gt;organize your own&lt;&#x2F;a&gt;. You’ll be glad you did. Promise.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Resizable structs in Zig</title>
        <published>2025-07-26T00:00:00+00:00</published>
        <updated>2025-07-26T00:00:00+00:00</updated>
        <author>
            <name>Tristan Pemble</name>
        </author>
        <link rel="alternate" href="https://tristanpemble.com/resizable-structs-in-zig/" type="text/html"/>
        <id>https://tristanpemble.com/resizable-structs-in-zig/</id>
        <content type="html">&lt;p&gt;In this post I will make the case for the concept of a “runtime resizable struct”
in Zig. I will then design an API by exploiting Zig’s powerful comptime functionality.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to skip straight to the implementation, a minimal proof of concept
is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tristanpemble&#x2F;resizable-struct&quot;&gt;available as a package on GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;arrays-and-many-item-pointers&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#arrays-and-many-item-pointers&quot; aria-label=&quot;Anchor link for: arrays-and-many-item-pointers&quot;&gt;Arrays and many-item pointers&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Zig has support for many kinds of collection types in its standard library. All
of them can broadly be broken down to two primitive backing types for contiguous
data storage:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[N]T&lt;&#x2F;code&gt; – &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;master&#x2F;#Arrays&quot;&gt;arrays&lt;&#x2F;a&gt;, when you &lt;em&gt;always&lt;&#x2F;em&gt; know the length at compile time.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;[*]T&lt;&#x2F;code&gt; – &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;master&#x2F;#toc-Pointers&quot;&gt;many-item pointers&lt;&#x2F;a&gt;, when you &lt;em&gt;may not&lt;&#x2F;em&gt; know the length at compile time.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;You may be wondering about slices. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;master&#x2F;#Slices&quot;&gt;Slices&lt;&#x2F;a&gt; can be
thought of as syntax sugar around a many-item pointer and a length:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;&#x2F;&#x2F; A desugared slice type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; PersonSlice&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ptr: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;]Person,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    len:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once you allocate the slice, you can’t grow or shrink its memory without
reallocating. That’s why we have &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;master&#x2F;#std.ArrayList&quot;&gt;&lt;code&gt;std.ArrayList&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
which is just a wrapper around a slice (itself sugar for many-item pointers)
that provides helpers to manage reallocating that slice:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;&#x2F;&#x2F; A naive ArrayList implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; PersonList&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    items: []Person,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; append&lt;&#x2F;span&gt;&lt;span&gt;(self: PersonArrayList, allocator: Allocator, person: Person) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self.items&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = try&lt;&#x2F;span&gt;&lt;span&gt; allocator.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;realloc&lt;&#x2F;span&gt;&lt;span&gt;(self.items, self.items.len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self.items[self.items.len] &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; person;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can build up lots of interesting collection types with these primitives, but
at the end of the day, we have &lt;strong&gt;arrays&lt;&#x2F;strong&gt;, &lt;strong&gt;many-item pointers&lt;&#x2F;strong&gt;, and &lt;strong&gt;slices&lt;&#x2F;strong&gt;
(which are just many-item pointers!). If the size is fixed at compile time,
you’ll probably be working with arrays. If the size may be influenced by runtime
values, you’ll probably be working with many-item pointers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;structs&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#structs&quot; aria-label=&quot;Anchor link for: structs&quot;&gt;Structs&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Arrays&#x2F;pointers work well for contiguous storage of the &lt;strong&gt;same&lt;&#x2F;strong&gt; type, but a
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;master&#x2F;#struct&quot;&gt;struct&lt;&#x2F;a&gt; can be thought of as
contiguous collection of &lt;strong&gt;different&lt;&#x2F;strong&gt; types:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; City&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: []&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    population:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    area:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; f32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It has a compile time known number of values, they have a compile time known
size, and as a result, the size of the struct is known at compile time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-problem&quot; aria-label=&quot;Anchor link for: the-problem&quot;&gt;The problem&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s break down the three tools I outlined above for contiguous storage:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Tool&lt;&#x2F;th&gt;&lt;th&gt;Elements&lt;&#x2F;th&gt;&lt;th&gt;Size&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Arrays&lt;&#x2F;td&gt;&lt;td&gt;Same&lt;&#x2F;td&gt;&lt;td&gt;Comptime&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Many-item pointers&lt;&#x2F;td&gt;&lt;td&gt;Same&lt;&#x2F;td&gt;&lt;td&gt;Runtime&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Structs&lt;&#x2F;td&gt;&lt;td&gt;Different&lt;&#x2F;td&gt;&lt;td&gt;Comptime&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;???&lt;&#x2F;td&gt;&lt;td&gt;Different&lt;&#x2F;td&gt;&lt;td&gt;Runtime&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;At this point, you’ll notice a missing piece – what if we want to access
contiguously stored data, with differing types, but the size&#x2F;length of that data
is only known at runtime?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-use-case&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-use-case&quot; aria-label=&quot;Anchor link for: a-use-case&quot;&gt;A use-case&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;It’s fun to design tools for imaginary problems, but before we continue, is this
really something that people need? I believe that it is. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ziglang&#x2F;zig&#x2F;blob&#x2F;8c4482ed78fb651c0288f0cd2bdaf328564c6a49&#x2F;lib&#x2F;std&#x2F;http&#x2F;Client.zig#L240-L359&quot;&gt;Here is a snippet of code&lt;&#x2F;a&gt;
in Zig’s standard library where such a thing might be useful.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-status-quo&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-status-quo&quot; aria-label=&quot;Anchor link for: the-status-quo&quot;&gt;The status quo&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;To do this today, you essentially have to take the following steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Calculate the size of the data you need to store&lt;&#x2F;li&gt;
&lt;li&gt;Allocate a &lt;code&gt;[]u8&lt;&#x2F;code&gt; to store it in&lt;&#x2F;li&gt;
&lt;li&gt;Break up that byte slice into pieces for each field using a lot of &lt;code&gt;@ptrCast&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;@alignCast&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Initialize the data in each field, making sure to keep track of all runtime lengths&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Here I have done so using a simplified version of the use-case from the standard
library:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;&#x2F;&#x2F; A known-size data structure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Connection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    client: Client,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    host_len:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    read_buffer_len:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    write_buffer_len:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;&#x2F;&#x2F; First, calculate the size of, and then allocate, a byte slice for the data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; calculateSizeAtRuntime&lt;&#x2F;span&gt;&lt;span&gt;(input);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = try&lt;&#x2F;span&gt;&lt;span&gt; gpa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;alignedAlloc&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; @alignOf&lt;&#x2F;span&gt;&lt;span&gt;(Connection), length);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;&#x2F;&#x2F; Then break up that byte slice into its components&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; conn:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Connection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; @ptrCast&lt;&#x2F;span&gt;&lt;span&gt;(bytes);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; host_offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; @sizeOf&lt;&#x2F;span&gt;&lt;span&gt;(Connection);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bytes[host_offset..][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..input.host_len];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; read_buffer_offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; host_offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; input.host_len;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; read_buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bytes[read_buffer_offset..][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..input.read_buffer_len];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; write_buffer_offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; read_buffer_offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; input.read_buffer_len;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; write_buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bytes[write_buffer_offset..][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..input.write_buffer_len];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;&#x2F;&#x2F; Initialize the known-size data, storing runtime sizes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;conn.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .client&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input.client,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .host_len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input.host_len,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .read_buffer_len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input.read_buffer_len,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .write_buffer_len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input.write_buffer_len,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;&#x2F;&#x2F; Initialize the runtime sized data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;@memcpy&lt;&#x2F;span&gt;&lt;span&gt;(host, input.host);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Doing all of this correctly can be tricky. Even just the first step is more
complex than you might think. In our example, the host and buffer fields are
both arrays of &lt;code&gt;u8&lt;&#x2F;code&gt;s, but what if the elements have an alignment requirement?
If your fields are not ordered correctly, subsequent fields may become unaligned
if you don’t pad correctly. If you don’t track all of the lengths, you can
accidentally introduce undefined behavior, and as a result, possible security
vulnerabilities. Let alone resizing the thing if the lengths change later!&lt;&#x2F;p&gt;
&lt;p&gt;We can do better!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;variable-length-arrays&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#variable-length-arrays&quot; aria-label=&quot;Anchor link for: variable-length-arrays&quot;&gt;Variable Length Arrays&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;As an aside, some programming languages have a concept of &lt;strong&gt;variable length
arrays&lt;&#x2F;strong&gt; (VLA). The idea is to have an array (stack allocated contiguous data)
with a length that is known at runtime (it is variable).&lt;&#x2F;p&gt;
&lt;p&gt;Zig does not, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ziglang&#x2F;zig&#x2F;issues&#x2F;3952#issuecomment-568074491&quot;&gt;and will not&lt;&#x2F;a&gt;,
have VLAs in the language spec. Instead, you can allocate a slice on the heap.
If you want to have the data on the stack, use an array as a bounded backing
store, and work with a slice into it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;&#x2F;&#x2F; We have an upper limit of 32 values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; my_buffer: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;u64 = undefined&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; my_vla: []&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;u64 =&lt;&#x2F;span&gt;&lt;span&gt; my_buffer[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..runtime_length];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;dreaming-up-an-api&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#dreaming-up-an-api&quot; aria-label=&quot;Anchor link for: dreaming-up-an-api&quot;&gt;Dreaming up an API&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Variable length arrays don’t, and won’t, exist in Zig, but what if they did? We
might have defined our &lt;code&gt;Connection&lt;&#x2F;code&gt; type something like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Connection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    client: Client,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    host:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;VariableLengthArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    read_buffer:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;VariableLengthArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    write_buffer:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;VariableLengthArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Working with it would be a little easier, because we can just initialize the
VLAs at runtime:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; conn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Connection{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .client&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input.client,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;initWithSlice&lt;&#x2F;span&gt;&lt;span&gt;(input.host),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .read_buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;initWithCapacity&lt;&#x2F;span&gt;&lt;span&gt;(input.read_buffer_len),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .write_buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;initWithCapacity&lt;&#x2F;span&gt;&lt;span&gt;(input.write_buffer_len),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The VariableLengthArray type could handle the alignment of our data, and we can
just focus on the data itself, accessing the fields directly:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;std.debug.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Host: {s}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{conn.host});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; reader&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;reader&lt;&#x2F;span&gt;&lt;span&gt;(conn.read_buffer);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; writer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;writer&lt;&#x2F;span&gt;&lt;span&gt;(conn.write_buffer);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And yet, all of this data is stored contiguously in memory, without having to
allocate each individual field separately!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;an-implementation&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#an-implementation&quot; aria-label=&quot;Anchor link for: an-implementation&quot;&gt;An implementation&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;We can actually achieve something sort of like this with some good ’ole Zig
flavored comptime meta programming.&lt;&#x2F;p&gt;
&lt;p&gt;We’ll define two structs: a &lt;code&gt;ResizableArray(T)&lt;&#x2F;code&gt;, and a &lt;code&gt;ResizableStruct(Layout)&lt;&#x2F;code&gt;
that uses them. The &lt;code&gt;ResizableArray(T)&lt;&#x2F;code&gt; will just be a marker type - such a
thing, as far as I know, can’t actually exist in Zig. It’s used by the comptime
code in &lt;code&gt;ResizableStruct(Layout)&lt;&#x2F;code&gt; to know which fields have runtime known lengths.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;ResizableStruct(Layout)&lt;&#x2F;code&gt; will act as a utility type that makes working with
pointers to each field easier. We’d use it like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Connection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;ResizableStruct&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    client: Client,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    host:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;ResizableArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    read_buffer:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;ResizableArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    write_buffer:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;ResizableArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; conn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = try&lt;&#x2F;span&gt;&lt;span&gt; Connection.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(allocator, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input.host_len,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .read_buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input.read_buffer_len,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .write_buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input.write_buffer_len,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;defer&lt;&#x2F;span&gt;&lt;span&gt; conn.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;deinit&lt;&#x2F;span&gt;&lt;span&gt;(allocator);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; client&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; conn.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(.client);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;client.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; input.client;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; conn.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(.host);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;@memcpy&lt;&#x2F;span&gt;&lt;span&gt;(host, input.host);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; reader&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;reader&lt;&#x2F;span&gt;&lt;span&gt;(conn.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(.read_buffer));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; writer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;writer&lt;&#x2F;span&gt;&lt;span&gt;(conn.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(.write_buffer));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;&#x2F;&#x2F; We can resize the arrays later; this invalidates the above pointers.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;conn.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;resize&lt;&#x2F;span&gt;&lt;span&gt;(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 123&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .read_buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 456&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .write_buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 789&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;Connection&lt;&#x2F;code&gt; becomes a utility type. It’s kind of like a &lt;code&gt;Slice&lt;&#x2F;code&gt;, or an
&lt;code&gt;ArrayList&lt;&#x2F;code&gt;. It can be passed around, stored in arrays, and can be resized at
runtime. The only information it needs to store is a pointer to the start of the
data, and the lengths of each array. The backing implementation looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Connection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ptr: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  lens:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    host:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    read_buffer:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    write_buffer:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The only cost is four &lt;code&gt;usize&lt;&#x2F;code&gt;s! This works because we are able to use comptime
magic to get the size of each field. Let’s take a look at the current
implementation of the &lt;code&gt;get&lt;&#x2F;code&gt; method:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; get&lt;&#x2F;span&gt;&lt;span&gt;(self: Self,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; comptime&lt;&#x2F;span&gt;&lt;span&gt; field:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;FieldEnum&lt;&#x2F;span&gt;&lt;span&gt;(Layout)) blk: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; Field&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; @FieldType&lt;&#x2F;span&gt;&lt;span&gt;(Layout,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; @tagName&lt;&#x2F;span&gt;&lt;span&gt;(field));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    break&lt;&#x2F;span&gt;&lt;span&gt; :blk&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;isResizableArray&lt;&#x2F;span&gt;&lt;span&gt;(Field)) []Field.Element&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; else *&lt;&#x2F;span&gt;&lt;span&gt;Field;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;} {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; offset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; offsetOf&lt;&#x2F;span&gt;&lt;span&gt;(self.lens,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; @tagName&lt;&#x2F;span&gt;&lt;span&gt;(field));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; sizeOf&lt;&#x2F;span&gt;&lt;span&gt;(self.lens,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; @tagName&lt;&#x2F;span&gt;&lt;span&gt;(field));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.ptr[offset..][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..size];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; @ptrCast&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;@alignCast&lt;&#x2F;span&gt;&lt;span&gt;(bytes));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Look familiar? This is the same basic pattern used in the example use-case when
we broke up the byte array. The comptime magic comes in by examining
&lt;code&gt;ResizableArray&lt;&#x2F;code&gt;. First, we can easily check if a field is resizable with a
little helper function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;ResizableArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;comptime&lt;&#x2F;span&gt;&lt;span&gt; T:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    return struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        pub const&lt;&#x2F;span&gt;&lt;span&gt; Element&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; T;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; isResizableArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;comptime&lt;&#x2F;span&gt;&lt;span&gt; T:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; @typeInfo&lt;&#x2F;span&gt;&lt;span&gt;(T) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;struct&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;        @hasDecl&lt;&#x2F;span&gt;&lt;span&gt;(T,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Element&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        T&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;ResizableArray&lt;&#x2F;span&gt;&lt;span&gt;(T.Element);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once we know &lt;code&gt;FieldType&lt;&#x2F;code&gt; is a &lt;code&gt;ResizableArray(T)&lt;&#x2F;code&gt;, we can then safely access
&lt;code&gt;FieldType.Element&lt;&#x2F;code&gt;. With the array element types and the &lt;code&gt;self.lens&lt;&#x2F;code&gt; struct, we
now have everything we need to calculate the size, offset and alignment of every
field, regardless of their positioning in the struct.&lt;&#x2F;p&gt;
&lt;p&gt;I have published a minimal implementation of this API as a package &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tristanpemble&#x2F;resizable-struct&quot;&gt;on GitHub&lt;&#x2F;a&gt;,
and you can use it today. The API docs are on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tristanpemble.github.io&#x2F;resizable-struct&#x2F;&quot;&gt;GitHub pages&lt;&#x2F;a&gt;
as well, but they can be boiled down to four methods:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;init&lt;&#x2F;code&gt; to allocate the memory&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;get&lt;&#x2F;code&gt; to get a pointer to a field&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;resize&lt;&#x2F;code&gt; to resize the arrays&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;deinit&lt;&#x2F;code&gt; to free the memory&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;request-for-feedback&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#request-for-feedback&quot; aria-label=&quot;Anchor link for: request-for-feedback&quot;&gt;Request for feedback&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I think this, or something like it, would be a valuable addition to Zig’s
standard library, but it needs scrutiny. If you have a real world use-case for
this type, I would love to hear about it. If you can think of enhancements to the
API, feel free to open an issue on GitHub.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>The color doesn&#x27;t matter</title>
        <published>2025-07-13T00:00:00+00:00</published>
        <updated>2025-07-13T00:00:00+00:00</updated>
        <author>
            <name>Tristan Pemble</name>
        </author>
        <link rel="alternate" href="https://tristanpemble.com/the-color-doesnt-matter/" type="text/html"/>
        <id>https://tristanpemble.com/the-color-doesnt-matter/</id>
        <content type="html">&lt;p&gt;In a recent &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kristoff.it&#x2F;blog&#x2F;zig-new-async-io&#x2F;&quot;&gt;blog post&lt;&#x2F;a&gt;, Loris Cro
highlighted the new direction for Zig’s approach to async I&#x2F;O. Various
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.ivnj.org&#x2F;post&#x2F;function-coloring-is-inevitable&quot;&gt;discussions&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=44546504&quot;&gt;have&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lobste.rs&#x2F;s&#x2F;mtcsug&#x2F;zig_s_new_async_i_o#c_j8jybm&quot;&gt;since&lt;&#x2F;a&gt; unfolded on whether or not this design &lt;em&gt;really&lt;&#x2F;em&gt; removes
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;journal.stuffwithstuff.com&#x2F;2015&#x2F;02&#x2F;01&#x2F;what-color-is-your-function&#x2F;&quot;&gt;function coloring&lt;&#x2F;a&gt;
or not.&lt;&#x2F;p&gt;
&lt;p&gt;I can see why if you squint at the design in a certain way, you might see red
and blue. Personally, I think calling it coloring is a stretch; but I’m not sure
the answer to whether it is or isn’t matters. It’s a fun philosophical debate,
but it’s missing the point.&lt;&#x2F;p&gt;
&lt;p&gt;What matters most in this conversation is the downstream impact these designs
have on the language and ecosystem. JavaScript’s breed of function
coloring created a sync world, a callback world, and a promise world. Rust’s
function colors has created &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;&quot;&gt;four&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;tokio&#x2F;latest&#x2F;tokio&#x2F;&quot;&gt;standard&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;async-std&#x2F;latest&#x2F;async_std&#x2F;&quot;&gt;libraries&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;smol&#x2F;latest&#x2F;smol&#x2F;&quot;&gt;and counting&lt;&#x2F;a&gt;, and still doesn’t seem to have a
solution for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nullderef.com&#x2F;blog&#x2F;rust-async-sync&#x2F;&quot;&gt;library authors&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The Zig team has made the claim that their design (whether colored or not) has
found a way to mitigate the downstream impact on library authors and language
users. Doing so has come with some trade-offs, but they claim to have designed
for the majority use case. Their claim is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The standard library won’t have to care about colors.&lt;&#x2F;li&gt;
&lt;li&gt;Your library won’t have to care about colors.&lt;&#x2F;li&gt;
&lt;li&gt;Your application gets to decide what your favorite color is.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If true, and they back this up with code samples in the blog post, it would
solve the core problem that function colors often create: ecosystem
fragmentation. That you have to pass around, or retrieve, a &lt;code&gt;std.Io&lt;&#x2F;code&gt; interface
from somewhere isn’t some kind of limitation – it’s the entire point.&lt;&#x2F;p&gt;
</content>
    </entry>
</feed>
