<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Arhan&apos;s Blog</title><description>A loose collection of technology and random thoughts</description><link>https://arhan.sh/</link><item><title>Bring Back the Paragraph</title><link>https://arhan.sh/blog/bring-back-the-paragraph/</link><guid isPermaLink="true">https://arhan.sh/blog/bring-back-the-paragraph/</guid><pubDate>Fri, 07 Aug 2026 17:59:10 GMT</pubDate><content:encoded>&lt;p&gt;One of the most insidious impacts of LLMs is the online death of the paragraph. You know exactly what I mean.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Here is a bullet point&lt;/strong&gt; — it is bold for no meaningful reason. The author does not trust me to have the attention span to read what they have to say.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Here is another bullet point&lt;/strong&gt; — You can’t explain why, but you feel forced to read this sentence. Your attention has been hijacked.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is some more text,&lt;/p&gt;
&lt;p&gt;expressing only a singular idea,&lt;/p&gt;
&lt;p&gt;that is&lt;/p&gt;
&lt;p&gt;unnecessarily&lt;/p&gt;
&lt;p&gt;separated by line breaks.&lt;/p&gt;
&lt;p&gt;Is this not exhausting to read?&lt;/p&gt;
&lt;p&gt;I like to call this type of writing “spaghetti writing”. Spaghetti writing is not &lt;em&gt;bad&lt;/em&gt; per se: there are benefits to micro-optimizing the communication of certain ideas or varying your sentence structure. However, you see it literally anywhere online. Most forms of writing on the worst social media sites longer than two sentences look like spaghetti writing. But social media was always meant for short-form content, so whatever. That was what you signed up for.&lt;/p&gt;
&lt;p&gt;Suddenly, spaghetti writing is becoming more prominent outside of social media—in places on the Internet I &lt;em&gt;didn’t&lt;/em&gt; sign up for. I used to be able to call Google search and GitHub safe havens for discovering technical authors who cared deeply about their craft. Now, to have the same opinion would be dishonest. LLMs are not only producing spaghetti writing, but subconciously teaching people spaghetti writing. Websites like Hacker News and Lobste.rs remain mostly high-quality, but the well is drying.&lt;/p&gt;
&lt;p&gt;My ask to the reader is straightforward: the next time you want to write something meaningful, consider writing in contiguous paragraphs. &lt;a href=&quot;https://wts.indiana.edu/writing-guides/paragraphs-and-topic-sentences.html&quot;&gt;Here is a brilliant guide on how to write a paragraph&lt;/a&gt;; there is no shame in relearning how to do so. I never understood what it meant to write a paragraph more than “it has a complete thought” and was never taught after grade school. Experiment with pacing your writing and building up to a conclusion.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blakeir.com/always-bet-on-text&quot;&gt;Always bet on text&lt;/a&gt;. Writing is the most powerful and intricate form of human expression; to be a great writer is to be human.&lt;/p&gt;
&lt;p&gt;The first step towards a more literate digital culture is to learn how to write a paragraph.&lt;/p&gt;</content:encoded></item><item><title>Native Instant Space Switching on MacOS</title><link>https://arhan.sh/blog/native-instant-space-switching-on-macos/</link><guid isPermaLink="true">https://arhan.sh/blog/native-instant-space-switching-on-macos/</guid><pubDate>Mon, 23 Mar 2026 09:27:02 GMT</pubDate><content:encoded>&lt;p&gt;The worst part about the MacOS window management situation is the inability to instantly switch spaces, and that Apple has &lt;a href=&quot;https://discussions.apple.com/thread/253938203?sortBy=rank&quot;&gt;continuously ignored requests&lt;/a&gt; to disable the nauseating switching animation. Sure, it’s not &lt;em&gt;that&lt;/em&gt; long, but I switch spaces often enough to the point where it becomes very noticeable and drives me insane.&lt;/p&gt;
&lt;p&gt;I believe to have found the best solution to instant space switching!&lt;/p&gt;
&lt;p&gt;But before I show you, of course, other people share the same sentiment. I claim that none of the surveyed contemporary solutions, except for what I bring up at the end of this article, suffice for what I want:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Enable the “Reduce motion” setting in System Settings.&lt;/p&gt;
&lt;p&gt;This is always the default answer to this question online, and I’m sick of it! It doesn’t even solve the problem, but rather replaces it with an equally useless fade-in animation. It also has the side effect of activating the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/prefers-reduced-motion&quot;&gt;prefers-reduced-motion&lt;/a&gt; media query on web browsers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install the &lt;a href=&quot;https://github.com/asmvik/yabai&quot;&gt;yabai&lt;/a&gt; tiling window manager and use its instant space switcher.&lt;/p&gt;
&lt;p&gt;And to be fair, it works pretty well. There are only two problems: for one, yabai does this by binary patching a part of the operating system. This is only possible by disabling &lt;a href=&quot;https://en.wikipedia.org/wiki/System_Integrity_Protection&quot;&gt;System Integrity Protection&lt;/a&gt; at your own discretion. For the second, installing yabai forces you to learn and use it as your tiling window manager&lt;sup&gt;&lt;a href=&quot;#fn-instantspaces&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. I personally use &lt;a href=&quot;https://github.com/mogenson/PaperWM.spoon&quot;&gt;PaperWM.spoon&lt;/a&gt; as my window manager. Both of which are incompatible when installed together.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use a third-party virtual space manager facade, hiding and showing windows as needed when switching spaces.&lt;/p&gt;
&lt;p&gt;Some popular options are &lt;a href=&quot;https://github.com/wojciech-kulik/FlashSpace&quot;&gt;FlashSpace&lt;/a&gt; and &lt;a href=&quot;https://nikitabobko.github.io/AeroSpace/guide#emulation-of-virtual-workspaces&quot;&gt;AeroSpace virtual workspaces&lt;/a&gt;. I actually offer no criticism other than that they are not native to MacOS, and feel unnecessary given that all we want to do is disable an animation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pay for a license for &lt;a href=&quot;https://folivora.ai&quot;&gt;BetterTouchTool&lt;/a&gt;. Enable “Move Right Space (Without Animation)” and “Move Left Space (Without Animation)”.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Without further ado, I managed to find &lt;a href=&quot;https://github.com/jurplel/InstantSpaceSwitcher&quot;&gt;InstantSpaceSwitcher&lt;/a&gt; by &lt;a href=&quot;https://github.com/jurplel&quot;&gt;jurplel&lt;/a&gt; on GitHub. It is a simple menu bar application that achieves instant space switching while offering &lt;em&gt;none&lt;/em&gt; of the aforementioned drawbacks. You can bind a keybind or use swipe gestures to instantly switch spaces.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/settings._dQOT8aK_SUPFf.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/settings._dQOT8aK_Z1T3Lz8.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/settings._dQOT8aK_Z37rj.png&quot; alt=&quot;A commit with 2,000 contributors&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;639&quot; /&gt;&lt;/picture&gt;&lt;div&gt;Here I have InstantSpaceSwitcher paired up with &lt;a href=&quot;https://github.com/ekalinin/SpaceName&quot;&gt;SpaceName&lt;/a&gt;.&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;InstantSpaceSwitcher does not require disabling Security Integration Protection; it works by simulating a trackpad swipe with a large amount of velocity. It additionally allows you to instantly jump to a space number. The last thing it provides is a command line interface.&lt;/p&gt;
&lt;p&gt;The installation instructions are &lt;a href=&quot;https://github.com/jurplel/InstantSpaceSwitcher#installation&quot;&gt;listed on the README&lt;/a&gt;, and I will briefly repeat them. You can either install InstantSpaceSwiter via Homebrew:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;brew install --cask jurplel/tap/instant-space-switcher&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Building from source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git clone https://github.com/jurplel/InstantSpaceSwitcher&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;cd InstantSpaceSwitcher&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;./dist/build.sh&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;open ./build/InstantSpaceSwitcher.app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or using a &lt;a href=&quot;https://github.com/jurplel/InstantSpaceSwitcher/tags&quot;&gt;pre-built binary&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It is recommended to move &lt;code&gt;InstantSpaceSwitcher.app&lt;/code&gt; to &lt;code&gt;/Applications&lt;/code&gt; to install it as a native application.&lt;/p&gt;
&lt;p&gt;The command line interface is provided at:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;$ InstantSpaceSwitcher.app/Contents/MacOS/ISSCli --help&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Usage: InstantSpaceSwitcher.app/Contents/MacOS/ISSCli [left|right|index &amp;lt;n&amp;gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Did I mention that the repository literally has one star on GitHub (me)? I want more people to discover InstantSpaceSwitcher and consider it trustworthy; hence, please consider giving it a &lt;a href=&quot;https://github.com/jurplel/InstantSpaceSwitcher&quot;&gt;star&lt;/a&gt; if you find it helpful.&lt;/p&gt;
&lt;p&gt;Until next time!&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;I found &lt;a href=&quot;https://github.com/flawnn/instantspaces&quot;&gt;instantspaces&lt;/a&gt; on GitHub, which attempts to isolate yabai’s instant space switcher. Unfortunately, I tried, and I really tried, but I could not get it to work on MacOS Tahoe. Although I anyways prefer InstantSpaceSwitcher, please let me know if you can get this working. &lt;a href=&quot;#fnref-instantspaces&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Memory-corrupting Pong</title><link>https://arhan.sh/blog/memory-corrupting-pong/</link><guid isPermaLink="true">https://arhan.sh/blog/memory-corrupting-pong/</guid><description>Allocating heap memory on the screen</description><pubDate>Mon, 17 Nov 2025 18:50:42 GMT</pubDate><content:encoded>&lt;p&gt;If you’ve kept up with my blog, you might know that my recent &lt;em&gt;“street-cred”&lt;/em&gt; has been messing around with “&lt;a href=&quot;../turning-image-corruption-into-art&quot;&gt;corruption art&lt;/a&gt;.” I can’t help it. Stuff like this is always so fascinating to me.&lt;/p&gt;
&lt;p&gt;Some context would be in order. Two years ago, I made &lt;a href=&quot;https://nand.arhan.sh&quot;&gt;NAND&lt;/a&gt;, a 16-bit computer made entirely from NAND gates emulated on the web. NAND features its own custom CPU architecture, virtual machine, programming language, compiler, and IDE, and it is based on the Jack-VM-Hack platform specified in the &lt;a href=&quot;https://www.nand2tetris.org/&quot;&gt;Nand to Tetris&lt;/a&gt; course. Here’s (single-player) pong!&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/pong.CkeuWA4b.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;Now, I have many &lt;a href=&quot;https://github.com/ArhanChaudhary/NAND/blob/main/README.md&quot;&gt;wonderful things&lt;/a&gt; to talk about with NAND, but we’re not going to be focusing on that. A few weeks ago during the height of my midterms I had a crazy idea: what if we allocated memory on the &lt;em&gt;screen&lt;/em&gt; instead of on the &lt;em&gt;heap&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;To understand what that means, let’s consider this program written in NAND’s custom programming language.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; Main&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    function &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        var &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; length&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        var &lt;/span&gt;&lt;span&gt;Array&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let length &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Keyboard&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;readInt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;How much memory? &quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let a &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Array&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compiler stores the local variables of a function in a memory region called the stack. Everything on the stack must have a size that is known at compile time so the compiler knows how much memory to reserve for it. However, the compiler has no way of knowing how much memory is required to store the array &lt;code&gt;a&lt;/code&gt;—it’s a dynamic amount only known at run time. The contemporary solution is to use a &lt;em&gt;memory allocator&lt;/em&gt;, something that you can ask for an arbitrary amount of memory and will return a pointer to a chunk of that much memory. The memory allocator looks for memory in a memory region called the heap.&lt;/p&gt;
&lt;p&gt;If you run the above program and enter 5, the NAND memory allocator does this to allocate the array:&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;The NAND memory allocator traverses a linked list of memory blocks and returns the first one with enough memory to satisfy the allocation request. It can undoubtedly be made &lt;a href=&quot;https://en.wikipedia.org/wiki/Memory_management#Implementations&quot;&gt;more efficient&lt;/a&gt;. The screen is stored as a bitmap of 512 (length) * 256 (width) = 131072 pixels in its own dedicated memory region. There are no colors; a 0 means black and a 1 means green. To &lt;em&gt;allocate memory on the screen instead of the heap&lt;/em&gt; means to tell the memory allocator to treat the screen memory region as the heap memory region.&lt;/p&gt;
&lt;p&gt;What makes this so interesting is the fact that NAND has no trap instructions, no hardware interrupts, and no concept of a kernel mode. Universally among modern computers, if you try to read or write memory that belongs to another process or memory region, the operating system will trigger a segmentation fault and terminate your program. But NAND gives every program full reign to modify any part of the computer memory; hence, logically invalid memory operations are shamelessly allowed.&lt;/p&gt;
&lt;p&gt;Now to actually do it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Memory.jack&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; Memory&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    static&lt;/span&gt;&lt;span&gt; Array&lt;/span&gt;&lt;span&gt; ptr&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    static&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; offset&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    /** Initializes the class. */&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    function &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; init&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    function &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; offset_&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let ptr &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let ptr&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2048&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 14334&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let ptr&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2049&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 16384&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let offset &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; offset_&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let ptr&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;offset&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 24574&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;span&gt; offset&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let ptr&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;offset &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 24576&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    /** Finds an available RAM block of the given size and returns&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;     *  a reference to its base address. */&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    function &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; alloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        var &lt;/span&gt;&lt;span&gt;Array&lt;/span&gt;&lt;span&gt; segment&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        var &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; length&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;size &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            do&lt;/span&gt;&lt;span&gt; Sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let segment &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 2048&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let segment &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; offset&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;(Reminder that this is NAND’s custom programming language; you can read it like Java)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In terms of modifying the memory allocator, this is all that is needed. The memory allocator normally starts at memory address 2048 and initializes its linked list data structure over there, the start of the heap memory region. This modification tells the memory allocator to start at the integer &lt;code&gt;offset_&lt;/code&gt; provided as an argument during initialization.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Sys.jack&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; Sys&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    /** Performs all the initializations required by the OS. */&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    function &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; init&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        do&lt;/span&gt;&lt;span&gt; Memory&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        do&lt;/span&gt;&lt;span&gt; Memory&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;16384&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        do&lt;/span&gt;&lt;span&gt; Math&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        do&lt;/span&gt;&lt;span&gt; Screen&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        do&lt;/span&gt;&lt;span&gt; Screen&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;clearScreen&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        do&lt;/span&gt;&lt;span&gt; Output&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        do&lt;/span&gt;&lt;span&gt; Main&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        do&lt;/span&gt;&lt;span&gt; Sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;halt&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The entrypoint of every NAND program is hardcoded to be &lt;code&gt;Sys.init&lt;/code&gt;. When this function is called, it initializes the operating system libraries, runs &lt;code&gt;Main.main&lt;/code&gt; to execute the program, and runs &lt;code&gt;Sys.halt&lt;/code&gt; to terminate the program. It’s analogous to the &lt;a href=&quot;http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html&quot;&gt;&lt;code&gt;_start&lt;/code&gt;&lt;/a&gt; entrypoint on Linux. We change &lt;code&gt;Memory.init&lt;/code&gt; to take as input the start of the screen memory region, 16384, so the memory allocator allocates memory on the screen. Additionally, we have to disable the routine that automatically clears the screen at the start of every program because it zeros out the metadata that was just configured by &lt;code&gt;Memory.init&lt;/code&gt; and renders the memory allocator unusable.&lt;/p&gt;
&lt;p&gt;With that out of the way, let’s run it on a hello world program and see what happens.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Main.jack&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; Main&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    function &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        do&lt;/span&gt;&lt;span&gt; Output&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;printString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/helloworld.CJzwGLdP_ZuL6oD.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/helloworld.CJzwGLdP_Z7YG1W.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/helloworld.CJzwGLdP_Z1CypFU.png&quot; alt=&quot;A screen with heap memory and hello world printed&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1080&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Great, there’s our heap! If you look at the top left corner of the screen, you’ll see “Hello World!”. Printing the text to the screen &lt;em&gt;overwrote&lt;/em&gt; some of the heap memory data. It looks wonderful, but this program is relatively uninteresting: it immediately terminates afterwards. Can we run the pong program initially shown with our modified, silly memory allocator? We need to do two more things.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Sys.jack&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    /** Halts the program execution. */&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    function &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; halt&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // Set a hardware-specific flag to tell the computer runtime to stop&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        do&lt;/span&gt;&lt;span&gt; Memory&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;poke&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;24576&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 32767&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;~&lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, whenever a NAND program is finished or the operating system detects something logically invalid like dividing by zero, the operating system prints “ERR” followed by an &lt;a href=&quot;https://github.com/ArhanChaudhary/NAND#error-codes&quot;&gt;error code number&lt;/a&gt; to the screen and calls &lt;code&gt;Sys.halt&lt;/code&gt; to terminate the program&lt;sup&gt;&lt;a href=&quot;#fn-termination&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. We don’t want our program to terminate for any reason, so we simply delete this code.&lt;/p&gt;
&lt;p&gt;Second, we add a prompt before running the program that asks the user to enter an integer offset to add to the screen region memory address (i.e &lt;code&gt;Memory.init(16384 + offset)&lt;/code&gt;).  We do this because allocating heap data at the same place on the screen would produce the same results every time. It’s nice (as you will soon see) to introduce variety in the results. The code at this point doesn’t feel necessary to explain in full detail, so I’ve omitted it.&lt;/p&gt;
&lt;p&gt;We’re off to the races. I spent a few days playing around with memory offsets and want to showcase the most interesting results. First up is memory offset 914:&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/offset_914.Dr0v34VS.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;There’s a lot to unpack here! You might have noticed that the ball appears to &lt;em&gt;teleport&lt;/em&gt;—this is because it is literally overwriting the bits that control its position on the screen while in motion. The ball then overwrites the &lt;em&gt;paddle’s&lt;/em&gt; position bits to the top of the screen and height bits to approximately three times as tall. Despite the extensive memory corruption, why did the pong program still have some semblance of being able to run? NAND uses the &lt;a href=&quot;https://en.wikipedia.org/wiki/Harvard_architecture&quot;&gt;Harvard architecture&lt;/a&gt;, which means that the program memory is stored separately from the instruction memory. The instruction memory can only be written to once when loading a program; it is read-only during its execution. So, the logic to move the paddle around and bounce the ball will always still exist.&lt;/p&gt;
&lt;p&gt;Next, here is memory offset 777:&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/offset_777.BenJVemi.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;The ball is doing some spooky things here—it’s supposed to move in a straight line as a reminder 👻. The main takeaway with this program is that it somehow &lt;em&gt;restarts itself&lt;/em&gt; at the end. Why this happens is simple: the program executed an instruction that sets the &lt;a href=&quot;https://en.wikipedia.org/wiki/Program_counter&quot;&gt;program counter&lt;/a&gt;’s value to 0, effectively telling the program to jump to the first instruction and start over.&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/cthulu.CYkqdeGX.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;Bam, what happened here? I would be lying if I said I knew exactly what happened, but what probably did is the program executed an instruction to jump to some random part in the instruction memory. At that point, all bets on what is supposed to happen are off: the abstractions of function calls and the program logic flow are destroyed. The processor might as well just be executing random instructions and interpreting random noise as memory. You invoked &lt;em&gt;undefined behavior&lt;/em&gt;. NAND invoked &lt;em&gt;Cthulhu&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I don’t have much to say about the next few videos, but you should give each one a moment to marvel at what is actually happening.&lt;/p&gt;
&lt;p&gt;Here is memory offset 6:&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/offset_6.C7Ew4aCW.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;Here is a run with extra modifications that I don’t remember:&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/blinking.DpbEWyqy.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;Here is memory offset 577:&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/offset_577.BnLGuXl_.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;Here is memory offset -10:&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/offset_minus_10.B1oeaU-2.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;This last one is my personal favorite because of how it long it lasts before restarting the program. Try to play pong all the way to the end; it’s a fun challenge.&lt;/p&gt;
&lt;p&gt;I invite you to try out this program with your own memory offsets at &lt;a href=&quot;https://nand.arhan.sh/&quot;&gt;NAND’s website&lt;/a&gt;. To run it, click “Load example program”, select “CorruptedPong”, and click “Start”. Note that your results will not always be deterministic because the program memory persists when a program is manually reset. If you want the same behavior every time, or if you want to reproduce the results of the memory offsets in my videos, make sure to first clear the program memory by clicking “Dec” on the memory view and selecting “Clr”.&lt;/p&gt;
&lt;p&gt;So, yeah. Your takeaway should be that this could technically happen the next time you read one byte of memory out of bounds in C. Until next time!&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;If &lt;code&gt;Memory.poke(24576, 32767)&lt;/code&gt; terminates the program, why does &lt;code&gt;Sys.halt&lt;/code&gt; need an infinite loop? It boils down to an &lt;a href=&quot;https://github.com/ArhanChaudhary/NAND/blob/main/src/core/builtins/runtime_worker.rs#L60-L82&quot;&gt;implementation detail in the computer runtime&lt;/a&gt;: the program will execute up to 30000 instructions at a time before polling memory address 24576 and testing if it is equal to 32767. So, it’s possible for other instructions to modify the program memory after setting the termination flag but before it is polled. It wouldn’t make sense for random memory to be modified after calling &lt;code&gt;Sys.halt&lt;/code&gt; because it can be used to debug the program memory using the built-in memory view. As such, &lt;code&gt;Sys.halt&lt;/code&gt; enters an infinite loop until the termination flag is actively polled again. &lt;a href=&quot;#fnref-termination&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>The Generativity Pattern in Rust</title><link>https://arhan.sh/blog/the-generativity-pattern-in-rust/</link><guid isPermaLink="true">https://arhan.sh/blog/the-generativity-pattern-in-rust/</guid><description>Reinventing ownership</description><pubDate>Mon, 04 Aug 2025 17:59:01 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;This article was peer-reviewed by my close friends &lt;a href=&quot;https://hrovnyak.gitlab.io/&quot;&gt;Henry Rovynak&lt;/a&gt;, &lt;a href=&quot;https://github.com/kartva&quot;&gt;Kartavya Vashishtha&lt;/a&gt;, &lt;a href=&quot;https://www.jackhogan.me/&quot;&gt;Jack Hogan&lt;/a&gt;, &lt;a href=&quot;https://mikail-khan.com/&quot;&gt;Mikhail Khan&lt;/a&gt; and &lt;a href=&quot;https://cad97.com/&quot;&gt;Crystal Durham&lt;/a&gt;. I thank them for their invaluable feedback. This article also uses special characters like the em-dash (—). These characters were lovingly hand-inserted and are not the result of AI-generated text.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#introduction&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#background&quot;&gt;Background&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#permutations&quot;&gt;Permutations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#permutation-groups&quot;&gt;Permutation groups&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-unsafe-approach&quot;&gt;The unsafe approach&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-atomic-id-approach&quot;&gt;The atomic ID approach&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-generativity-approach&quot;&gt;The generativity approach&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#the-fundamental-purpose&quot;&gt;The fundamental purpose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#why-the-implementation-caveat&quot;&gt;Why the implementation caveat?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#how-does-generativity-work&quot;&gt;How does &lt;code&gt;generativity&lt;/code&gt; work?&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#min_generativity&quot;&gt;&lt;code&gt;min_generativity&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-first-part&quot;&gt;The first part&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-second-part&quot;&gt;The second part&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-third-part&quot;&gt;The third part&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#verifying-soundness&quot;&gt;Verifying soundness&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#language-support&quot;&gt;Language support&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#benchmarks&quot;&gt;Benchmarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;The &lt;em&gt;generativity pattern&lt;/em&gt; in Rust is a combination of &lt;a href=&quot;https://cliffle.com/blog/rust-typestate/&quot;&gt;typestate&lt;/a&gt; and &lt;a href=&quot;https://plv.mpi-sws.org/rustbelt/ghostcell/&quot;&gt;GhostCell&lt;/a&gt;, techniques that move what you’d normally check at run-time to compile-time. This pattern is not commonplace; its usage warrants a specific set of circumstances. However, it is a hugely important part of &lt;a href=&quot;https://github.com/kyren/gc-arena/?tab=readme-ov-file#prior-art&quot;&gt;garbage&lt;/a&gt; &lt;a href=&quot;https://github.com/Manishearth/rust-gc&quot;&gt;collection&lt;/a&gt; utilities and other niche Rust crates.&lt;/p&gt;
&lt;p&gt;Aside from thinly spread academic literature&lt;sup&gt;&lt;a href=&quot;#fn-literature&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, I haven’t found an accessible analysis of this pattern online. In order to build up a full picture of the “what” and more importantly the “why,” we will first spend some time walking through a realistic example to gauge the type of problem the generativity pattern solves—statically requiring data to come from or refer to the same source—as a &lt;em&gt;stronger&lt;/em&gt; form of ownership. Then, we will introduce the generativity pattern and explain how to use it in the latter half of this article. Finally, we will follow up with a study of &lt;a href=&quot;https://cad97.com/&quot;&gt;Crystal Durham&lt;/a&gt;’s &lt;a href=&quot;https://crates.io/crates/generativity&quot;&gt;&lt;code&gt;generativity&lt;/code&gt;&lt;/a&gt; crate, a novel improvement to the generativity pattern. Buckle up!&lt;/p&gt;
&lt;h1&gt;Background&lt;/h1&gt;
&lt;h2&gt;Permutations&lt;/h2&gt;
&lt;p&gt;Let us take the role of a crate author about permutations. We want to investigate the &lt;a href=&quot;https://en.wikipedia.org/wiki/Permutation_group#Composition_of_permutations%E2%80%93the_group_product&quot;&gt;composition&lt;/a&gt; of zero-indexed permutations. This can be expressed nicely visually.&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;The permutation &lt;code&gt;b&lt;/code&gt; defines the remapping of the elements from permutation &lt;code&gt;a&lt;/code&gt;. Pretty simple. Notice that permutation composition is only possible under the following three conditions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; must have the same length.&lt;/li&gt;
&lt;li&gt;Every element from &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; must be non-negative and less than the length.&lt;/li&gt;
&lt;li&gt;Every element from &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; must be unique.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Our library is general-purpose, so it is important to handle these error cases. Here is the simplest way to do that.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/// We provide a `compose_into` function in case the caller already&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;/// has a permutation preallocated. (This is good practice IMO).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Permutations must have the same length&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; seen_b &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; seen_a &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;result_value&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;b_value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;iter_mut&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;zip&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;seen_b&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b_value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span&gt;ok_or&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;B contains an element greater than or equal to the length&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            return&lt;/span&gt;&lt;span&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;B contains repeated elements&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        seen_b&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;b_value&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; a_value &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;b_value&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;seen_a&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a_value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span&gt;ok_or&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;A contains an element greater than or equal to the length&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            return&lt;/span&gt;&lt;span&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;A contains repeated elements&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        seen_a&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;a_value&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;result_value &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; a_value&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Ok&lt;/span&gt;&lt;span&gt;(())&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Good on you if this made your Rust senses tingle because we shouldn’t have to validate &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; every time. Rust allows us to enforce at the type level that they are valid permutations, using the &lt;a href=&quot;https://rust-unofficial.github.io/patterns/patterns/behavioural/newtype.html&quot;&gt;newtype&lt;/a&gt; design pattern.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Box&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; from_mapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // This function errors if `mapping` is an invalid&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // permutation or its length does not match the second&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // argument. The implementation is ommitted.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        validate_permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; mapping&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;into_boxed_slice&lt;/span&gt;&lt;span&gt;()))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            return&lt;/span&gt;&lt;span&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Permutations must have the same length&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;result_value&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;b_value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;iter_mut&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;zip&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            // SAFETY: `b` is guaranteed to be a valid permutation&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            // whose elements can index `self`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            *&lt;/span&gt;&lt;span&gt;result_value &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b_value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Ok&lt;/span&gt;&lt;span&gt;(())&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;into_boxed_slice&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;aside&gt;&lt;p&gt;Unsafe is going to be a recurring theme here. You’ve had your fair warning.&lt;/p&gt;&lt;/aside&gt;
&lt;p&gt;The newtype pattern is more useful than just for getting around the orphan rule. We restrict construction of &lt;code&gt;Permutation&lt;/code&gt; to &lt;code&gt;Permutation::from_mapping&lt;/code&gt;, which returns an error if the input is not a valid permutation. That means if we have an instance of &lt;code&gt;Permutation&lt;/code&gt;, we don’t have to worry about its mapping being potentially invalid, reducing the validation overhead to a length check and permitting unsafe during permutation composition. Rustaceans describe type-level guarantees like this by saying an &lt;em&gt;invariant&lt;/em&gt; of &lt;code&gt;Permutation&lt;/code&gt; is that it represents a valid permutation. Composing two permutations upholds this invariant, so we expose &lt;code&gt;Permutation::compose&lt;/code&gt; to create a new &lt;code&gt;Permutation&lt;/code&gt; from existing ones.&lt;/p&gt;
&lt;p&gt;This code is a major improvement! It is simple, easy to use, and it provides reasonable errors. However, a closer examination reveals some problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Every call to our composition function spends time performing a length check. Our example is simplistic so it happens to be cheap, but this type of check may require more expensive logic in a practical scenario. Note that we can’t use const generic lengths because our library operates on arbitrarily-sized slices at run-time.&lt;/li&gt;
&lt;li&gt;Returning a &lt;code&gt;Result&lt;/code&gt; forces the caller to be prepared to handle the error variant. Library users might be able to guarantee that the length checks will pass, which would make the error handling more annoying than helpful.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Yes, these aren’t &lt;em&gt;important&lt;/em&gt; problems per se, but they are still inconveniences to be aware of.&lt;/p&gt;
&lt;h2&gt;Permutation groups&lt;/h2&gt;
&lt;p&gt;We now want to extend our library to model a &lt;a href=&quot;https://en.wikipedia.org/wiki/Permutation_group&quot;&gt;permutation group&lt;/a&gt;, a description of a set of permutations. In a permutation group, every permutation in the set can be written as a sequence of compositions of a select few &lt;em&gt;base permutations&lt;/em&gt;, which we will use to represent the entire collection. For example, the manipulations of the Rubik’s Cube form a permutation group. Its base permutations which represent the entire permutation group are the six face rotations. By definition, every possible state on the Rubik’s Cube can be reached from a combination of those face rotations.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/Stickered%20Cube.DFWwGJj3_ZcaYgy.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/Stickered%20Cube.DFWwGJj3_aAq68.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/Stickered%20Cube.DFWwGJj3_Z1jXixP.png&quot; alt=&quot;The solved Rubik&apos;s Cube&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;625&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;The illustrated turn is a permutation fifty-four elements long, because there are fifty-four stickers on a Rubik’s Cube&lt;sup&gt;&lt;a href=&quot;#fn-cube&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;It follows that if you compose two permutations in a permutation group, the resulting permutation will also be a permutation in that group. The reasoning is not so relevant; take this at face value.&lt;/p&gt;
&lt;p&gt;A reasonable data structure for permutation groups looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    base_permutation_length&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    base_permutations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        base_permutation_length&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        base_permutation_mappings&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    )&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        for&lt;/span&gt;&lt;span&gt; mapping &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;base_permutation_mappings &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            validate_permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; base_permutation_length&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            base_permutation_length&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            base_permutations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; base_permutation_mappings&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                .&lt;/span&gt;&lt;span&gt;into_iter&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                .&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;into_boxed_slice&lt;/span&gt;&lt;span&gt;()))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                .&lt;/span&gt;&lt;span&gt;collect&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; base_permutations&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your &lt;em&gt;inner Ferris&lt;/em&gt; awakens. With the annoyances of our last iteration freshly in memory, you ask yourself: can we perform that length check (done in the &lt;code&gt;validate_permutation&lt;/code&gt; function) during the creation of &lt;code&gt;PermGroup&lt;/code&gt;, and avoid it entirely in &lt;code&gt;Permutation::compose_into&lt;/code&gt;? Then, can we tweak our composition function to only operate on permutations from the same permutation group?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // No `from_mapping` method. `Permutation` can only be&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // constructed within `PermGroup::new`, and accessed via&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // `PermGroup::base_permutations`.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        for&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;..&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            // SAFETY: ... ?&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                *&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked_mut&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;into_boxed_slice&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        result&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All of a sudden, we’ve opened up an unsafety hole! We implicitly assumed that the permutations to compose were from the same permutation group. This is not necessarily true: what if a library user composes two base permutations from different permutation groups? If the permutation lengths &lt;em&gt;don’t&lt;/em&gt; match, &lt;code&gt;get_unchecked&lt;/code&gt; will index out of bounds and exhibit undefined behavior; this is clearly a problem! The intent of this operation is obviously nonsensical, but it does not change the fact that it is still our responsibility, as the crate author, that the safe functions we provide can never cause undefined behavior.&lt;/p&gt;
&lt;p&gt;There is a more fundamental reason to care about this unsoundness if left unchecked. An invariant of permutation composition within the same permutation group is membership; if the permutations to compose are in the same permutation group, the resulting permutation is also in that group. Even if the lengths of permutations from two different permutation groups &lt;em&gt;did&lt;/em&gt; match, composing them could produce a permutation outside of either group, which is a logic error. Other code may even have unsafe blocks that rely on permutation group membership, for example a Rubik’s Cube solver optimized for speed.&lt;/p&gt;
&lt;p&gt;Mitigating this by checking permutation group membership every function call is a very expensive operation. This is an example of the “practical scenario” mentioned beforehand.&lt;/p&gt;
&lt;p&gt;We have demonstrated that the newtype pattern alone is not powerful enough to prevent this logic error. We will analyze different approaches that ensure our library only permits permutation composition within the same permutation group. Each has their own trade-offs, but are all right answers for different situations. They will also lay the groundwork to justify using the generativity pattern.&lt;/p&gt;
&lt;p&gt;All the code segments provided in this article can be found &lt;a href=&quot;https://github.com/ArhanChaudhary/generativity-pattern-rs&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;The unsafe approach&lt;/h1&gt;
&lt;p&gt;The simplest solution is to mark &lt;code&gt;Permutation::compose_into&lt;/code&gt; and &lt;code&gt;Permutation::compose&lt;/code&gt; unsafe.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/// # Safety&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;///&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;/// `self`, `b`, and `result` must all be from the same&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;/// permutation group.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; unsafe&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;..&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // SAFETY: permutations within the same group can be&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // composed.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            *&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked_mut&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Although the extent of the undefined behavior with permutation composition is just the bounds checking, the goal of this approach is to enforce permutation group membership. Thus, the above safety contract is made more restrictive to reflect this idea. The usage of unsafe to maintain a validity invariant is contentious. Permutation composition of the same length within different permutation groups is a logic error, and it violates the safety contract, but is not technically unsafe. Sure, you might panic later on or get some other issue, but this alone will never cause undefined behavior.&lt;/p&gt;
&lt;p&gt;To play devil’s advocate, since we only care about composition within the same permutation group, one may consider producing an invalid value from this type of permutation composition undefined behavior. With the safety contract’s additional restriction, calling code no longer has to worry about handling this logic error, while additionally gaining the contextual benefit of this assumption. Personally, I believe this use of unsafe is warranted—at the end of the day, the safety contract does still prevent undefined behavior. I encourage you to &lt;a href=&quot;https://users.rust-lang.org/t/should-i-use-unsafe-merely-to-encourage-users-to-maintain-invariants/27856&quot;&gt;have your own opinion&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you don’t care about using unsafe—and there are valid reasons not to—then this might be what you want. That said, it’s not always going to be this simple. What if we introduce a new trait, &lt;code&gt;ComposablePermutation&lt;/code&gt;, that generalizes over different permutation representations? For example, the &lt;code&gt;PSHUFB&lt;/code&gt; instruction can compose two permutations in a single clock cycle if they have less than sixteen elements.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; trait&lt;/span&gt;&lt;span&gt; ComposablePermutation&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Clone&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    fn&lt;/span&gt;&lt;span&gt; from_mapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    /// # Safety&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ///&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    /// `self`, `b`, and `result` must all be from the same&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // permutation group.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    unsafe&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    /// # Safety&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ///&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    /// `self` and `b` must both be from the same permutation&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // group.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    unsafe&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;clone&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // SAFETY: `self`, `b`, and `result` are all from the&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // same permutation group.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        result&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt; ComposablePermutation&lt;/span&gt;&lt;span&gt; for&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The consequences of using unsafe begin to show. Because our generic &lt;code&gt;Permutation&lt;/code&gt; implements &lt;code&gt;ComposablePermutation&lt;/code&gt;, and we have shown that permutation composition from different permutation groups may cause undefined behavior, &lt;code&gt;Permutation::compose_into&lt;/code&gt; must be made unsafe at the trait level. Rust doesn’t allow us to only make &lt;code&gt;Permutation&lt;/code&gt;’s implementation unsafe. Either all implementers must be made unsafe, or none at all. In a library &lt;em&gt;about&lt;/em&gt; permutation composition, we have now forced our users to wrangle with unsafe for its most essential operation. Not just with &lt;code&gt;Permutation::compose_into&lt;/code&gt;, but with all of their own implementations of &lt;code&gt;ComposablePermutation&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“That is completely unfair!”&lt;/em&gt; You might say. &lt;em&gt;“This is a small edge condition I don’t care about. I’m going to mark this trait method safe anyways.”&lt;/em&gt; Well, the Rust community generally has a zero-tolerance stance on undefined behavior; the last time someone wanted to mark an unsound method safe, &lt;a href=&quot;https://github.com/ogxd/gxhash/issues/82#issuecomment-2257578785&quot;&gt;it didn’t end very well&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;The atomic ID approach&lt;/h1&gt;
&lt;p&gt;The second approach is to validate our base permutations &lt;em&gt;upfront&lt;/em&gt; and use a private integer to associate them to a unique permutation group. This simplifies the test for permutation group membership to a cheap integer comparison. Internalizing how this approach works will be crucial to understanding the generativity approach. Rereading is encouraged.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;sync&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;atomic&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;AtomicU64&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; Ordering&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Relaxed&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    base_permutation_length&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    base_permutations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; u64&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; ID&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; AtomicU64&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; AtomicU64&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        base_permutation_length&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        base_permutation_mappings&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    )&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        for&lt;/span&gt;&lt;span&gt; mapping &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;base_permutation_mappings &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            validate_permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; base_permutation_length&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; id &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ID&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fetch_add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; Relaxed&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            base_permutation_length&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            base_permutations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; base_permutation_mappings&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                .&lt;/span&gt;&lt;span&gt;into_iter&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                .&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;into_boxed_slice&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                .&lt;/span&gt;&lt;span&gt;collect&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            id&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; base_permutations&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The implementation of &lt;code&gt;PermGroup&lt;/code&gt; does not actually change much. As before, we check that all mappings from &lt;code&gt;base_permutation_mappings&lt;/code&gt; are valid permutations of the same length before creating a new &lt;code&gt;PermGroup&lt;/code&gt;. This time, we utilize a global &lt;code&gt;AtomicU64&lt;/code&gt; to uniquely identify the permutations in a permutation group, passing it as an integer to &lt;code&gt;Permutation&lt;/code&gt;. The integer is guaranteed to be unique for &lt;code&gt;Permutation&lt;/code&gt;s among different &lt;code&gt;PermGroup&lt;/code&gt;s because we increment the identifier every call to &lt;code&gt;PermGroup::new&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Box&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; u64&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; from_mapping_and_group&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        mapping&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        group&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;PermGroup&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    )&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        validate_permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutation_length&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; permutation &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;into_boxed_slice&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        validate_permutation_group_membership&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;permutation&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;permutation&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            return&lt;/span&gt;&lt;span&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Permutations must come from the same permutation group&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        for&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;..&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            // SAFETY: `self`, `b`, and `result` have the same ID.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            // Therefore, they are members of the same group and&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            // can be composed.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                *&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked_mut&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Ok&lt;/span&gt;&lt;span&gt;(())&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;into_boxed_slice&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Creating a new &lt;code&gt;Permutation&lt;/code&gt; now requires a mapping and a &lt;code&gt;PermGroup&lt;/code&gt; reference. Once the mapping is verified as both a valid permutation and a member of that permutation group, only then is a new &lt;code&gt;Permutation&lt;/code&gt; created with that &lt;code&gt;PermGroup&lt;/code&gt;’s identifier, as a “token” of its membership. We can no longer create &lt;code&gt;Permutation&lt;/code&gt;s willy-nilly from just a mapping because that would offer no guarantees about the uniqueness of its identifier.&lt;/p&gt;
&lt;p&gt;The fruits of our labor are rewarded in &lt;code&gt;Permutation::compose_into&lt;/code&gt;. The expensive permutation group membership test is performed exclusively during &lt;code&gt;Permutation&lt;/code&gt;’s creation. When two permutations are composed, those same “tokens” are used to cheaply verify membership within the same permutation group. Hence, callers can safely assume permutation composition produces another permutation in the same permutation group without compromising efficiency.&lt;/p&gt;
&lt;p&gt;This solution is likely to be considered good enough in industry—most practitioners would need a good reason to care more about this problem. However, if your interest is piqued, what would really be nice is an &lt;em&gt;infallible&lt;/em&gt; yet &lt;em&gt;zero-cost&lt;/em&gt; permutation composition operation—one that is guaranteed to be valid at compile-time and as fast as the unsafe approach. If you’re willing to go a small step farther, we arrive at…&lt;/p&gt;
&lt;h1&gt;The generativity approach&lt;/h1&gt;
&lt;p&gt;The big reveal: the generativity approach is functionally equivalent to the atomic ID approach, except everything is done at compile-time. Generativity solves the fundamental problem thus far: the invariant of &lt;code&gt;Permutation&lt;/code&gt; guarantees it is a valid permutation, but not that it is necessarily associated with a specific &lt;code&gt;PermGroup&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Existing literature achieves generativity by sacrificing ergonomics and readability. They require wrapping all code in (often deeply nested) closures, warding off much of their interest in practice. We will spend the rest of this article examining &lt;a href=&quot;https://cad97.com/&quot;&gt;Crystal Durham&lt;/a&gt;’s &lt;a href=&quot;https://crates.io/crates/generativity&quot;&gt;&lt;code&gt;generativity&lt;/code&gt;&lt;/a&gt; crate, which utilizes a novel and highly experimental technique to achieve generativity without needing a closure. Later, we will show that the &lt;code&gt;generativity&lt;/code&gt; crate is a zero-cost compile-time abstraction.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Subtle-but-no-so-subtle foreshadowing: we will explore my own improvement to this technique in the next section)&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt; generativity&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;Guard&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; make_guard&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // Create a variable `guard` of type `Guard&amp;lt;&apos;_&amp;gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    make_guard&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;guard&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // Consume that `guard` into an `Id&amp;lt;&apos;_&amp;gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; guard&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;into&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;generativity&lt;/code&gt; publicizes three things: &lt;code&gt;Guard&lt;/code&gt;, &lt;code&gt;Id&lt;/code&gt;, and &lt;code&gt;make_guard&lt;/code&gt;. Invoking the &lt;code&gt;make_guard&lt;/code&gt; macro creates a &lt;code&gt;Guard&amp;lt;&apos;_&amp;gt;&lt;/code&gt; with a let binding, an identifier that carries a guaranteed unique lifetime. This lifetime is not actually used as a lifetime in the usual sense. It exists solely to make each instance of &lt;code&gt;Guard&amp;lt;&apos;_&amp;gt;&lt;/code&gt; a unique type. This is not voluntary nor merely a suggestion; the following &lt;em&gt;does not compile&lt;/em&gt; because &lt;code&gt;make_guard&lt;/code&gt;’s lifetime uniqueness guarantee cannot be broken&lt;sup&gt;&lt;a href=&quot;#fn-unique&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; unify_lifetimes&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Guard&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Guard&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;make_guard!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;make_guard!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// rejected: unique lifetimes cannot be unified (this&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// is not the actual compiler error message)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;unify_lifetimes&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Id&amp;lt;&apos;_&amp;gt;&lt;/code&gt; is like &lt;code&gt;Guard&amp;lt;&apos;_&amp;gt;&lt;/code&gt; except that it implements &lt;code&gt;Copy&lt;/code&gt; and &lt;code&gt;Clone&lt;/code&gt; while the latter does not. So, to create distributable copies of this identifier, you must consume a &lt;code&gt;Guard&amp;lt;&apos;_&amp;gt;&lt;/code&gt; into an &lt;code&gt;Id&amp;lt;&apos;_&amp;gt;&lt;/code&gt; using its &lt;code&gt;From&lt;/code&gt; implementation. This is all that &lt;code&gt;generativity&lt;/code&gt; exports.&lt;/p&gt;
&lt;p&gt;With the generativity pattern in place, the body of &lt;code&gt;PermGroup::new&lt;/code&gt; remains sound because it creates &lt;code&gt;Permutation&lt;/code&gt;s with the same lifetime identifier, making it unique among different &lt;code&gt;PermGroup&lt;/code&gt;s.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    base_permutation_length&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    base_permutations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; u64&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    base_permutation_length&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    base_permutation_mappings&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    guard&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Guard&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; mapping &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;base_permutation_mappings &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        validate_permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; base_permutation_length&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; id &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ID&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fetch_add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; Relaxed&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; id &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; guard&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;into&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        base_permutation_length&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        base_permutations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; base_permutation_mappings&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span&gt;into_iter&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mapping&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;into_boxed_slice&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span&gt;collect&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        id&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why is &lt;code&gt;guard&lt;/code&gt; passed as an argument, and why isn’t &lt;code&gt;make_guard&lt;/code&gt; creating it within the function body? This reveals &lt;code&gt;generativity&lt;/code&gt;’s implementation caveat: a &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; can never escape the scope it was defined in. Think of creating a &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; as creating a reference to a local variable. No matter what, it is only valid inside of its enclosing scope.&lt;/p&gt;
&lt;p&gt;So, instantiating two different permutation groups, for example, looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;make_guard!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;guard1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;make_guard!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;guard2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; first &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; guard1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; second &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; guard2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// rejected: `guard1` used after move&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// let third = PermGroup::new(..., guard1);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The purpose of &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; when &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; already exists becomes clear when considering that &lt;code&gt;third&lt;/code&gt; is rejected by the compiler. If &lt;code&gt;PermGroup::new&lt;/code&gt; accepted an &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt;, two different permutation groups could be assigned the same &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; because it implements &lt;code&gt;Copy&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Okay, this is all fine and dandy, but how does this help improve permutation composition?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Box&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; u64&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Box&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Recall that every &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; carries a unique lifetime among different &lt;code&gt;PermGroup&amp;lt;&apos;id&amp;gt;&lt;/code&gt;s. By combining &lt;code&gt;Permutation&lt;/code&gt; with &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; and a lifetime parameter, we create a collection &lt;code&gt;Permutation&amp;lt;&apos;id&amp;gt;&lt;/code&gt;s whose types are the same within a &lt;code&gt;PermGroup&amp;lt;&apos;id&amp;gt;&lt;/code&gt; but distinct from permutations within other &lt;code&gt;PermGroups&amp;lt;&apos;id2&amp;gt;&lt;/code&gt;s. Our permutation composition function takes in the same type &lt;code&gt;Self&lt;/code&gt; for all arguments—it follows that &lt;code&gt;Permutation&amp;lt;&apos;id&amp;gt;&lt;/code&gt;s from different permutation groups cannot be composed as they are not the same type, and &lt;code&gt;Permutation&amp;lt;&apos;id&amp;gt;&lt;/code&gt;s from the same permutation group can be composed as they are the same type. This is the essence of the generativity pattern, enforced at compile-time.&lt;/p&gt;
&lt;p&gt;Behold: a permutation composition function that is unchecked, infallible, and safe. The full implementation is &lt;a href=&quot;https://github.com/ArhanChaudhary/generativity-pattern-rs/blob/main/src/5-generativity.rs&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Permutations must come from the same permutation group&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; compose_into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;..&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // SAFETY: `self`, `b`, and `result` are members of the&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // same group and can be composed.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            *&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked_mut&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_unchecked&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Ok&lt;/span&gt;&lt;span&gt;(())&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let us informally prove &lt;code&gt;generativity&lt;/code&gt;’s equivalence to the atomic ID approach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the atomic ID approach, unique integer identifiers are created à la &lt;code&gt;ID.fetch_add(1, Relaxed)&lt;/code&gt;. This directly parallels &lt;code&gt;make_guard!(guard)&lt;/code&gt;, which creates a unique &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; identifier.&lt;/li&gt;
&lt;li&gt;The unique integer identifier is then stored inside a primitive &lt;code&gt;u64&lt;/code&gt;. This implements &lt;code&gt;Copy&lt;/code&gt; and it is distributed among the input base permutations to associate each one with its permutation group. Similarly, &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; serves this purpose.&lt;/li&gt;
&lt;li&gt;The unique integer identifier is used to test permutation group membership during permutation composition, erroring if not the case. The generativity pattern directly embeds the same test into the type system.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It would be irresponsible for me to advertise the &lt;code&gt;generativity&lt;/code&gt; crate as a perfect solution barring its implementation caveat. Yes, the implementation caveat is its only functional limitation, but there are some developer experience problems to consider.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Although there’s only a single line marked unsafe in our &lt;code&gt;Permutation&amp;lt;&apos;id&amp;gt;&lt;/code&gt; example, its soundness is now much harder to justify. It is on the developer to prove that &lt;code&gt;&apos;id&lt;/code&gt; uniquely associates permutations to their permutation group; any mishandling could easily make the whole thing unsound (i.e. if &lt;code&gt;PermGroup::new&lt;/code&gt; took an &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; instead of a &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;&apos;id&lt;/code&gt; lifetime, like all other lifetimes, is pervasive. Data structures that wish to store &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; or &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt;, or any other data structure that stores &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; or &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt;, must have a lifetime annotation. But &lt;code&gt;make_guard&lt;/code&gt; is typically invoked at the outermost scope, and will likely have to be passed through many types, so the number of lifetime annotations is amplified.&lt;/li&gt;
&lt;li&gt;Some APIs require types to satisfy &lt;code&gt;&apos;static&lt;/code&gt;. For example, the closure passed to &lt;code&gt;thread::spawn&lt;/code&gt; must satisfy &lt;code&gt;&apos;static&lt;/code&gt;, making it impossible to return a &lt;code&gt;Permutation&amp;lt;&apos;id&amp;gt;&lt;/code&gt;. The workaround is usually an inconvenient band-aid; in this case the standard library offers &lt;code&gt;thread::scope&lt;/code&gt; to borrow non-&lt;code&gt;&apos;static&lt;/code&gt; data in a thread.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=4675f6eb33925940c51668ee15a00010&quot;&gt;compiler errors&lt;/a&gt; from misusing &lt;code&gt;generativity&lt;/code&gt; don’t provide the location of the error. They are generally confusing, even when you know how &lt;code&gt;generativity&lt;/code&gt; internally works.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The atomic ID approach shares only the first problem. Given your use case, it might be what you want.&lt;/p&gt;
&lt;h2&gt;The fundamental purpose&lt;/h2&gt;
&lt;p&gt;Notice how different instances of &lt;code&gt;Permutation&amp;lt;&apos;id&amp;gt;&lt;/code&gt; masquerade as separate types even though they have the same underlying data representation. In Rust, &lt;code&gt;&apos;id&lt;/code&gt; is known as a &lt;em&gt;branded lifetime&lt;/em&gt;, or more generally, a &lt;em&gt;type brand&lt;/em&gt;. The first principles of type branding date back at least to the work of John Launchbury and Simon Peyton Jones on the &lt;a href=&quot;https://doi.org/10.1007/BF01018827&quot;&gt;ST monad in Haskell&lt;/a&gt; (section 2.5.2) in 1995. Aria Desires’ &lt;a href=&quot;https://github.com/Gankra/thesis/blob/master/thesis.pdf&quot;&gt;master’s thesis&lt;/a&gt; (section 6.3) brought this into the context of Rust in 2015, coining lifetime branding in Rust with the term “generativity.” The more recent &lt;a href=&quot;https://plv.mpi-sws.org/rustbelt/ghostcell/&quot;&gt;GhostCell paper&lt;/a&gt; by Joshua Yanovski and others utilized generativity to present interior mutability as a zero-cost abstraction in 2021.&lt;/p&gt;
&lt;p&gt;This segues into an important point. The fundamental purpose of the generativity pattern is not necessarily to improve performance, but to statically require that individual values come from or refer to the same source. The performance benefits are a symptom of this requirement. I like to informally think of it as a stronger form of ownership.&lt;/p&gt;
&lt;p&gt;For an alternative perspective, Aria Desires’ master’s thesis explores this idea with &lt;code&gt;BrandedVec&lt;/code&gt;, an append-only vector. When the &lt;code&gt;i&lt;/code&gt;th element of an ordinary vector &lt;code&gt;vec&lt;/code&gt; is accessed through &lt;code&gt;&amp;amp;vec[i]&lt;/code&gt;, a run-time check is performed to see if &lt;code&gt;i&lt;/code&gt; is in bounds. If not, then the program will panic. However, in many situations we know that the indices are always in bounds; one such case regards the append-only vector, the &lt;code&gt;BrandedVec&lt;/code&gt;. All elements pushed to this type of vector are forever valid. Leveraging this fact, the push operation returns the index of the pushed element so it can later be used to soundly perform unchecked indexing.&lt;/p&gt;
&lt;p&gt;If we want to mark the unchecked indexing operation safe, this returned index can’t be an ordinary &lt;code&gt;usize&lt;/code&gt;. Bad actors may provide their own &lt;code&gt;usize&lt;/code&gt; instead of one returned from the push operation. This returned index can’t be a newtyped &lt;code&gt;usize&lt;/code&gt; either. The problem with this is a microcosm of the problem with our initial &lt;code&gt;Permutation&lt;/code&gt; example: different indices from different append-only vectors may be used to unsoundly index one another. To make our accesses safe, the solution is to lifetime brand the returned indices to statically associate them with &lt;code&gt;BrandedVec&lt;/code&gt;—the generativity pattern.&lt;/p&gt;
&lt;p&gt;As hinted to beforehand, generativity has traditionally only been achieved through the use of a closure. The GhostCell paper includes this following example, taken from its inspired &lt;a href=&quot;https://gitlab.mpi-sws.org/FP/ghostcell/-/blob/master/ghostcell/examples/branded_vec.rs&quot;&gt;adaption&lt;/a&gt; of &lt;code&gt;BrandedVec&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; vec1&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 11&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; vec2&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 21&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;BrandedVec&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;vec1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; move&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; bvec1&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; BrandedVec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bvec1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;12&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; i1&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; bvec1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;13&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; _idx&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; bvec1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_index&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unwrap&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    BrandedVec&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;vec2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; move&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; bvec2&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; BrandedVec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; i2&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; bvec2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;22&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;:?&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; bvec2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i2&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;span&gt; // No bound check! Prints 22&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;bvec2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_mut&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;         // No bound check!&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;:?&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; bvec2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i2&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;span&gt; // Prints 21&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;:?&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; bvec1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i1&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;span&gt; // Prints 13&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // rejected: i1 is not an index of bvec2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // println!(&quot;{:?}&quot;, bvec2.get(i1));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each &lt;code&gt;BrandedVec&lt;/code&gt; created from a &lt;code&gt;Vec&lt;/code&gt; receives its own lifetime brand within each closure&lt;sup&gt;&lt;a href=&quot;#fn-brandedvec&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. In terms of ergonomics, it’s not exactly your Friendly Neighborhood Spider-Man.&lt;/p&gt;
&lt;p&gt;But through the &lt;code&gt;generativity&lt;/code&gt; crate, we eliminate the rightward drift, changing just &lt;a href=&quot;https://github.com/ArhanChaudhary/generativity-pattern-rs/commit/806c8bef89b1d0c0621db42c130856bf33fffb9f&quot;&gt;nine lines&lt;/a&gt; of &lt;code&gt;BrandedVec&lt;/code&gt;’s implementation. The API now appears less foreign and more Rust-like.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; vec1&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 11&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; vec2&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 21&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;make_guard!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;guard1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; bvec1 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; BrandedVec&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;vec1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; guard1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;bvec1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;12&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; i1 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; bvec1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;13&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; _idx &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; bvec1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_index&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unwrap&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;make_guard!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;guard2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; bvec2 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; BrandedVec&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;vec2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; guard2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; i2 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; bvec2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;22&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;:?&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; bvec2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i2&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;span&gt; // No bound check! Prints 22&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;bvec2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get_mut&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;         // No bound check!&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;:?&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; bvec2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i2&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;span&gt; // Prints 21&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;:?&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; bvec1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i1&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;span&gt; // Prints 13&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// rejected: i1 is not an index of bvec2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// println!(&quot;{:?}&quot;, bvec2.get(i1))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our digression in bringing up this comparison has an ulterior motive. The original closure technique bears the exact same implementation caveat with &lt;code&gt;generativity&lt;/code&gt;: nothing declared inside of the closure can escape it. &lt;code&gt;make_guard&lt;/code&gt; effectively does the same thing as wrapping the rest of the function in an immediately invoked closure, and is no less capable than the closure technique.&lt;/p&gt;
&lt;h2&gt;Why the implementation caveat?&lt;/h2&gt;
&lt;p&gt;Let us offer another perspective as to why &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; cannot escape its defining scope. StackOverflow user &lt;a href=&quot;https://stackoverflow.com/users/865874/rodrigo&quot;&gt;rodrigo&lt;/a&gt; &lt;a href=&quot;https://stackoverflow.com/a/76876800&quot;&gt;points out&lt;/a&gt; that you can achieve something similar to &lt;code&gt;generativity&lt;/code&gt; using an anonymous unit struct and a macro to create the permutation group. Successive calls to this macro create permutation groups branded by this newly generated unit struct. In the context of our &lt;code&gt;Permutation&lt;/code&gt; example, example usage looks like this. The full implementation is &lt;a href=&quot;https://github.com/ArhanChaudhary/generativity-pattern-rs/blob/main/src/6-unsound_token.rs&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;macro_export&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;macro_rules!&lt;/span&gt;&lt;span&gt; new_perm_group&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;$len&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;expr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; $mappings&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;expr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; len &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; $len&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; mappings &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; $mappings&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        struct&lt;/span&gt;&lt;span&gt; InvariantToken&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // SAFETY: private API, only used in this macro.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;PermGroup&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;InvariantToken&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; mappings&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }};&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; first_perm_group &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new_perm_group!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;]])&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unwrap&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; second_perm_group &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new_perm_group!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;]])&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unwrap&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; first_perm &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;first_perm_group&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;span&gt;()[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; second_perm &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;second_perm_group&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;span&gt;()[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// rejected: `first_perm` and `second_perm` are not the same type&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// first_perm.compose(second_perm);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The flaw is quite subtle. The macro constructor creates a token per-&lt;em&gt;call-site&lt;/em&gt; instead of per-&lt;em&gt;owner&lt;/em&gt;. Every expression results in a particular type; if the same macro is run more than once, it will produce the same type, even if it is unique to the expression. This can be exploited to give multiple owners the same brand. To exemplify:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; first &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;]]);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; second &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;]]);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; perm_groups &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; mappings&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; second&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // I expanded the macro to make it easier to understand!&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // perm_groups.push(new_perm_group!(len, mappings).unwrap());&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    perm_groups&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; mappings&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; mappings&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        struct&lt;/span&gt;&lt;span&gt; InvariantToken&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        // SAFETY: private API, only used in this macro.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;PermGroup&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;InvariantToken&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; mappings&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unwrap&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; first_perm &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;perm_groups&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;span&gt;()[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; second_perm &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;perm_groups&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;span&gt;()[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// not rejected, UB!&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;first_perm&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;second_perm&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have just invoked undefined behavior from safe user-facing code. This is unsound without question, and there is no point in endorsing this approach.&lt;/p&gt;
&lt;p&gt;There is a remedy: combine &lt;code&gt;InvariantToken&lt;/code&gt; with a locally-scoped lifetime, as &lt;a href=&quot;https://codeberg.org/binarycat/typetoken/src/branch/trunk/src/lib.rs&quot;&gt;illustrated&lt;/a&gt; in &lt;a href=&quot;https://codeberg.org/binarycat&quot;&gt;binarycat&lt;/a&gt;’s crate &lt;a href=&quot;https://crates.io/crates/typetoken&quot;&gt;&lt;code&gt;typetoken&lt;/code&gt;&lt;/a&gt;. This only creates a strictly less capable version of &lt;code&gt;generativity&lt;/code&gt;. There is no point in endorsing this approach either.&lt;/p&gt;
&lt;p&gt;If the above code were possible with &lt;code&gt;generativity&lt;/code&gt;, &lt;code&gt;&apos;id&lt;/code&gt; could escape the scope and assign all elements of the vector the same lifetime brand. We would have the exact same unsoundness problem, thus we cannot use a loop to create a dynamic number of &lt;code&gt;PermGroup&amp;lt;&apos;id&amp;gt;&lt;/code&gt;s.&lt;/p&gt;
&lt;h1&gt;How does &lt;code&gt;generativity&lt;/code&gt; work?&lt;/h1&gt;
&lt;p&gt;At this point a good part of my readers are &lt;em&gt;itching&lt;/em&gt; to know what makes the &lt;code&gt;generativity&lt;/code&gt; crate so magical compared to the age-old closure technique. The suspense is probably killing you. Or more likely putting you to sleep. We will introduce the inner workings of &lt;code&gt;generativity&lt;/code&gt; top-down. I will first present my own minimal rewrite of the &lt;code&gt;generativity&lt;/code&gt; crate, called &lt;code&gt;min_generativity&lt;/code&gt;. Then, we will comprehensively walk through how each part of it works.&lt;/p&gt;
&lt;h2&gt;&lt;code&gt;min_generativity&lt;/code&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;marker&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;PhantomData&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; PhantomData&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; ())&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Guard&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; From&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Guard&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; for&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    fn&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;guard&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Guard&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        guard&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; LifetimeBrand&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;PhantomData&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; LifetimeBrand&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        LifetimeBrand&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;PhantomData&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; Drop&lt;/span&gt;&lt;span&gt; for&lt;/span&gt;&lt;span&gt; LifetimeBrand&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    fn&lt;/span&gt;&lt;span&gt; drop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;macro_export&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;macro_rules!&lt;/span&gt;&lt;span&gt; make_guard&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;$name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;ident&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; branded_place&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Id&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;marker&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;PhantomData&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; lifetime_brand &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;LifetimeBrand&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;branded_place&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; $name&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Guard&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;branded_place&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before we get started, let’s get some low hanging fruit out of the way. We can verify that &lt;code&gt;min_generativity&lt;/code&gt; is zero-cost: every single type is some form of &lt;code&gt;PhantomData&lt;/code&gt;, a zero-sized type that is optimized away at compile-time. However, there is a sharp corner: we create a reference to a &lt;code&gt;PhantomData&lt;/code&gt; in &lt;code&gt;make_guard&lt;/code&gt;, and references to zero-sized types are perhaps surprisingly &lt;a href=&quot;https://github.com/rust-lang/rfcs/pull/2040#issuecomment-317275303&quot;&gt;not zero-sized&lt;/a&gt; due to some idiosyncrasies. Thus, we cannot prove &lt;code&gt;min_generativity&lt;/code&gt; is zero-cost as Rust lacks a specification for optimization behavior. I claim that in practice this is the case the overwhelming majority of the time. The reference: is never used anywhere, is associated with an unused variable (&lt;code&gt;lifetime_brand&lt;/code&gt;), and has no &lt;code&gt;Drop&lt;/code&gt; impl. Even at the most basic optimization level, rustc is smart enough to &lt;a href=&quot;https://godbolt.org/z/4h4xccfjT&quot;&gt;no-op everything&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;min_generativity&lt;/code&gt; benevolently assumes that library users will only use &lt;code&gt;make_guard&lt;/code&gt; to construct &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; and &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt;, as both are public types with public field visibility. The actual &lt;code&gt;generativity&lt;/code&gt; crate privatizes &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; (via a newtype) and &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; and marks their constructors unsafe, hidden within &lt;code&gt;make_guard&lt;/code&gt;. Such was omitted to be concise.&lt;/p&gt;
&lt;h2&gt;The first part&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;marker&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;PhantomData&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; PhantomData&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; ())&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you’ve only used &lt;code&gt;PhantomData&lt;/code&gt; when the compiler has told you to, this certainly looks nonsensical. The purpose of &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; as we saw earlier is to carry a &lt;em&gt;unique&lt;/em&gt; lifetime brand among different &lt;code&gt;PermGroup&amp;lt;&apos;id&amp;gt;&lt;/code&gt;s, but aren’t lifetimes already unique? What’s the deal?&lt;/p&gt;
&lt;p&gt;In Rust, &lt;em&gt;variance&lt;/em&gt; determines whether you can substitute one lifetime for another. If you have a longer lifetime, Rust lets you use it where a shorter one is expected. This is also known as &lt;em&gt;subtyping&lt;/em&gt;. Normally this is good—subtyping introduces static analysis that allows for more programs to compile—but in our case this automatic substitution works against our favor. If an &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; can be tied to a lifetime other than its lifetime brand, we lose. So, the unique lifetime &lt;code&gt;&apos;id&lt;/code&gt; must have no subtyping relation with other lifetimes; &lt;code&gt;&apos;id&lt;/code&gt; is what’s called an &lt;em&gt;invariant&lt;/em&gt; lifetime.&lt;/p&gt;
&lt;p&gt;The contemporary usage of the word “invariant” by Rustaceans has two meanings: one as a type-level guarantee (a noun), and one as a no-subtyping relation (an adjective). Invariant generally means something that cannot change or must be fixed to a specific value. Both meanings refer to this same general concept. We’ve been working with the first meaning so far, but for the rest of this article we’ll switch to the second one.&lt;/p&gt;
&lt;p&gt;To make &lt;code&gt;&apos;id&lt;/code&gt; invariant, we take advantage of a fundamental constraint with function pointer types. When you have &lt;code&gt;fn(&amp;amp;&apos;id T) -&amp;gt; &amp;amp;&apos;id T&lt;/code&gt;, the caller provides a reference with lifetime &lt;code&gt;&apos;id&lt;/code&gt; and expects to get back a reference with that same lifetime &lt;code&gt;&apos;id&lt;/code&gt;. If Rust allowed the function pointer type to accept a longer lifetime but return a shorter one, or vice versa, it would break this explicit contract. You might pass in a reference that lives for ten seconds but get one back that lives for five seconds, creating a dangling pointer. Function pointer types with the same lifetime in the input and output positions force that lifetime to be invariant. No substitution allowed.&lt;/p&gt;
&lt;p&gt;Of course, we don’t actually want to store a function pointer at run-time. We only utilize it to make &lt;code&gt;&apos;id&lt;/code&gt; invariant at compile-time. The language provides &lt;code&gt;PhantomData&lt;/code&gt; to enable fine-grained control over variance. In this case it tells the compiler to pretend like it holds a function pointer while not actually taking up any space.&lt;/p&gt;
&lt;aside&gt;&lt;p&gt;Throughout the years lifetime invariance has been achieved in several other ways.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; PhantomData&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // Rust standard library&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; PhantomData&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // GhostCell paper&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; PhantomData&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Cell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; u8&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // Aria Desires&apos; master&apos;s thesis&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; PhantomData&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Cell&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; mut&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // Also from her master&apos;s thesis&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;They work because they follow the core principal that &lt;code&gt;&amp;amp;mut T&lt;/code&gt; is invariant over &lt;code&gt;T&lt;/code&gt; (click &lt;a href=&quot;https://doc.rust-lang.org/nomicon/subtyping.html#variance&quot;&gt;here&lt;/a&gt; to see why). With &lt;code&gt;T = &amp;amp;&apos;id ()&lt;/code&gt;, &lt;code&gt;&apos;id&lt;/code&gt; must become invariant. Unlike the others, &lt;code&gt;PhantomData&amp;lt;fn(T) -&amp;gt; T&amp;gt;&lt;/code&gt; implements all auto traits (&lt;code&gt;Send&lt;/code&gt;, &lt;code&gt;Sync&lt;/code&gt;, etc) for its owner, and it is generally preferred to convey that the only purpose is to indicate invariance. For further reading, the Rustonomicon provides &lt;a href=&quot;https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns&quot;&gt;a table&lt;/a&gt; of common &lt;code&gt;PhantomData&lt;/code&gt; patterns.&lt;/p&gt;&lt;/aside&gt;
&lt;p&gt;When I first learned how to use &lt;code&gt;PhantomData&lt;/code&gt; to indicate variance I couldn’t help but think of it as an obnoxiously leaky abstraction. There is a &lt;a href=&quot;https://github.com/rust-lang/rust/issues/135806&quot;&gt;movement&lt;/a&gt; to make it a bit more ergonomic by introducing custom variance newtypes into the standard library, i.e. &lt;code&gt;PhantomInvariantLifetime&lt;/code&gt;. Sure enough, the status quo of &lt;code&gt;PhantomData&lt;/code&gt; has been considered “&lt;a href=&quot;https://github.com/rust-lang/rfcs/pull/3417#pullrequestreview-1396551771&quot;&gt;something of a failure&lt;/a&gt;.”&lt;/p&gt;
&lt;h2&gt;The second part&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Guard&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; From&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Guard&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; for&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    fn&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;guard&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Guard&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        guard&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The entire implementation of &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; is a newtype around &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt;. The established difference being that &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; doesn’t implement &lt;code&gt;Copy&lt;/code&gt; or &lt;code&gt;Clone&lt;/code&gt;. We provide a &lt;code&gt;From&lt;/code&gt; implementation to consume a &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; into an &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; to create distributable copies of the lifetime brand, as we saw earlier.&lt;/p&gt;
&lt;h2&gt;The third part&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; LifetimeBrand&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;PhantomData&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; LifetimeBrand&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pub&lt;/span&gt;&lt;span&gt; fn&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        LifetimeBrand&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;PhantomData&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; Drop&lt;/span&gt;&lt;span&gt; for&lt;/span&gt;&lt;span&gt; LifetimeBrand&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    fn&lt;/span&gt;&lt;span&gt; drop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;macro_export&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;macro_rules!&lt;/span&gt;&lt;span&gt; make_guard&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;$name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;ident&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; branded_place&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Id&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;marker&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;PhantomData&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; lifetime_brand &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;LifetimeBrand&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;branded_place&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; $name&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Guard&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;branded_place&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It turns out that disabling lifetime subtyping is not enough. While Rust believes it’s unsound to freely resize &lt;code&gt;&apos;id&lt;/code&gt;, there’s nothing that constrains where &lt;code&gt;&apos;id&lt;/code&gt; should come from. Consider the following system:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; unify_lifetimes&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; _&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; id1&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id1&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; PhantomData&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; id2&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Id&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id2&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; PhantomData&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;unify_lifetimes&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;id1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;id2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The constraint solver realizes there is no logical contradiction with the obvious solution of &lt;code&gt;&apos;id2 = &apos;id1&lt;/code&gt;, and it allows this program to compile. We need to uniquely tie &lt;code&gt;&apos;id1&lt;/code&gt; and &lt;code&gt;&apos;id2&lt;/code&gt; to their respective declaration sites to prevent Rust from unifying them.&lt;/p&gt;
&lt;p&gt;After &lt;code&gt;make_guard&lt;/code&gt; creates &lt;code&gt;branded_place&lt;/code&gt; and generates an invariant lifetime &lt;code&gt;&apos;id&lt;/code&gt;, we are now armed with the knowledge required to examine how &lt;code&gt;LifetimeBrand&lt;/code&gt; ensures it is non-unifiable. It takes the approach of establishing distinct lower and upper bounds for &lt;code&gt;&apos;id&lt;/code&gt;, highlighting the need for a macro with protected hygiene to prevent these bounds from potentially being manipulated.&lt;/p&gt;
&lt;p&gt;Notice that &lt;code&gt;LifetimeBrand&lt;/code&gt; carries the phantom type &lt;code&gt;&amp;amp;&apos;id Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; (to avoid actually storing the reference). The existence of &lt;code&gt;LifetimeBrand&lt;/code&gt;’s &lt;code&gt;Drop&lt;/code&gt; impl means this borrowed data could potentially be used at the end of the scope, delegating special analysis called the &lt;a href=&quot;https://doc.rust-lang.org/std/ops/trait.Drop.html#drop-check&quot;&gt;drop check&lt;/a&gt;. The drop check forces the compiler to extend &lt;code&gt;&apos;id&lt;/code&gt; to live at the point where &lt;code&gt;lifetime_brand&lt;/code&gt; is dropped, constituting our lower bound. The actual &lt;code&gt;Drop&lt;/code&gt; impl is purposefully left blank.&lt;/p&gt;
&lt;p&gt;An important guarantee from the compiler is that local variables in a scope are dropped in the opposite order they are defined. Now we must prevent successive &lt;code&gt;make_guard&lt;/code&gt; invocations in the same scope from unifying with the first invocation whose lifetime lives the longest. We are left with a need to &lt;em&gt;upper-bound&lt;/em&gt; &lt;code&gt;&apos;id&lt;/code&gt;, and this is done by tying &lt;code&gt;&apos;id&lt;/code&gt; to the &lt;em&gt;borrow of what created it&lt;/em&gt;. So, any expansion of &lt;code&gt;&apos;id&lt;/code&gt; would mean &lt;code&gt;branded_place&lt;/code&gt;’s borrow of lifetime &lt;code&gt;&apos;id&lt;/code&gt; wouldn’t live long enough when it is dropped.&lt;/p&gt;
&lt;p&gt;If you still find it confusing, I encourage you to work out rustc’s error message &lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=649d51907c2612c310eb627a0c863399&quot;&gt;in this example&lt;/a&gt;. I also encourage you to play around with this code snippet to see what compiles and what doesn’t. I’ve found this exercise illuminating. Another tip to help you understand is to remember the pithy saying that lifetimes are descriptive, not prescriptive.&lt;/p&gt;
&lt;h2&gt;Verifying soundness&lt;/h2&gt;
&lt;p&gt;It is easy to verify that &lt;code&gt;generativity&lt;/code&gt; is sound.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;make_guard!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;make_guard!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;assert_eq!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; id1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;assert_eq!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; id2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// rejected: `branded_place` does not live long enough&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// assert_eq!(id1, id2);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At the time of writing, this test case passes. However, &lt;code&gt;generativity&lt;/code&gt;’s vice is that it relies on internal behavior from the drop check analysis, the precise rules of which have historically been ill-defined and subject to change. In theory, sufficiently advanced analysis would be able to see that dropping &lt;code&gt;lifetime_brand&lt;/code&gt; doesn’t require &lt;code&gt;&apos;id&lt;/code&gt; to live because its &lt;code&gt;Drop&lt;/code&gt; impl is empty, destroying the uniqueness guarantee we have created.&lt;/p&gt;
&lt;aside&gt;&lt;p&gt;The full extent of the current drop check analysis is detailed in a &lt;a href=&quot;https://hackmd.io/h9YBnIbaRSCD7Ej6hUpF_w&quot;&gt;t-types meeting document&lt;/a&gt;. &lt;a href=&quot;https://doc.rust-lang.org/std/ops/trait.Drop.html#drop-check&quot;&gt;TL;DR&lt;/a&gt;.&lt;/p&gt;&lt;/aside&gt;
&lt;p&gt;Pertaining to our concerns, any weakening of the drop check forcing captured lifetimes to live will most likely be opt-in, based on the direction of the &lt;a href=&quot;https://rust-lang.github.io/rfcs/1327-dropck-param-eyepatch.html&quot;&gt;“drop check eyepatch” RFC&lt;/a&gt;. It introduces the unsafe &lt;code&gt;#[may_dangle]&lt;/code&gt; attribute which relaxes this requirement. &lt;code&gt;#[may_dangle]&lt;/code&gt; &lt;em&gt;opts-in&lt;/em&gt; a struct’s &lt;code&gt;Drop&lt;/code&gt; impl to say, “I don’t access a generic parameter, so it can be dropped before I run.” Drop check eyepatch was introduced as a hacky refinement over “&lt;a href=&quot;https://rust-lang.github.io/rfcs/1238-nonparametric-dropck.html#unguarded-escape-hatch&quot;&gt;unguarded escape hatch&lt;/a&gt;,” which permitted high-priority collections like &lt;code&gt;Vec&amp;lt;&amp;amp;T&amp;gt;&lt;/code&gt; to drop despite the &lt;code&gt;&amp;amp;T&lt;/code&gt; borrow being invalidated beforehand.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/famous%20last%20words.B4TkvFT9_Z1FISYY.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/famous%20last%20words.B4TkvFT9_9zlQt.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/famous%20last%20words.B4TkvFT9_1uVsKj.png&quot; alt=&quot;A contributor commenting how this RFC was supposed to be a temporary fix&quot; loading=&quot;lazy&quot; width=&quot;1100&quot; height=&quot;278&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Here are some famous last words. Drop check eyepatch was accepted nine years ago, yet stabilization is &lt;a href=&quot;https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types/topic/Perma-unstable.20status.20of.20.60.23.5Bmay_dangle.5D.60&quot;&gt;still opposed&lt;/a&gt;. There are too many subtle gotchas with respect to the drop check that have been found to be too much of a footgun even for an internal compiler feature. It has resulted in unsoundness &lt;a href=&quot;https://github.com/rust-lang/rust/issues/76367&quot;&gt;multiple&lt;/a&gt; &lt;a href=&quot;https://github.com/rust-lang/rust/issues/99408&quot;&gt;times&lt;/a&gt;. The stable analysis is deliberately conservative for this reason. To quote from the Rustonomicon’s &lt;a href=&quot;https://doc.rust-lang.org/nomicon/dropck.html#an-escape-hatch&quot;&gt;explanation&lt;/a&gt; of &lt;code&gt;#[may_dangle]&lt;/code&gt;, “it is better to avoid adding the attribute.”&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/rust-lang/rfcs/pull/3417&quot;&gt;existing avenue of improvement&lt;/a&gt; clarifies the semantics but still holds that this behavior will be &lt;em&gt;opt-in&lt;/em&gt;. Hence, we can strengthen our confidence that the livelihood requirements for &lt;code&gt;generativity&lt;/code&gt; will remain sound.&lt;/p&gt;
&lt;p&gt;There are two other soundness concerns that are unlikely to be problematic but are still brought up in brief:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;generativity&lt;/code&gt; relies on an unused variable, &lt;code&gt;lifetime_brand&lt;/code&gt;, to impact borrow checking and the drop check. If support for unused variable analysis is ever removed, then &lt;a href=&quot;https://crates.io/crates/scopeguard&quot;&gt;&lt;code&gt;scopeguard&lt;/code&gt;&lt;/a&gt;, a crate with hundreds of millions of downloads, would break, and Rust is very careful not to break existing code. &lt;code&gt;scopeguard&lt;/code&gt; &lt;a href=&quot;https://docs.rs/scopeguard/latest/src/scopeguard/lib.rs.html#287&quot;&gt;also relies&lt;/a&gt; on the &lt;code&gt;Drop&lt;/code&gt; impl of an unused variable. Additionally, with the drop check, borrow checking must also run by virtue of &lt;code&gt;lifetime_brand&lt;/code&gt;’s &lt;code&gt;Drop&lt;/code&gt; impl, which could possibly access the borrow&lt;sup&gt;&lt;a href=&quot;#fn-unreachable&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;In the ultra rare case where &lt;code&gt;generativity&lt;/code&gt; is used in a divergent function, the drop checker will realize that &lt;code&gt;Drop&lt;/code&gt; never runs and skip the drop check entirely. &lt;a href=&quot;https://github.com/CAD97/generativity/pull/16&quot;&gt;Special care&lt;/a&gt; is required in this case to uphold soundness.&lt;/li&gt;
&lt;li&gt;It may still be hard to trust the delicate configuration of upper and lower bounding the generated lifetime. With &lt;a href=&quot;https://blog.rust-lang.org/2022/08/05/nll-by-default/&quot;&gt;non-lexical lifetimes&lt;/a&gt; stabilized in 2022 as the second edition of the borrow checker, the only planned next iteration is &lt;a href=&quot;https://github.com/rust-lang/polonius&quot;&gt;Polonius&lt;/a&gt;, the implementation of which currently &lt;a href=&quot;https://rust.godbolt.org/z/vhMjKGbz3&quot;&gt;passes&lt;/a&gt; the aforementioned test case. I haven’t given it much thought, but proving &lt;code&gt;generativity&lt;/code&gt;’s soundness with Polonius’ formal model of the borrow checker would be a fun project (to me at least).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Language support&lt;/h2&gt;
&lt;p&gt;We can no longer ignore the elephant in the room with the &lt;code&gt;make_guard&lt;/code&gt; macro: it looks ugly. It injects local variables into the current scope, and we saw this was necessary in the statement-position to prevent the lifetime bounding tricks from being manipulated. For a while there was no resolution, until just a few months ago when the experimental &lt;a href=&quot;https://github.com/rust-lang/rust/pull/139080&quot;&gt;&lt;code&gt;super let&lt;/code&gt;&lt;/a&gt; feature was introduced to extend the lifetimes of block-scoped variables. By creating a block scope, expression-position &lt;code&gt;make_guard&lt;/code&gt; is made possible on nightly Rust.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;#!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;feature&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;super_let&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// ...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;macro_export&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;macro_rules!&lt;/span&gt;&lt;span&gt; make_guard&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;$name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;ident&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; branded_place&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Id&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;marker&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;PhantomData&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; lifetime_brand &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;LifetimeBrand&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;branded_place&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; $name&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Guard&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;branded_place&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ()&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        super&lt;/span&gt;&lt;span&gt; let&lt;/span&gt;&lt;span&gt; branded_place&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Id&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;marker&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;PhantomData&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        super&lt;/span&gt;&lt;span&gt; let&lt;/span&gt;&lt;span&gt; lifetime_brand &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;LifetimeBrand&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;branded_place&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        $&lt;/span&gt;&lt;span&gt;crate&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Guard&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;branded_place&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }};&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    make_guard!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;guard&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; guard &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; make_guard!&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Furthermore, there are &lt;a href=&quot;https://blog.m-ou.se/super-let#a-potential-extension&quot;&gt;preliminary ideas&lt;/a&gt; that would allow &lt;code&gt;make_guard&lt;/code&gt; to be a function instead of a macro. The feedback for &lt;code&gt;super let&lt;/code&gt; has so far been positive, so once the semantics are ironed out I think efforts to stabilize this feature will be underway.&lt;/p&gt;
&lt;p&gt;My last contribution to this discussion is some wishful thinking about first-class language support for &lt;code&gt;generativity&lt;/code&gt;. The troubles with unique lifetime branding stem from the fact that Rust offers no way to prevent lifetimes from unifying. So, I propose the &lt;code&gt;#[nonunifiable]&lt;/code&gt; lifetime attribute. It would allow lifetimes to declaratively guarantee non-unifiability without having to resort to &lt;code&gt;generativity&lt;/code&gt;’s lifetime bounding tricks. &lt;code&gt;#[nonunifiable]&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; intended to indicate variance—that’s the job of &lt;code&gt;PhantomData&lt;/code&gt;. For the permutation example, first-class language support from the compiler would look like this. The full implementation is &lt;a href=&quot;https://github.com/ArhanChaudhary/generativity-pattern-rs/blob/main/src/7-nonunifiable_proposal.rs&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;nonunifiable&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; &apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    base_permutation_length&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    base_permutations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; PhantomData&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; ())&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Permutation&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Box&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;usize&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; PhantomData&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; ())&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First-class language support is also the perfect excuse to improve the &lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=47b36de838eaeeebe236e2f3b4aa279b&quot;&gt;confusing&lt;/a&gt; compiler errors:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; first &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;]])&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unwrap&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; second &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; PermGroup&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;vec!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;]])&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unwrap&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; first_perm &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;span&gt;()[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; second_perm &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;second&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;span&gt;()[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;first_perm&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;second_perm&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;E0308&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; mismatched types&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; --&amp;gt;&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;rs&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;9&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;23&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt;     let&lt;/span&gt;&lt;span&gt; first_perm &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;span&gt;()[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  |&lt;/span&gt;&lt;span&gt;         ----------&lt;/span&gt;&lt;span&gt; binding `first_perm` declared here with nonunifiable lifetime `’&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;7&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt;     let&lt;/span&gt;&lt;span&gt; second_perm &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;second&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;base_permutations&lt;/span&gt;&lt;span&gt;()[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  |&lt;/span&gt;&lt;span&gt;         -----------&lt;/span&gt;&lt;span&gt; binding `second_perm` declared here with nonunifiable lifetime `’&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;9&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt;     first_perm&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;second_perm&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  |&lt;/span&gt;&lt;span&gt;                -------&lt;/span&gt;&lt;span&gt; ^^^^^^^^^^^&lt;/span&gt;&lt;span&gt; expected `&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;1&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; found a different `&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;2&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  |&lt;/span&gt;&lt;span&gt;                |&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  |&lt;/span&gt;&lt;span&gt;                arguments to this method are incorrect&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  =&lt;/span&gt;&lt;span&gt; note&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; expected reference `&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;1&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;             found reference `&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;2&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  =&lt;/span&gt;&lt;span&gt; note&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; `&lt;/span&gt;&lt;span&gt;Permtuation&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;1&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;` and `&lt;/span&gt;&lt;span&gt;Permutation&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;2&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;` look like similar types&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; but are distinct because they carry `&lt;/span&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;nonunifiable&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;` lifetimes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Jack (one of this article’s peer reviewers) and I discussed what first-class language support to remove the lifetime parameter and allow &lt;code&gt;Guard&lt;/code&gt; to escape its scope could look like. Unfortunately, we came to the conclusion that such a system would be equivalent to the problem case described in &lt;a href=&quot;#why-the-implementation-caveat&quot;&gt;Why the implementation caveat?&lt;/a&gt;. Creating an arbitrary number of branded types in a loop during run-time would require deep changes to the type system.&lt;/p&gt;
&lt;p&gt;Maybe &lt;code&gt;#[nonunifiable]&lt;/code&gt; will have an unexpected use case that would make it practical, or maybe not. I’m not going to pretend like I’ve figured out all of the semantics. The point is to get my thoughts up in the air.&lt;/p&gt;
&lt;h1&gt;Benchmarks&lt;/h1&gt;
&lt;p&gt;No comparison would be complete without a benchmark. Yes, the point of the generativity pattern is more fundamental than just speed, but I know what people want. I statically generated two random length-fifteen permutations and wrote a Criterion benchmark for all five approaches to permutation composition.&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Benchmark Name&lt;/th&gt;&lt;th&gt;Time (ns)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1-slice&lt;/td&gt;&lt;td&gt;14.805&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2-newtype&lt;/td&gt;&lt;td&gt;4.257&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4-atomic_id&lt;/td&gt;&lt;td&gt;3.940&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5-generativity&lt;/td&gt;&lt;td&gt;3.604&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3-unsafe_trait&lt;/td&gt;&lt;td&gt;3.602&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Empirically, this validates all of my observations. The naive &lt;code&gt;1-slice&lt;/code&gt; is the slowest because it checks every permutation for complete validity during composition. &lt;code&gt;2-newtype&lt;/code&gt; removes most of the validation overhead. Admittedly this is good enough; again, from a practical standpoint, you would only care about the other solutions if you could prove that permutation composition was the bottleneck. &lt;code&gt;4-atomic_id&lt;/code&gt; replaces the validation with a single integer comparison, making it marginally faster, likely because it avoids dereferencing. Finally, &lt;code&gt;5-generativity&lt;/code&gt; and &lt;code&gt;3-unsafe_trait&lt;/code&gt; emerge the fastest because they avoid validation entirely, and I have also verified that the generated machine code is identical. The important difference: &lt;code&gt;3-unsafe_trait&lt;/code&gt; marks permutation composition unsafe while &lt;code&gt;5-generativity&lt;/code&gt; does not.&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Truthfully I don’t have many final thoughts. I just needed a transition to end this article. I suppose my primary conclusion is that this article has gotten &lt;em&gt;far&lt;/em&gt; longer than I had originally planned 😛.&lt;/p&gt;
&lt;p&gt;I don’t think this is a bad thing; its comprehensiveness more than makes up for it. The hidden agenda was to survey design patterns and write about Rust code I thought were interesting, culminating with the generativity pattern, which shows us how to take advantage of the type checker’s power in a non-obvious manner.&lt;/p&gt;
&lt;p&gt;This concludes my first educational write-up on my blog. I came into this topic with surface level understandings of what &lt;code&gt;generativity&lt;/code&gt;, &lt;code&gt;PhantomData&lt;/code&gt;, and the drop check are and how they work. I was not expecting this to take five weeks of meticulous research and writing throughout my summer break in undergrad. I was entirely unprepared for how interesting the full story would be.&lt;/p&gt;
&lt;p&gt;Thank you for reading this far :-). Until next time!&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Yes, I will eventually get to them. You just need to keep reading. &lt;a href=&quot;#fnref-literature&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The center stickers don’t actually move, and thus can be ignored, so the illustrated turn is traditionally simplified to a permutation forty-eight elements long. &lt;a href=&quot;#fnref-cube&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This lifetime is not technically unique. You could unify it with another lifetime in a similar function call: &lt;code&gt;fn unify_lifetimes&amp;lt;&apos;id&amp;gt;(impostor: &amp;amp;&apos;id (), guard: &amp;amp;Guard&amp;lt;&apos;id&amp;gt;) { ... }&lt;/code&gt;. The lifetime is only unique among the provided &lt;code&gt;Id&amp;lt;&apos;id&amp;gt;&lt;/code&gt; and &lt;code&gt;Guard&amp;lt;&apos;id&amp;gt;&lt;/code&gt; types, so as long as your code only trusts lifetimes carried by those types it will be sound. &lt;a href=&quot;#fnref-unique&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Rust doesn’t have &lt;a href=&quot;https://en.wikipedia.org/wiki/Parametric_polymorphism#Higher-rank_polymorphism&quot;&gt;rank-2 polymorphism&lt;/a&gt;, so we need to replicate it using a closure with a &lt;a href=&quot;https://doc.rust-lang.org/nomicon/hrtb.html&quot;&gt;Higher-Rank Trait Bound&lt;/a&gt;. The type signature of the closure passed to &lt;code&gt;BrandedVec::new&lt;/code&gt; is &lt;code&gt;inner: impl for&amp;lt;&apos;id&amp;gt; FnOnce(BrandedVec&amp;lt;&apos;id, T&amp;gt;) -&amp;gt; R&lt;/code&gt;, and this just means every call to &lt;code&gt;inner&lt;/code&gt; must be prepared to handle an argument with any possible lifetime. Within a single function the compiler has perfect information, but calling &lt;code&gt;inner&lt;/code&gt; inside &lt;code&gt;BrandedVec::new&lt;/code&gt; tricks the borrow checker. Since it doesn’t (and will likely never) do interprocedural analysis, it conservatively sees every call to &lt;code&gt;inner&lt;/code&gt; as producing an opaque lifetime that can’t be unified with any other. To avoid any relation with an existing lifetime, a fresh new lifetime is statically generated for every call to &lt;code&gt;BrandedVec::new&lt;/code&gt;, our lifetime brand for &lt;code&gt;BrandedVec&amp;lt;&apos;id, T&amp;gt;&lt;/code&gt;. This is just a brief overview of a well-investigated topic. Repeating for convenience, further reading is encouraged &lt;a href=&quot;https://github.com/Gankra/thesis/blob/master/thesis.pdf&quot;&gt;here&lt;/a&gt; (section 6.3) and &lt;a href=&quot;https://plv.mpi-sws.org/rustbelt/ghostcell/&quot;&gt;here&lt;/a&gt; (section 2.2.1). &lt;a href=&quot;#fnref-brandedvec&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Unreachable code on the other hand is &lt;em&gt;not&lt;/em&gt; borrow checked because it simply &lt;a href=&quot;https://github.com/rust-lang/rust/issues/91377#issuecomment-993875185&quot;&gt;wasn’t a priority&lt;/a&gt;. &lt;a href=&quot;#fnref-unreachable&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Turning Image Corruption into Art</title><link>https://arhan.sh/blog/turning-image-corruption-into-art/</link><guid isPermaLink="true">https://arhan.sh/blog/turning-image-corruption-into-art/</guid><description>My most fun project in a while</description><pubDate>Wed, 14 May 2025 05:15:02 GMT</pubDate><content:encoded>&lt;aside&gt;&lt;p&gt;If some of the videos don’t properly load, try to either reload or open them in a new tab.&lt;/p&gt;&lt;/aside&gt;
&lt;p&gt;You might have heard of the recent “&lt;a href=&quot;https://www.replicateimage.com/&quot;&gt;Replicate Image&lt;/a&gt;” trend. It reminded me of something I used to do when I was younger. When I was bored, or had some sort of exam tomorrow, I would open a JPEG in TextEdit and delete random binary data to see how it would corrupt the image. It turns out that modern image formats are quite malleable, and more often than not, you would still end up with a decodable image! Definitely a little geeky, but hear me out, it was a surprisingly fun way to waste time pointing out the bizarre image artifacts. As you may have guessed, I was spontaneously motivated to turn this into its own “Replicate Image” project.&lt;/p&gt;
&lt;p&gt;The gist: I would write a program that would randomly tweak a few bytes of an image a thousand times over. Then, I would compile every image into a video of the process from start to finish, and do this many times for different image formats. Let’s get to it.&lt;/p&gt;
&lt;p&gt;First, I needed a target image to work with, ideally something with interesting color variety. My close friend &lt;a href=&quot;https://bithole.dev/&quot;&gt;Adrian&lt;/a&gt; snapped this cool picture demonstrating the concept of symmetry on the Rubik’s Cube.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/symmetry.C-tHQFeY_EawRO.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/symmetry.C-tHQFeY_cJxY1.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/symmetry.C-tHQFeY_Z1QiLQM.png&quot; alt=&quot;Two symmetric Rubik&apos;s Cube positions&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;651&quot; /&gt;&lt;/picture&gt;&lt;div&gt;This marvelous composition has no idea what it&apos;s about to go through&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Perfect! Now, a simple Python script to perform our byte-hacking does the trick, using ffmpeg to perform some error checking.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;image_corrupt.py&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; argparse&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; sys&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; subprocess&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; random&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; pathlib &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Path&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;COUNT &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 1000&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;parser &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; argparse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ArgumentParser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;Corrupt an image file.&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;parser&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;add_argument&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;image_file&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    type&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;str&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    help&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;The image file to corrupt&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;args &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; parser&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;parse_args&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;file &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Path&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;image_file&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;base &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; file&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stem&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ext &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; file&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;suffix&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;:]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; not&lt;/span&gt;&lt;span&gt; ext&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;image_corrupt.py: Please provide an image file with an extension.&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;exit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; not&lt;/span&gt;&lt;span&gt; file&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;exists&lt;/span&gt;&lt;span&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;image_corrupt.py: File &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;file&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; does not exist.&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;exit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;base&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;ext&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;rb&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; as&lt;/span&gt;&lt;span&gt; f&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; bytearray&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;read&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;subprocess&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;span&gt;&quot;mkdir&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;-p&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; f&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;ext&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;s&quot;&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;COUNT&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    while&lt;/span&gt;&lt;span&gt; True&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        olddata &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; data&lt;/span&gt;&lt;span&gt;[:]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        # The beginning has important metadata&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        pos &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; random&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;randint&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        # I didn&apos;t have luck *deleting* bytes, as the image&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        # quickly became unrecoverably corrupted. I found success&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        # in just incrementing each randomly selected byte&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        data&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;pos&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;pos&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; +&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; 256&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        with&lt;/span&gt;&lt;span&gt; open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;ext&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;s/&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;:04&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;ext&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;wb&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; as&lt;/span&gt;&lt;span&gt; f&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            subprocess&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                    &quot;ffmpeg&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                    &quot;-v&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                    &quot;error&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                    &quot;-i&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                    f&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;ext&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;s/&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;:04&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;ext&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                    &quot;-f&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                    &quot;null&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                    &quot;-&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                ],&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                stderr&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;subprocess&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;DEVNULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            ).&lt;/span&gt;&lt;span&gt;returncode&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            ==&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            break&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; olddata&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I converted Adrian’s picture to JPEG, PNG, WEBP, and AVIF and ran my script to generate the images. So far, the results looked extremely promising.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/first.ZoWEQPys_Z13LRTO.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/first.ZoWEQPys_ZJvKlE.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/first.ZoWEQPys_1YTJz8.jpg&quot; alt=&quot;An corrupted image of two Rubik&apos;s Cubes&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;427&quot; /&gt;&lt;/picture&gt;&lt;div&gt;You could hang this up on a wall in your house and pass it off as an eccentric art piece. Somebody could come in and have no idea what they were looking at was the result of changing a single byte from an original image&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;To convert the images to a video, I experimented with two different methods. First, a simple Google search demonstrates &lt;a href=&quot;https://stackoverflow.com/a/37478183&quot;&gt;directly using&lt;/a&gt; ffmpeg like so.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;image_corrupt.sh&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# The image extension&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ext&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# The image base name&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;base&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Assume the generated images are in &quot;${ext}s&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;${ext}&lt;/span&gt;&lt;span&gt;s&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# If ffmpeg doesn&apos;t glob-match properly, follow this&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# https://stackoverflow.com/a/64407890/12230735&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ffmpeg&lt;/span&gt;&lt;span&gt; -framerate&lt;/span&gt;&lt;span&gt; 30&lt;/span&gt;&lt;span&gt; -pattern_type&lt;/span&gt;&lt;span&gt; glob&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; &quot;*.&lt;/span&gt;&lt;span&gt;$ext&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; -c:v&lt;/span&gt;&lt;span&gt; libx264&lt;/span&gt;&lt;span&gt; -pix_fmt&lt;/span&gt;&lt;span&gt; yuv420p&lt;/span&gt;&lt;span&gt; -vf&lt;/span&gt;&lt;span&gt; &quot;pad=ceil(iw/2)*2:ceil(ih/2)*2&quot;&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;&quot;.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; Done!&lt;/span&gt;&lt;span&gt; Generated&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;&quot;.mp4&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; the&lt;/span&gt;&lt;span&gt; directory&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;${ext}&lt;/span&gt;&lt;span&gt;s&quot;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, most of my experimentation with this approach was uninteresting. ffmpeg conservatively repairs each image fed as input when converting to video. The files were apparently so viscerally mangled that ffmpeg deems the whole operation unworthy and just gives up.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/green.UBh5oCCN_Z1I92zc.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/green.UBh5oCCN_Z1IHG9S.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/green.UBh5oCCN_Z1ITnbY.jpg&quot; alt=&quot;An image that is entirely green&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;428&quot; /&gt;&lt;/picture&gt;&lt;div&gt;ffmpeg&apos;s entire 30 second video is a green screen with occasional flickering&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Alternatively, you could first use ImageMagick to convert the images to a GIF and then use ffmpeg to convert that GIF to a video. Yes, this was literally the only intermediary step I could get working. The plan isn’t entirely foolproof. Despite the error checking from ffmpeg, some of the generated images were still invalid. I figured out that re-feeding each image one-by-one into ffmpeg repaired them enough to shut up ImageMagick’s complaints without compromising the image data. &lt;a href=&quot;https://stackoverflow.com/a/23309346&quot;&gt;Thanks&lt;/a&gt; &lt;a href=&quot;https://stackoverflow.com/a/50554953&quot;&gt;kind&lt;/a&gt; &lt;a href=&quot;https://superuser.com/a/1261681&quot;&gt;strangers&lt;/a&gt;. I love the Internet!&lt;/p&gt;
&lt;p&gt;&lt;code&gt;image_corrupt.sh&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# The image extension&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ext&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# The image base name&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;base&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Assume the generated images are in &quot;${ext}s&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;${ext}&lt;/span&gt;&lt;span&gt;s&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Use parallel processing if `parallel` is installed&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; command&lt;/span&gt;&lt;span&gt; -v&lt;/span&gt;&lt;span&gt; parallel&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; /dev/null&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    # Functionally identical to the `else` branch&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    parallel&lt;/span&gt;&lt;span&gt; --progress&lt;/span&gt;&lt;span&gt; --eta&lt;/span&gt;&lt;span&gt; ffmpeg&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;span&gt; _{}&lt;/span&gt;&lt;span&gt; :::&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;.&quot;&lt;/span&gt;&lt;span&gt;$ext&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; file &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; [!_&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$ext&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        mv&lt;/span&gt;&lt;span&gt; &quot;_&lt;/span&gt;&lt;span&gt;$file&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$file&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    done&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; file &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; *.&quot;&lt;/span&gt;&lt;span&gt;$ext&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ffmpeg&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$file&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &quot;_&lt;/span&gt;&lt;span&gt;$file&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        mv&lt;/span&gt;&lt;span&gt; &quot;_&lt;/span&gt;&lt;span&gt;$file&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$file&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    done&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;fi&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# I had to resort to ImageMagick&apos;s deprecated `convert` program because&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ImageMagick would sometimes crash more than half way through without&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# generating the GIF. The old version handled this correctly, and I&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# couldn&apos;t figure out how to make the current version do this.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;magick&lt;/span&gt;&lt;span&gt; convert&lt;/span&gt;&lt;span&gt; -limit&lt;/span&gt;&lt;span&gt; memory&lt;/span&gt;&lt;span&gt; 100000&lt;/span&gt;&lt;span&gt; ./&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&quot;&lt;/span&gt;&lt;span&gt;$ext&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;&quot;.gif&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ffmpeg&lt;/span&gt;&lt;span&gt; -itsscale&lt;/span&gt;&lt;span&gt; 0.2&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;&quot;.gif&lt;/span&gt;&lt;span&gt; -movflags&lt;/span&gt;&lt;span&gt; faststart&lt;/span&gt;&lt;span&gt; -pix_fmt&lt;/span&gt;&lt;span&gt; yuv420p&lt;/span&gt;&lt;span&gt; -vf&lt;/span&gt;&lt;span&gt; &quot;scale=trunc(iw/2)*2:trunc(ih/2)*2&quot;&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;&quot;.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; Done!&lt;/span&gt;&lt;span&gt; Generated&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;&quot;.gif&lt;/span&gt;&lt;span&gt; and&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;&quot;.mp4&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; the&lt;/span&gt;&lt;span&gt; directory&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;${ext}&lt;/span&gt;&lt;span&gt;s&quot;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most of what you’re about to see was produced by this cursed workaround. Compared to ffmpeg, ImageMagick was far less pedantic about repairing images, so the results turned out more visually interesting.&lt;/p&gt;
&lt;p&gt;With everything in hand, off to the races! First up, PNG.&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/pngs.DGi5bHfm.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;PNGs were the hardest to corrupt. Each image iteration took a few dozen attempts before finding a byte that could be changed while still passing the error checking mechanism. Intuitively, this makes sense. PNG is a lossless format from 1995, when data corruption was endemic and most small companies had their connectivity through flaky phone lines. So, the PNG designers put a strong emphasis on data integrity, making every image chunk include a &lt;a href=&quot;https://en.wikipedia.org/wiki/Cyclic_redundancy_check&quot;&gt;cycle redundancy check&lt;/a&gt; (CRC), and adding even more checks for more important image chunks. What you’re seeing is probably just ffmpeg trying its best to recover from malformed CRCs.&lt;/p&gt;
&lt;p&gt;Additionally, I got this one work. Some more techno spaghettio.&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/pngs2.C-f3hOmf.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;Next up, JPEG.&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/jpgs.Bjx17sDy.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;I was really excited to be able to make out &lt;a href=&quot;https://en.wikipedia.org/wiki/JPEG#Block_slitting&quot;&gt;block splitting&lt;/a&gt; and the &lt;a href=&quot;https://en.wikipedia.org/wiki/JPEG#Discrete_cosine_transform&quot;&gt;discrete cosine transform&lt;/a&gt;. This is the stuff I live for! Unlike every other format, I was only able to make this interesting by skipping the repair phase with ffmpeg and directly feeding each image to ImageMagick. Even though ImageMagick was operating on raw, corrupted JPEGs, it was still able to recognize three-fourths of the generated images before crashing. A quick look at JPEG’s &lt;a href=&quot;https://en.wikipedia.org/wiki/JPEG#Syntax_and_structure&quot;&gt;syntax and structure&lt;/a&gt; corroborates that its only form of data integrity is sparse “restart markers” that don’t seem to have much effect. Honestly, JPEG data corruption is itself a whole other topic worth investigating. See the JPEG editor on &lt;a href=&quot;https://parametric.press/issue-01/unraveling-the-jpeg/&quot;&gt;this excellent blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Up again, WEBP.&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/webps.DNm60S17.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;It’s not quite static noise, and it’s not quite order either. It’s like you’re trying to remember something, but you can only see a blurry mess of pixels. There is more detail than meets the eye; you could pause at any timestamp and land on a novel expression of color. On the technical side, WEBP worked without issue and was well-behaved. I don’t have much else to say, so let’s finally move on to AVIF.&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/avifs.Cl4aapit.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;This took me many tries to get right. It’s my favorite one, and it’s incredibly mesmerizing!&lt;/p&gt;
&lt;p&gt;I asked my friend &lt;a href=&quot;https://www.matthewstanciu.com/&quot;&gt;Matthew&lt;/a&gt; to give me another image to corrupt with the AVIF format. This was the highest quality video I could produce before ImageMagick ran out of memory. The result also ended up being awesome!&lt;/p&gt;
&lt;div&gt;&lt;video controls width=&quot;600&quot;&gt;&lt;source src=&quot;/_astro/cards.BRNG9kZy.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;I’ve written some goofy blog posts before, but this one takes the cake for how much fun I working on it. I have made the source code &lt;a href=&quot;https://github.com/ArhanChaudhary/image-corrupt&quot;&gt;public&lt;/a&gt; so you can try corrupting your own images. Do let me know how it goes. Until next time!&lt;/p&gt;</content:encoded></item><item><title>An Image Compression Tip with Astro</title><link>https://arhan.sh/blog/an-image-compression-tip-with-astro/</link><guid isPermaLink="true">https://arhan.sh/blog/an-image-compression-tip-with-astro/</guid><description>AVIF made dead-simple</description><pubDate>Sat, 10 May 2025 03:57:18 GMT</pubDate><content:encoded>&lt;p&gt;Thanks to my friend &lt;a href=&quot;https://ericswpark.com/&quot;&gt;Eric&lt;/a&gt; for telling me about this! If you use &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;, the web framework this site is built on, there is a sweet drop-in replacement for the &lt;code&gt;&amp;lt;Image&amp;gt;&lt;/code&gt; component that offers better compression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Image&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&amp;lt;Picture &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    formats&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;&quot;avif&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;webp&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    src&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;penguinSrc&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    alt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;A very cool penguin!&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Better, you can create a light component wrapper around this technique called &lt;code&gt;&amp;lt;ContentImage&amp;gt;&lt;/code&gt; to encapsulate the &lt;code&gt;formats&lt;/code&gt; parameter.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://docs.astro.build/en/guides/images/#create-responsive-images-with-the-picture--component&quot;&gt;&lt;code&gt;&amp;lt;Picture&amp;gt;&lt;/code&gt;&lt;/a&gt; component instructs the browser to use the modern AVIF format for efficient image compression. If your browser doesn’t support AVIF (which is &lt;a href=&quot;https://caniuse.com/?search=avif&quot;&gt;unlikely&lt;/a&gt;), it falls back to the WEBP format, what &lt;code&gt;&amp;lt;Image&amp;gt;&lt;/code&gt; already compiles to. However, this of course means Astro generates two versions of every image, so keep that in mind if you have many images on your site.&lt;/p&gt;
&lt;p&gt;A side note: AVIF is amazing! Someone managed to compress &lt;a href=&quot;https://www.reddit.com/r/AV1/comments/msb74a/shrek_but_its_8mb_again/&quot;&gt;the entirety of Shrek&lt;/a&gt; in 8MB. How it works is borderline magic, and its future looks bright. Once it becomes a little more mature in the web ecosystem, I have no doubt &lt;code&gt;&amp;lt;Image&amp;gt;&lt;/code&gt; will eventually compile to AVIF and automate this process.&lt;/p&gt;
&lt;p&gt;Until next time!&lt;/p&gt;</content:encoded></item><item><title>Two Years of University</title><link>https://arhan.sh/blog/two-years-of-university/</link><guid isPermaLink="true">https://arhan.sh/blog/two-years-of-university/</guid><pubDate>Wed, 30 Apr 2025 02:39:17 GMT</pubDate><content:encoded>&lt;p&gt;Throughout my teenage years, college felt like a mystery. I had a general idea of what life was like &lt;em&gt;after&lt;/em&gt; college, through TV shows, my parents, and the Internet. And, at that time, I was exactly living through life &lt;em&gt;before&lt;/em&gt; college. College &lt;em&gt;itself&lt;/em&gt;, on the other hand, was a black box, where people go into, are never heard from again until after four years, and magically transform into adults. I had no idea what to expect from going into college, and would often be met with the dull “it’s the best time of your life” and “it’s a place to discover yourself.” Maybe I was just ignorant, but this was overwhelmingly how I felt. I cried on my first night in my dorm room.&lt;/p&gt;
&lt;p&gt;Now, I completed two years as a computer science major and electrical computer engineering minor at Purdue University! Okay, I still have two more weeks before the year ends, but whatever. Sue me. If you are expecting me to say something meaningful about the college experience, I’m not going to pretend like the conventional advice about college is untrue. It would feel disingenuous to try regurgitating it, so all I have to say in that regard is I’m loving every moment of university so far. This is my blog after all, so let’s go over what’s happened since my last &lt;a href=&quot;../hello-world/&quot;&gt;update&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;I ditched the skateboard&lt;/h1&gt;
&lt;p&gt;From the beginning to end of 2024, I learned how to skateboard, became moderately good at it, and quit without looking back. On my way to class, my back foot hit the back wheel while pushing off my board sending me tumbling into the asphalt. It was a very rough fall, and I eventually turned out fine, but I was spooked enough when it happened &lt;em&gt;again&lt;/em&gt; that I decided skateboarding wasn’t worth jeopardizing my well-being. Oh well, I’m glad I tried it out.&lt;/p&gt;
&lt;h1&gt;I uninstalled social media&lt;/h1&gt;
&lt;p&gt;I used to be morbidly addicted to social media. Quintessential Gen Z stuff. I’m not entirely clean, I still &lt;a href=&quot;/media&quot;&gt;watch&lt;/a&gt; a lot of YouTube, my last vice, but I’ve phased out everything else from my life. Ultimately, none of it ever mattered to me. I am proud to say that I have recently been spending my time focusing on things I care about.&lt;/p&gt;
&lt;h1&gt;I took interesting classes&lt;/h1&gt;
&lt;p&gt;I declared a minor in electrical computer engineering! This semester I finished my first electrical engineering fundamentals class, absolutely loving it, albeit scary at first. Truthfully, I wasn’t confident about taking up the minor; it’s not something you usually hear CS majors doing. Compared to other minors, I had to take triple the number of classes, forcing me to stay at Purdue for all four years. It’s not particularly helpful on a resume either. Don’t get me wrong, while an ECE minor is nice to show off, there are better time investments into my career for my major. In my interpretation, these arguments were missing of the point of a minor&lt;sup&gt;&lt;a href=&quot;#fn-masters&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;: to do something because you enjoy it. I would never be able to live with myself if I passed up the opportunity to take advantage of &lt;a href=&quot;https://engineering.purdue.edu/Engr&quot;&gt;one of the best engineering programs in the world&lt;/a&gt; and Purdue’s maker space culture.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/audio-amplifier.BUQORk6K_Z1lS00h.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/audio-amplifier.BUQORk6K_ZrMNxa.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/audio-amplifier.BUQORk6K_2qmrML.jpg&quot; alt=&quot;A picture of an audio equalizer circuit&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;667&quot; /&gt;&lt;/picture&gt;&lt;div&gt;I made an audio equalizer circuit!&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;As a student, I had always hated English class. The word “hate” isn’t used lightly; I fell into a defeatist, closed-minded mindset, and actively refused to read because it was never something I thought I could get good at. Fast forward to my previous semester at university, I had the option to fulfill my writing requirement with an easy class I wouldn’t really care about. I gave myself a chance, and reluctantly signed up for a discussion-based reading and writing class. I’m so happy I did. It was my favorite class this semester! As much as I love computers, this class was a breath of fresh air. I especially enjoyed reading Dante’s &lt;em&gt;The Inferno&lt;/em&gt;. I will definitely be checking out the sequels &lt;em&gt;Purgatorio&lt;/em&gt; and &lt;em&gt;Paradiso&lt;/em&gt;. My goal by the end of this year is to start reading for pleasure more often.&lt;/p&gt;
&lt;h1&gt;I joined my favorite club&lt;/h1&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/purdue-hackers-passport.C4knEc0I_5JNVn.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/purdue-hackers-passport.C4knEc0I_EYwps.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/purdue-hackers-passport.C4knEc0I_1l2PLY.jpg&quot; alt=&quot;A picture of a hand-made passport&quot; loading=&quot;lazy&quot; width=&quot;1250&quot; height=&quot;797&quot; /&gt;&lt;/picture&gt;&lt;div&gt;My hand-crafted Purdue Hackers passport&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;I joined the Purdue Hackers club! I frequently regular Hack Night, the club’s flagship weekly hacker festival, where people collaborate to create and engineer interesting technical projects. &lt;a href=&quot;https://ersei.net/&quot;&gt;I&lt;/a&gt; &lt;a href=&quot;https://blog.vashishtha.in/&quot;&gt;have&lt;/a&gt; &lt;a href=&quot;https://kasad.com/&quot;&gt;made&lt;/a&gt; &lt;a href=&quot;https://ericswpark.com/&quot;&gt;crazy&lt;/a&gt; &lt;a href=&quot;https://inx.moe/&quot;&gt;talented&lt;/a&gt; &lt;a href=&quot;https://www.rayhanadev.com/&quot;&gt;friends&lt;/a&gt; at Hack Night who continue to inspire and motivate me. I have many more positive thoughts, but I think &lt;a href=&quot;https://blog.purduehackers.com/posts/galactic-empire&quot;&gt;Galactic Empire&lt;/a&gt; does full justice to the unique culture Purdue Hackers has spent years creating.&lt;/p&gt;
&lt;div&gt;&lt;video controls width=&quot;400&quot;&gt;&lt;source src=&quot;/_astro/robot-arm.BRCWHmVp.mp4&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;div&gt;&lt;a href=&quot;https://fizzyapple12.com/&quot;&gt;Hazel&lt;/a&gt; rescued an abandoned industrial robot arm from the flooded swamps of Florida, brought it to Hack Night, and actually managed to get it working&lt;/div&gt;&lt;/div&gt;
&lt;h1&gt;And onwards&lt;/h1&gt;
&lt;p&gt;One thing I admire about one of my best friends &lt;a href=&quot;https://hrovnyak.gitlab.io/&quot;&gt;Henry&lt;/a&gt; is his motivation to write in a personal journal. I’ve never felt the need to express myself privately, it’s not something I feel motivated to do. But writing in any form is cathartic, and I’ve found that expressing myself to others suddenly makes the process fun and exciting. I think that blogging is just a great way to share all the cool stuff I’ve been up to.&lt;/p&gt;
&lt;p&gt;This post is quite different compared to the other technical write-ups on my blog. If it isn’t your cup of tea, throughout my last few months of inactivity, I did end up thinking of some new blogpost ideas, some of which I am currently working on.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Rubik’s Cube is a Computer&lt;/strong&gt;: My most ambitious project to date, where all my time has recently been put towards, and a collaboration with friends Henry and &lt;a href=&quot;https://thegraycuber.github.io/&quot;&gt;Asher&lt;/a&gt;. It will take many months or even a year for this to come out.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;From NAND to AI&lt;/strong&gt;: A detailed technical narrative of &lt;a href=&quot;https://github.com/ArhanChaudhary/NAND&quot;&gt;NAND&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GitHub’s Most Influential Controversies&lt;/strong&gt;: I want to curate the most influential issues from &lt;a href=&quot;https://github.com/neodrama/github-drama?tab=readme-ov-file&quot;&gt;here&lt;/a&gt; and analyze the role of drama in shaping policy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Implanting a VSCode Rickroll&lt;/strong&gt;: I exploited an oversight in a popular VSCode extension to implant a silly rickroll into VSCode. It would have otherwise been a small write-up, however in doing so I may have potentially uncovered a subtle vulnerability with private GitHub repositories. Unfortunately there hasn’t been much recent development, but if something happens I will definitely get around to publishing it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A Timeline of Rust&lt;/strong&gt;: If there is one thing more enjoyable than writing Rust, it’s reading Rust! I want to briefly look at its older design using real examples. I intend to remaster &lt;a href=&quot;https://www.ncameron.org/blog/rust-through-the-ages/&quot;&gt;this&lt;/a&gt; excellent post.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Four Years, 30k Lines of Code, and Nothing to Show For It&lt;/strong&gt;: If you happen to know me then you know what this is going to be about, and I would appreciate if you please don’t personally bring this up to me :(&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So… stay tuned. There’s always more to come. Until next time!&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;I have considered saving ECE for my masters. I decided against it because I want to reserve it for something else CS related. &lt;a href=&quot;#fnref-masters&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Wasm-pack Optimization Flags you Never Knew About!</title><link>https://arhan.sh/blog/wasm-pack-optimization-flags-you-never-knew-about/</link><guid isPermaLink="true">https://arhan.sh/blog/wasm-pack-optimization-flags-you-never-knew-about/</guid><description>TL;DR: You can forward optimization flags to binaryen</description><pubDate>Sun, 25 Aug 2024 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We’ve all known and loved Rust’s wasm-pack for generating WebAssembly packages. Did you know that it provides dozens of obscure optimization flags hiding in plain sight?&lt;/p&gt;
&lt;p&gt;Let’s first take a look at the available optimization flags from wasm-pack’s documentation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;package.metadata.wasm-pack.profile.dev&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Should `wasm-opt` be used to further optimize the wasm binary generated after&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# the Rust compiler has finished? Using `wasm-opt` can often further decrease&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# binary size or do clever tricks that haven&apos;t made their way into LLVM yet.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Configuration is set to `false` by default for the dev profile, but it can&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# be set to an array of strings which are explicit arguments to pass to&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# `wasm-opt`. For example `[&apos;-Os&apos;]` would optimize for size while `[&apos;-O4&apos;]`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# would execute very expensive optimizations passes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;wasm-opt &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&apos;-O&apos;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For most people, &lt;code&gt;-O4&lt;/code&gt; is enough, case closed, but it is easy to overlook an important detail. wasm-opt isn’t a tool from Rust, but rather a Rust-facing wrapper around &lt;a href=&quot;https://github.com/WebAssembly/binaryen&quot;&gt;binaryen&lt;/a&gt;’s wasm-opt, the C++ toolchain infrastructure that actually does the meat of the work. You never could have known this if you were new to rustwasm, as it’s omitted from the documentation.&lt;/p&gt;
&lt;p&gt;You have to dig through source to find the full list of binaryen’s wasm-opt optimization flags. Bizarrely, the only mention of the list in fine print is within this test file.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/WebAssembly/binaryen/blob/version_117/test/lit/help/wasm-opt.test&quot;&gt;&lt;code&gt;test/lit/help/wasm-opt.test&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT: Optimization options:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT: ---------------------&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:    -O                                           execute default optimization&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 passes (equivalent to -Os)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:    -O0                                          execute no optimization passes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:    -O1                                          execute -O1 optimization passes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 (quick&amp;amp;useful opts, useful for&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 iteration builds)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:    -O2                                          execute -O2 optimization passes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 (most opts, generally gets most&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 perf)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:    -O3                                          execute -O3 optimization passes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 (spends potentially a lot of&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 time optimizing)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:    -O4                                          execute -O4 optimization passes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 (also flatten the IR, which can&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 take a lot more time and memory,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 but is useful on more nested /&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 complex / less-optimized input)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:    -Os                                          execute default optimization&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 passes, focusing on code size&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:    -Oz                                          execute default optimization&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 passes, super-focusing on code&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 size&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --optimize-level,-ol                          How much to focus on optimizing&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 code&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --shrink-level,-s                             How much to focus on shrinking&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 code size&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --debuginfo,-g                                Emit names section in wasm&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 binary (or full debuginfo in&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 wast)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --always-inline-max-function-size,-aimfs      Max size of functions that are&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 always inlined (default 2, which&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 is safe for use with -Os builds)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --flexible-inline-max-function-size,-fimfs    Max size of functions that are&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 inlined when lightweight (no&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 loops or function calls) when&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 optimizing aggressively for&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 speed (-O3). Default: 20&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --one-caller-inline-max-function-size,-ocimfs Max size of functions that are&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 inlined when there is only one&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 caller (default -1, which means&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 all such functions are inlined)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --inline-functions-with-loops,-ifwl           Allow inlining functions with&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 loops&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --partial-inlining-ifs,-pii                   Number of ifs allowed in partial&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 inlining (zero means partial&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 inlining is disabled) (default:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 0)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --ignore-implicit-traps,-iit                  Optimize under the helpful&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 assumption that no surprising&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 traps occur (from load, div/mod,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 etc.)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --traps-never-happen,-tnh                     Optimize under the helpful&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 assumption that no trap is&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 reached at runtime (from load,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 div/mod, etc.)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --low-memory-unused,-lmu                      Optimize under the helpful&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 assumption that the low 1K of&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 memory is not used by the&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 application&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --fast-math,-ffm                              Optimize floats without handling&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 corner cases of NaNs and&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 rounding&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --zero-filled-memory,-uim                     Assume that an imported memory&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 will be zero-initialized&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Shrouded within the codebase, these few extra flags are actually useful in extreme optimization cases. Namely, in my case, &lt;code&gt;--flexible-inline-max-function-size&lt;/code&gt; boasts a respectful &lt;strong&gt;40%&lt;/strong&gt; speed improvement while increasing my WebAssembly file size from 67KB to 83KB.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Cargo.toml&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;package.metadata.wasm-pack.profile.release&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;wasm-opt &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;-O4&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;--flexible-inline-max-function-size&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;4294967295&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are just the “Optimization options”. There exists an even &lt;em&gt;larger&lt;/em&gt; list of around 150 “Optimization passes” within the same test file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT: Optimization passes:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT: --------------------&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --abstract-type-refining                      refine and merge abstract&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 (never-created) types&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --alignment-lowering                          lower unaligned loads and stores&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 to smaller aligned ones&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --asyncify                                    async/await style transform,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 allowing pausing and resuming&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --avoid-reinterprets                          Tries to avoid reinterpret&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 operations via more loads&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --cfp                                         propagate constant struct field&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 values&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --coalesce-locals                             reduce # of locals by coalescing&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --coalesce-locals-learning                    reduce # of locals by coalescing&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 and learning&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --code-folding                                fold code, merging duplicates&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --code-pushing                                push code forward, potentially&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 making it not always execute&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --const-hoisting                              hoist repeated constants to a&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 local&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:   --dae                                         removes arguments to calls in an&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;;; CHECK-NEXT:                                                 lto-like manner&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I spent almost an entire day testing out the effectiveness of each flag to little avail. A lot of these flags aren’t even optimizations, and the ones that are were all seemingly ineffectual. If you’re looking to hyper-optimize your binaryen WebAssembly you’re better off sticking with the “Optimization options” flags. You may also find useful the &lt;a href=&quot;https://github.com/WebAssembly/binaryen/wiki/Optimizer-Cookbook&quot;&gt;optimizer cookbook&lt;/a&gt; and the &lt;a href=&quot;https://github.com/WebAssembly/binaryen/wiki/GC-Optimization-Guidebook&quot;&gt;GC optimization guidebook&lt;/a&gt; from binaryen’s wiki.&lt;/p&gt;
&lt;p&gt;Coming to think about it, this post doesn’t have to be about wasm-pack at all, as the topic more closely concerns binaryen. I thought it was important to frame this post from a Rust point of view because of how surprisingly obscure this information is to wasm-pack users new to the WebAssembly pipeline. I have opened a &lt;a href=&quot;https://github.com/rustwasm/wasm-pack/pull/1423&quot;&gt;pull request&lt;/a&gt; that explicitly references the full list of available wasm-opt flags in wasm-pack’s documentation to make them easier to find.&lt;/p&gt;
&lt;aside&gt;&lt;p&gt;UPDATE: My PR was recently merged. How cool is that!&lt;/p&gt;&lt;/aside&gt;
&lt;p&gt;Until next time!&lt;/p&gt;</content:encoded></item><item><title>How Many Iconic Computing Numbers can you Recognize?</title><link>https://arhan.sh/blog/how-many-iconic-computing-numbers-can-you-recognize/</link><guid isPermaLink="true">https://arhan.sh/blog/how-many-iconic-computing-numbers-can-you-recognize/</guid><description>A puzzle for programming hobbyists and computer nerds</description><pubDate>Fri, 23 Aug 2024 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;TL;DR: Here is the challenge &lt;a href=&quot;https://numbers.arhan.sh/&quot;&gt;https://numbers.arhan.sh/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Two years ago, I applied to college. I would be lying if I said it wasn’t a harrowing process, but like all other phases in life it passed.&lt;/p&gt;
&lt;p&gt;During that time, one of my friends sent me a &lt;a href=&quot;https://www.reddit.com/r/ApplyingToCollege/comments/103aycn/only_a2c/&quot;&gt;meme on Reddit&lt;/a&gt; about a list acronyms that only college applicants could understand. The author coined it as “the only place on the internet where you can say something like this and it makes total sense”. And you know what, they’re not wrong. The post reads like absolute nonsense to the ordinary person. Through a sense of shared adversity, students applying to college have created a digital subculture, and I found this concept fascinating to think about.&lt;/p&gt;
&lt;p&gt;Reddit posts don’t usually deserve this much attention, but it inspired me to create something similar for computer nerds with my own creative twist. As programmers, we’re often told to avoid so called “magic numbers” for good reason, as they can make programs harder to understand. Let’s flip this idea on its head.&lt;/p&gt;
&lt;p&gt;My close friend &lt;a href=&quot;https://bithole.dev&quot;&gt;Adrian&lt;/a&gt; and I spent three weeks curating a secret message, a string of 31 iconic magic numbers in various fields of computing that only true programming hobbyists can decipher. If you think you’re into computers, I challenge you to fully decipher my secret message in under 40 guesses: &lt;a href=&quot;https://numbers.arhan.sh/&quot;&gt;https://numbers.arhan.sh/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;On an unrelated note, this was my first time properly using Tailwindcss! I’m enamored by its simplicity, and love everything about it so far. Check out this project’s associated &lt;a href=&quot;https://github.com/ArhanChaudhary/iconic-computing-numbers&quot;&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Comments about how many guesses and how long it took you to finish the challenge are welcomed and appreciated, have fun! Until next time!&lt;/p&gt;</content:encoded></item><item><title>Implementing === in JavaScript from Scratch</title><link>https://arhan.sh/blog/implementing-strict-equality-in-javascript-from-scratch/</link><guid isPermaLink="true">https://arhan.sh/blog/implementing-strict-equality-in-javascript-from-scratch/</guid><description>Object reference comparison on Chromium&lt;=103</description><pubDate>Sat, 17 Aug 2024 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Yes, I know exactly what you’re thinking.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Reinventing the wheel? That’s the most moronic idea I’ve ever heard since that guy who wanted to invade Russia in the winter.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And you’re not wrong. For all practical purposes, this blog is pointless. What you’re about to read is so obscenely nutty that it only works on a legacy version of Chromium as an extension running millions of times slower.&lt;/p&gt;
&lt;p&gt;The strict equality operator in JavaScript (===) compares two values for object equality. As you probably already know, this operator tests reference equality for non-primitive JavaScript values. In effect, because &lt;code&gt;{ foo: 42 } === { foo: 42 }&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;, reimplementing spec-compliant functionality becomes much more interesting. I’m not talking about the obvious ways. Various other built-ins make object reference comparison trivial.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; obj1 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; foo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 42&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; obj2 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; obj1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;is&lt;/span&gt;&lt;span&gt;(obj1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; obj2) &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;same&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[obj1]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;includes&lt;/span&gt;&lt;span&gt;(obj2) &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;same&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;switch&lt;/span&gt;&lt;span&gt; (obj1) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  case&lt;/span&gt;&lt;span&gt; obj2&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;same&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; Set&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(obj1)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;has&lt;/span&gt;&lt;span&gt;(obj2) &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;same&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We will implement this basic operation on a far lower level. But what does that mean, and how else could JavaScript differentiate two objects that hold the same data? &lt;a href=&quot;https://stackoverflow.com/questions/1997661/unique-object-identifier-in-javascript&quot;&gt;Surface level research&lt;/a&gt; yields nothing, so we’re on our own. Let’s take a deep dive.&lt;/p&gt;
&lt;p&gt;A few weeks ago I was looking into the Chromium DevTools heap profiler for a separate &lt;a href=&quot;../true-private-state-in-javascript-a-chromium-rabbit-hole/&quot;&gt;blog&lt;/a&gt; post of mine. I keenly noticed that the heap profiler distinguishes JavaScript objects by memory location. I might be able to utilize that to my advantage.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; obj1 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; foo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 42&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; obj2 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; foo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 42&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/heap-profiler.Bi30p_gp_1tXM4H.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/heap-profiler.Bi30p_gp_Z2bvJPK.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/heap-profiler.Bi30p_gp_27O01B.png&quot; alt=&quot;The heap profiler demonstrating that two objects have different memory locations&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;287&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;This isn’t useful if there isn’t a way to access these memory locations programmatically. Fortunately, Chrome uses the Chrome DevTools Protocol (CDP), a standardized JavaScript API that allows for direct inspection into the JavaScript runtime on Blink-based browsers.&lt;/p&gt;
&lt;p&gt;The original question still stands; how does JavaScript access the CDP? The documentation endorses two means of access. First, open “&lt;a href=&quot;https://stackoverflow.com/questions/12291138/how-do-you-inspect-the-web-inspector-in-chrome/12291163#12291163&quot;&gt;devtools-on-devtools&lt;/a&gt;” and interface with the CDP like so.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; Main &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;./devtools-frontend/front_end/entrypoints/main/main.js&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; Main&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MainImpl&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sendOverProtocol&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;Emulation.setDeviceMetricsOverride&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  mobile&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  width&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 412&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  height&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 732&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  deviceScaleFactor&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 2.625&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; Main&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MainImpl&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sendOverProtocol&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Page.captureScreenshot&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This requires explicit access to DevTools and some setup, meaning it wouldn’t work plainly on a website. The alternative option is the &lt;code&gt;chrome.debugger&lt;/code&gt; API within a Chrome extension. Although this would be a bit harder to use, it was actually programmatic and eventually the option I chose to work with.&lt;/p&gt;
&lt;p&gt;I hacked up a Chrome extension but was surprised when my testing errored with the following message.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;code&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;-32601&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&quot;&apos;HeapProfiler.enable&apos; wasn&apos;t found&quot;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What’s going on here? As it turns out, internal documentation reveals that specific protocol domains including the heap profiler are restricted for security reasons.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;However, since the protocol is also exposed to chrome extensions through chrome.debugger API, the backend implements additional access control in some of the methods to prevent extensio[n]s form accessing file system or otherwise escaping the sandbox. These restrictions are not extended to other types of clients.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://chromium.googlesource.com/v8/v8/+/c42e620355453fc0510b06e089ca7d92598bd54f%5E%21/&quot;&gt;Here&lt;/a&gt; is the v8 commit that adds these restrictions, dating back to May 2022 and Chromium version v104. The solution to our dilemma, you guessed it, is time travel.&lt;/p&gt;
&lt;p&gt;Google doesn’t distribute legacy versions of Chrome. We’ll have to be a bit more hands-on. Archives of older versions of Chrome exist online. However, I’m wary of downloading unknown files from the Internet. Instead, I installed the official v103 Chromium build from source following their &lt;a href=&quot;https://www.chromium.org/getting-involved/download-chromium/#downloading-old-builds-of-chrome-chromium&quot;&gt;guide&lt;/a&gt;. You may have to run &lt;code&gt;/usr/bin/xattr -cr /Applications/Chromium.app&lt;/code&gt; on an ARM-based Macs to fix broken metadata preventing Chromium from launching.&lt;/p&gt;
&lt;p&gt;My extension didn’t initially work because global content scripts were only supported in Chromium v111 and later, so I had to resort to an &lt;a href=&quot;https://stackoverflow.com/questions/9602022/chrome-extension-retrieving-global-variable-from-webpage/9636008#9636008&quot;&gt;older&lt;/a&gt; content script hack to get it to work.&lt;/p&gt;
&lt;p&gt;That was a lot; let’s take a small step back. To reiterate, the goal is to implement a spec-compliant strict equality operation in JavaScript from scratch. We’ve found a version of Chromium that enables programmatic access to the DevTools heap profiler. Let’s build the bridge between the CDP and JavaScript object memory addresses.&lt;/p&gt;
&lt;p&gt;A good place to start is the &lt;code&gt;HeapProfiler.takeHeapSnapshot&lt;/code&gt; method. This will profile the &lt;em&gt;entire&lt;/em&gt; page, and is obviously cumbersome, but whatever. Next, the &lt;code&gt;Runtime.evaluate&lt;/code&gt; method creates a unique object identifier from the evaluation result of a stringified JavaScript expression. The caveat is that this only evaluates the global scope, coercing some really bizarre JavaScript.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;strictEquality.js&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span&gt; strictEquality&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;obj1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; obj2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  window&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;__obj1 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; obj1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  window&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;__obj2 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; obj2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  // Communicate with the extension content script&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  // and perform the strict equality (will be explained later)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;dispatchEvent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; CustomEvent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;strictEquality&quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  let&lt;/span&gt;&lt;span&gt; e &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Promise&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resolve&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addEventListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;strictEqualityResponse&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; resolve&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; once&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  )&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  delete&lt;/span&gt;&lt;span&gt; window&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;__obj1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  delete&lt;/span&gt;&lt;span&gt; window&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;__obj2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;detail&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    throw&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Error&lt;/span&gt;&lt;span&gt;(e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;detail)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;detail&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ugh. It’s async not because of I/O, but because of the event loop. It’s also non-reentrant, in other words it must always be &lt;code&gt;await&lt;/code&gt;-ed. These types of unavoidably stateful functions are typically only present within C, not JavaScript!&lt;/p&gt;
&lt;p&gt;Fine. Finally, we can pass that identifier to &lt;code&gt;HeapProfiler.getHeapObjectId&lt;/code&gt; and earn our heap profiler memory address value. The full pipeline:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;background.js&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; chrome&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debugger&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;attach&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; tabId &lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;span&gt; &quot;1.3&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; chrome&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debugger&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sendCommand&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; tabId &lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;span&gt; &quot;HeapProfiler.takeHeapSnapshot&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; objDetails &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; Promise&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  chrome&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debugger&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sendCommand&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; tabId &lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;span&gt; &quot;Runtime.evaluate&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    expression&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;window.__obj1&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  chrome&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debugger&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sendCommand&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; tabId &lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;span&gt; &quot;Runtime.evaluate&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    expression&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;window.__obj2&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;])&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; objHeapDetails &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; Promise&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  chrome&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debugger&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sendCommand&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; tabId &lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;span&gt; &quot;HeapProfiler.getHeapObjectId&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    objectId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; objDetails[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;objectId&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  chrome&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debugger&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sendCommand&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; tabId &lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;span&gt; &quot;HeapProfiler.getHeapObjectId&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    objectId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; objDetails[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;objectId&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;])&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; chrome&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debugger&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;detach&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; tabId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; sender&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tab&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;filePath &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sendResponse&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    objHeapDetails[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;heapSnapshotObjectId &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    objHeapDetails[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;heapSnapshotObjectId&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We’re almost done! We now just need to handle important edge cases. Because primitive types aren’t usually stored on the heap and instead on the stack (with the exception of Symbols), &lt;code&gt;Runtime.evaluate&lt;/code&gt; treats them differently. The method skips to the last step and directly returns their &lt;code&gt;memcpy&lt;/code&gt;-able value.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;// `Runtime.evaluate` on `{ foo: 42 }`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;className&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;Object&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;Object&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;objectId&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;...&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;object&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;// `Runtime.evaluate` on `42`&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;42&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;number&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 42&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While comparing two primitives would be a simple equality operation, I wanted to stay true to my word and avoid its use entirely. Rather, we need to implement the &lt;a href=&quot;https://tc39.es/ecma262/multipage/abstract-operations.html#sec-isstrictlyequal&quot;&gt;isStrictlyEqual&lt;/a&gt; ecma262 subroutine at the high level like so.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;background.js&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; primitiveEquality&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;p1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; p2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;subtype) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;subtype&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;subtype) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;subtype&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type)) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;number&quot;&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;NaN&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      stringEquality&lt;/span&gt;&lt;span&gt;(p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;NaN&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      (&lt;/span&gt;&lt;span&gt;stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;0&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        stringEquality&lt;/span&gt;&lt;span&gt;(p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;-0&quot;&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      (&lt;/span&gt;&lt;span&gt;stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;-0&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        stringEquality&lt;/span&gt;&lt;span&gt;(p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;0&quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unserializableValue &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unserializableValue) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;null&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;undefined&quot;&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;bigint&quot;&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;string&quot;&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;stringEquality&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;boolean&quot;&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(p1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; p2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  throw&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Unsupported primitive type&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; stringEquality&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;str1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; str2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (str1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; str2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; str1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i&lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (str1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;charCodeAt&lt;/span&gt;&lt;span&gt;(i) &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; str2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;charCodeAt&lt;/span&gt;&lt;span&gt;(i)) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And… there we go. The full implementation is provided in a &lt;a href=&quot;https://github.com/ArhanChaudhary/strictequality-js&quot;&gt;GitHub repository&lt;/a&gt;. I coughed together an ugly test module to verify its correctness.&lt;/p&gt;
&lt;p&gt;Did I forget to mention that it doesn’t work on page load because content scripts aren’t available globally? You’ll have to have fun awaiting the &lt;code&gt;strictEqualityLoaded&lt;/code&gt; event before usage.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;test.html&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  await&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Promise&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resolve&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addEventListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;strictEqualityLoaded&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; resolve&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; once&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  let&lt;/span&gt;&lt;span&gt; significantValues &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    0&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Symbol&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Math&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;PI&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Number&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MAX_SAFE_INTEGER&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Number&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MIN_SAFE_INTEGER&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Number&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MAX_SAFE_INTEGER &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Number&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MIN_SAFE_INTEGER &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Infinity&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -&lt;/span&gt;&lt;span&gt;Infinity&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    NaN&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    null&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    undefined&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    false&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {},&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    []&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    new&lt;/span&gt;&lt;span&gt; Date&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; obj1 &lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt; significantValues) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; obj2 &lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt; significantValues) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      let&lt;/span&gt;&lt;span&gt; expected &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; obj1 &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; obj2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      let&lt;/span&gt;&lt;span&gt; actual &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; strictEquality&lt;/span&gt;&lt;span&gt;(obj1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; obj2)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (actual &lt;/span&gt;&lt;span&gt;!==&lt;/span&gt;&lt;span&gt; expected) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        throw&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`Failed for &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;obj1&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; and &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;obj2&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Passed!&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Until next time!&lt;/p&gt;</content:encoded></item><item><title>DEF CON 32 Photo Dump</title><link>https://arhan.sh/blog/def-con-32-photo-dump/</link><guid isPermaLink="true">https://arhan.sh/blog/def-con-32-photo-dump/</guid><pubDate>Tue, 13 Aug 2024 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It’s that time of year again. I had the opportunity to attend DEF CON 32 at Las Vegas with my friends &lt;a href=&quot;https://bithole.dev&quot;&gt;Adrian&lt;/a&gt; and &lt;a href=&quot;https://rluo.dev&quot;&gt;Ruien&lt;/a&gt;, my CTF teammates. DEF CON is the world’s largest cybersecurity convention, and this was my second DEF CON event. The event lasted for four days, so we made sure to spend that time in its fullest.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/plane.DjcxCfbb_ZwuASF.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/plane.DjcxCfbb_G23uw.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/plane.DjcxCfbb_Z2k79y0.jpg&quot; alt=&quot;The plane flight to Las Vegas&quot; loading=&quot;lazy&quot; width=&quot;375&quot; height=&quot;500&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;This year, DEF CON moved to an entirely new venue. Feast your eyes on the Las Vegas Convention Center, one of the largest convention centers in the world.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/venue.C-wqegOV_mFR6s.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/venue.C-wqegOV_VUzzx.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/venue.C-wqegOV_1BXSW4.jpg&quot; alt=&quot;The Las Vegas Convention Center&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;750&quot; /&gt;&lt;/picture&gt;&lt;div&gt;This photo was taken at 0.5x zoom&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;As expected, we were greeted by this hacked sign. This was how we knew we were at the right place.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/sign.fJnjSyWB_Z1O530T.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/sign.fJnjSyWB_1DbvTv.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/sign.fJnjSyWB_brLFJ.jpg&quot; alt=&quot;A hacked sign at DEF CON&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;531&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Someone gave me some cool swag xD.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/crowdstrike.CuiV9NdO_Z1UhUw4.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/crowdstrike.CuiV9NdO_ZA4dr4.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/crowdstrike.CuiV9NdO_Y4y8B.jpg&quot; alt=&quot;A Crowdstrike sticker&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;933&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;We spent the entirety of our first day in LineCon. I’m not exaggerating. I waited in the merch line for seven hours straight.&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/balls.r70S0JVu.mov&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;Anyways, this year’s DEF CON badge was a fully fleshed out entire RPG game made by a &lt;a href=&quot;https://dmitry.gr/&quot;&gt;sole developer&lt;/a&gt;. More excitingly, DEF CON attendees were given exclusive access to the new RP2350 Raspberry PI MCU embedded within the badge.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/badge.e9RFN9bj_Z1rU52D.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/badge.e9RFN9bj_20ltRL.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/badge.e9RFN9bj_xBJE0.jpg&quot; alt=&quot;The DEF CON badge&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;800&quot; /&gt;&lt;/picture&gt;&lt;div&gt;The chip is the small black square at the bottom center&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;I tried to hack it, but eventually gave up because the tooling for such a new technology was virtually nonexistent.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/hack.CQGf_TAE_Z1abKxS.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/hack.CQGf_TAE_Z1xocOF.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/hack.CQGf_TAE_2aSbUL.jpg&quot; alt=&quot;Attempting to hack the DEF CON badge&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;933&quot; /&gt;&lt;/picture&gt;&lt;div&gt;Me trying and failing to install pico-sdk&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;The second day, we played a mini CTF called 5n4ck3y.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/vending.CbVwzPH5_PSGda.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/vending.CbVwzPH5_Z1zpMh2.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/vending.CbVwzPH5_Z13ww6v.jpg&quot; alt=&quot;The 5n4ck3y vending machine&quot; loading=&quot;lazy&quot; width=&quot;375&quot; height=&quot;500&quot; /&gt;&lt;/picture&gt;&lt;div&gt;You don&apos;t get to say every day that you managed to brick a vending machine&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;And won a cool DOOM gameboy.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/hackboi.CHNcq7qf_Z1zx4DG.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/hackboi.CHNcq7qf_14kzF3.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/hackboi.CHNcq7qf_1AdPPz.jpg&quot; alt=&quot;The DOOM gameboy&quot; loading=&quot;lazy&quot; width=&quot;375&quot; height=&quot;500&quot; /&gt;&lt;/picture&gt;&lt;div&gt;Yes, I did remove the plastic wrapper later&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;The day after that, we spent the entire afternoon playing our first attack and defense CTF. We managed to &lt;em&gt;somehow&lt;/em&gt; win the first round by being quick, but placed third in the second round. Neither of us really knew what we were doing. We played blue team pretty much the entire time, changing passwords and rebooting attacked systems. Still, it was a cool learning experience.&lt;/p&gt;
&lt;p&gt;We met a &lt;a href=&quot;https://danielchateau.com/&quot;&gt;friend&lt;/a&gt; on our team as well.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/aandd.DYDK4gHd_Z2h5VVc.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/aandd.DYDK4gHd_1baBYd.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/aandd.DYDK4gHd_Zgy7ey.jpg&quot; alt=&quot;The A&amp;amp;D CTF&quot; loading=&quot;lazy&quot; width=&quot;675&quot; height=&quot;514&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Finally, on our last day, I visited some DEF CON villages and tried my hand at soldering and lock picking. I also got the chance to talk with other students from Purdue. Exciting stuff!&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/soldering.cNL-sGt8_Z1qWmw6.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/soldering.cNL-sGt8_17FsiG.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/soldering.cNL-sGt8_4QV4j.jpg&quot; alt=&quot;soldering&quot; loading=&quot;lazy&quot; width=&quot;375&quot; height=&quot;500&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/lock.CY_2F9gl_Z16DjUv.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/lock.CY_2F9gl_Z1tPLci.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/lock.CY_2F9gl_2eqCy9.jpg&quot; alt=&quot;lock&quot; loading=&quot;lazy&quot; width=&quot;375&quot; height=&quot;500&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Of course, as my last remark, we can’t leave out our friend group shenanigans at the hotel.&lt;/p&gt;
&lt;div&gt;&lt;video controls&gt;&lt;source src=&quot;/_astro/sandstorm.B49AQseZ.mov&quot; type=&quot;video/mp4&quot;&gt;&lt;/source&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/div&gt;
&lt;p&gt;This year’s DEF CON was awesome! Until next time!&lt;/p&gt;</content:encoded></item><item><title>True Private State in JavaScript: a Chromium Rabbit Hole</title><link>https://arhan.sh/blog/true-private-state-in-javascript-a-chromium-rabbit-hole/</link><guid isPermaLink="true">https://arhan.sh/blog/true-private-state-in-javascript-a-chromium-rabbit-hole/</guid><description>Front-end obfuscation without network or cryptography</description><pubDate>Sun, 11 Aug 2024 08:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Table of Contents&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#what-is-true-private-state&quot;&gt;What is “true” private state?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#true-private-state-in-javascript&quot;&gt;True private state in JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#true-private-state-in-devtools&quot;&gt;True private state in DevTools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#true-private-state-in-devtools-the-extension-way&quot;&gt;True private state in DevTools: the extension way&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#closing-thoughts&quot;&gt;Closing thoughts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;What is “true” private state?&lt;/h1&gt;
&lt;p&gt;One of the first programming concepts you learn is the private variable, and the notion of encapsulation. These are fundamental concepts of object-oriented programming, a paradigm that emphasizes data structures, message passing, and abstraction.&lt;/p&gt;
&lt;p&gt;For no reason at all, we’re going to casually set aside the intended theory, and take the term “private variable” (or “private state”) literally.&lt;/p&gt;
&lt;p&gt;What do I think true private state should actually mean? For a class definition in a given programming language:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;There must not exist a way to &lt;strong&gt;directly&lt;/strong&gt; access a private variable’s value given an instance of the class.&lt;/li&gt;
&lt;li&gt;There must exist exactly one &lt;strong&gt;indirect&lt;/strong&gt; way to access a private variable’s value given an instance of the class.&lt;/li&gt;
&lt;li&gt;The first step of the private variable access must be performed from within the language (no CheatEngine/GDB).&lt;/li&gt;
&lt;li&gt;The class implementation’s source cannot be modified by the private variable access (to counter archaic solutions similar to &lt;a href=&quot;https://stackoverflow.com/a/59424277/12230735&quot;&gt;this&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;The class implementation must not use cryptography or network programming.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Direct access refers to code that aliases into a private variable’s value, for example by property accessor syntax such as &lt;code&gt;rectangle.length&lt;/code&gt; or direct memory access. Indirect access refers to code that evaluates to a private variable’s value, but doesn’t actually alias into it in the same manner. While the expression &lt;code&gt;rectangle.getLength()&lt;/code&gt; retrieves the private variable’s value, the expression alone doesn’t alias into it.&lt;/p&gt;
&lt;p&gt;My definitions inherently make the meaning of indirect access subjective. After all, these concepts and ideas are based on high-level programming abstractions. The processor sees every operation as just reading and writing to memory, thereby voiding the concept of indirect access at the low level. Hopefully, the following examples and the rest of the post will help draw the line between what qualifies access as “direct” or “indirect”.&lt;/p&gt;
&lt;p&gt;These five implementation requirements will be the key criteria in assessing whether or not a class implementation provides true private state. Generalizing them across many popular programming languages unmasks true identity of the term “private variable”… as a shameless misnomer!&lt;/p&gt;
&lt;p&gt;Let’s first look at Java, a language whose primary purpose is to provide strong encapsulation boundaries. So, implementing true private state seems like it would simple enough, right?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; class&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  private&lt;/span&gt;&lt;span&gt; Object&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  public&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  public&lt;/span&gt;&lt;span&gt; Object&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Red buzzer. It’s easy to hijack private fields using Java’s reflection services, breaking the requirement of no direct memory access for true private state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; java&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;lang&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;reflect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Field&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; class&lt;/span&gt;&lt;span&gt; Main&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  public&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; void&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;span&gt; args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; throws&lt;/span&gt;&lt;span&gt; NoSuchFieldException&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; IllegalAccessException&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Secret&lt;/span&gt;&lt;span&gt; secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Character&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;65&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;repeat&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Field&lt;/span&gt;&lt;span&gt; secretField &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getClass&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;getDeclaredField&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;secret&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    secretField&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setAccessible&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secretField&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // Output: AAAAAAAAAA&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You may point out that reflection can be disabled with the &lt;code&gt;-Djava.security.manager&lt;/code&gt; flag. But because this flag is opt-in, it doesn’t matter; recall that there must not exist &lt;u&gt;a&lt;/u&gt; way of direct access into a private variable. Even then, you could alternatively use Java’s Native Interface API as demonstrated &lt;a href=&quot;https://gist.github.com/ArhanChaudhary/20200eda359458aa72f748c285c139fd&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Looking at something else, Python barely even tries!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  def&lt;/span&gt;&lt;span&gt; __init__&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;__secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  def&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;__secret&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;chr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;65&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt; 10&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_Secret__secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Output: AAAAAAAAAA&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Such is the case with C++, C#, Ruby, and so on — there’s always a way to alias into private fields in such a way that breaks the requirements for true private state, most namely through foreign function interfaces.&lt;/p&gt;
&lt;p&gt;I want to make clear that I understand that these escape hatches are the results of intentional and thought-out design efforts. If you discount cryptography and network programming and really think about it, private state in modern object-oriented programming is by obscurity. The general philosophy is to present a massive “Here be dragons” warning when people decide to access the internals of an object anyways, typically through discomfort and community disapproval.&lt;/p&gt;
&lt;p&gt;In the Python example, &lt;code&gt;_Secret__secret&lt;/code&gt; is intimidating enough to discourage its usage, actively making the programmer feel bad. Endowing the programmer with full access to the internals of an object is OK, because it is assumed that they understand the consequences of depending on undocumented and volatile class APIs.&lt;/p&gt;
&lt;h1&gt;True private state in JavaScript&lt;/h1&gt;
&lt;p&gt;In regards to true private state, what does JavaScript offer?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  #secret&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  constructor&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;#secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  get&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;#secret&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;(String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromCharCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;65&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;repeat&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(secret&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// Output: AAAAAAAAAA&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Believe it or not, for how historically chaotically-evil JavaScript has proven itself as a language, this is our silly little answer. True private state! The &lt;a href=&quot;https://github.com/tc39/proposal-class-fields&quot;&gt;proposal&lt;/a&gt; for private JavaScript class fields guarantees their soundness:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Private fields provide a strong encapsulation boundary: It’s impossible to access the private field from outside of the class, unless there is some explicit code to expose it (for example, providing a getter).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If this is it, what was the deal with the mumbo jumbo at the beginning? Well, you can see from the remaining length of this blog post that there’s far more to the story than just JavaScript private fields. Our treasure lands on another island; I’m going to introduce a seemingly arbitrary liberation to the challenge: Chromium DevTools. What you see when you “inspect element” a web page. As I will soon demonstrate, this environment enables a myriad of backdoors that make true private state far more interesting.&lt;/p&gt;
&lt;h1&gt;True private state in DevTools&lt;/h1&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/private-accessor.kYjCB3B6_ZghvUv.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/private-accessor.kYjCB3B6_Z2tq4Bb.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/private-accessor.kYjCB3B6_ZR3vLi.png&quot; alt=&quot;An image demonstrating that you can directly access private variables in DevTools&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;213&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Something is already wrong right off the bat. Some research unveils &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_properties#sect1&quot;&gt;this documentation&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Code run in the Chrome console can access private properties outside the class. This is a DevTools-only relaxation of the JavaScript syntax restriction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Okay, we just need to try a little harder.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; Secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  // The difference between WeakMap&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  // and Map isn&apos;t relevant&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  let&lt;/span&gt;&lt;span&gt; _secrets &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; WeakMap&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; class&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    constructor&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      _secrets&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; secret)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    get&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; _secrets&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;(String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromCharCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;65&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;repeat&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(secret&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// Output: AAAAAAAAAA&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This approach is widely used as a polyfill for private JavaScript class fields, by &lt;a href=&quot;https://babeljs.io/repl#?browsers=&amp;amp;build=&amp;amp;builtIns=false&amp;amp;corejs=3.21&amp;amp;spec=false&amp;amp;loose=false&amp;amp;code_lz=KYDwDg9gTgLgBAYwDYEMDOa4GVgKseAbwCg44BiNXfGAbmNMQgDs0YoBXBGaACirwEAlHBJkyMABYBLNADpK1AnAC8cATXpkAvgzIBzArxFjxNDlGZwpshRoJa4u7UA&amp;amp;debug=false&amp;amp;forceAllTransforms=false&amp;amp;modules=false&amp;amp;shippedProposals=false&amp;amp;evaluate=false&amp;amp;fileSize=false&amp;amp;timeTravel=false&amp;amp;sourceType=module&amp;amp;lineWrap=true&amp;amp;presets=stage-3&amp;amp;prettier=false&amp;amp;targets=&amp;amp;version=7.25.3&amp;amp;externalPlugins=babel-plugin-iife-wrap%401.1.0&amp;amp;assumptions=%7B%7D&quot;&gt;Babel&lt;/a&gt; for instance. There’s seemingly no way for external code to access the closure variable &lt;code&gt;_secrets&lt;/code&gt;, is this true private state? Unfortunately, no. DevTools reveals the first trick of many up its sleeve.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/weakmap-devtools.CXnLu6Yv_15xHIf.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/weakmap-devtools.CXnLu6Yv_Z2hWuB5.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/weakmap-devtools.CXnLu6Yv_1vPzbz.png&quot; alt=&quot;An image demonstrating that you can directly access scope information in DevTools&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;583&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Recall my definition of direct access as “aliasing into a private variable’s value”. This is evidently what’s happening, thus discrediting closure variables as a solution, perhaps our biggest weapon so far. The DevTools scope inspector gives you access to practically &lt;em&gt;every&lt;/em&gt; internal variable within a class. To put the nail in the coffin, I developed a way to programmatically access closure variables within DevTools, and exactly how is a story for another blog.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;(String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromCharCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;65&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;repeat&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; scopeInspect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;secret&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// {value: &apos;AAAAAAAAAA&apos;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hm, let’s see if we can exploit the dynamic nature of the &lt;code&gt;eval&lt;/code&gt; function. Directly calling &lt;code&gt;eval&lt;/code&gt; still reveals closure variables to the scope inspector. Could we instead use a reference to &lt;code&gt;eval&lt;/code&gt; to conditionally capture closure variables?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  constructor&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; window[&lt;/span&gt;&lt;span&gt;&quot;ev&quot;&lt;/span&gt;&lt;span&gt; +&lt;/span&gt;&lt;span&gt; &quot;al&quot;&lt;/span&gt;&lt;span&gt;](&lt;/span&gt;&lt;span&gt;&quot;sec&quot;&lt;/span&gt;&lt;span&gt; +&lt;/span&gt;&lt;span&gt; &quot;ret&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;(String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromCharCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;65&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;repeat&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(secret&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// Output: AAAAAAAAAA (?)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Considering that complete static analysis for a program has been proven to be &lt;a href=&quot;https://en.wikipedia.org/wiki/Rice%27s_theorem&quot;&gt;undecidable&lt;/a&gt;, &lt;code&gt;window[&quot;ev&quot; + &quot;al&quot;]&lt;/code&gt; can only be evaluated at runtime. In theory, the scope inspector wouldn’t know to capture closure variables until the &lt;code&gt;eval&lt;/code&gt; in the getter function is called.&lt;/p&gt;
&lt;p&gt;As it turns out, the V8 engine is one step ahead of us. The above code throws a ReferenceError because smarter people than me have already thought of ways to compensate for this issue. &lt;code&gt;eval&lt;/code&gt; captures local scope only when &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#direct_and_indirect_eval&quot;&gt;directly&lt;/a&gt; called and captures global scope otherwise, bringing us back to square one.&lt;/p&gt;
&lt;p&gt;At this point I realized that what I was trying to achieve was going to be much more difficult than expected. A day of tinkering later, I stumbled upon this solution.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  constructor&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;warn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;`Secret` may not properly serialize complex JavaScript values&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`return JSON.parse(&apos;&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stringify&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&apos;)`&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      .&lt;/span&gt;&lt;span&gt;bind&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      .&lt;/span&gt;&lt;span&gt;bind&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;(String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromCharCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;65&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;repeat&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(secret&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// Output: AAAAAAAAAA&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To my credit, this was a surprisingly witty solution. It avoided the use of closures and utilized the &lt;code&gt;Function&lt;/code&gt; constructor to hide the secret. Calling &lt;code&gt;valueOf&lt;/code&gt; or &lt;code&gt;toString&lt;/code&gt; on a function normally reveals its source code, however postfixing two &lt;code&gt;.bind()&lt;/code&gt;s tricks DevTools into revealing &lt;code&gt;function () { [native code] }&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;It’s a shame that my friend Adrian debunked my findings two days later.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/bind-debunked.BMjZcL6Z_1BNts1.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/bind-debunked.BMjZcL6Z_1YzSOH.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/bind-debunked.BMjZcL6Z_u1aaJ.png&quot; alt=&quot;An image demonstrating that my solution was invalid&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;985&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Pivoting once again, does DevTools reveal WebAssembly memory? If not, we could interface with it to our advantage.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/wasm-memory.DRQwFF2B_Z1eNeU6.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/wasm-memory.DRQwFF2B_Z14cAHC.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/wasm-memory.DRQwFF2B_1mYseM.png&quot; alt=&quot;An image demonstrating that DevTools reveals WebAssembly memory&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;879&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Yes, it does as a form of direct memory access.&lt;/p&gt;
&lt;p&gt;Now, our first real breakthrough!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  constructor&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;(secret)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Promise&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resolve&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;updateState &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; resolve&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bind&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; secret))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;(String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromCharCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;65&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;repeat&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;updateState&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secret)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// Output: AAAAAAAAAA&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is similar to the closure solution except unlike the &lt;code&gt;eval&lt;/code&gt; solution, we’ve &lt;em&gt;actually&lt;/em&gt; tricked DevTools. For brevity I won’t show an image, but this time &lt;code&gt;secret&lt;/code&gt; is hidden from the scope inspector. Binding &lt;code&gt;this.updateState&lt;/code&gt; directly to &lt;code&gt;resolve&lt;/code&gt; relinquishes its need to display &lt;code&gt;secret&lt;/code&gt; because the binding doesn’t canonically create a closure. Simply calling the resolver and awaiting the promise gives back the original value!&lt;/p&gt;
&lt;p&gt;In a cruel twist of fate, this solution happens to be invalid because of the DevTools heap profiler.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/heap-profiler.DPQzubeE_1W2X0F.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/heap-profiler.DPQzubeE_Zg5zF0.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/heap-profiler.DPQzubeE_1lgX9S.png&quot; alt=&quot;An image showing off the DevTools heap profiler&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;567&quot; /&gt;&lt;/picture&gt;&lt;div&gt;The heap profiler exposes variables from web workers and popups as well&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;However, that doesn’t mean there isn’t more to the story. I was missing the bigger, more abstract picture. JavaScript is inherently a garbage collected language. Logically speaking, it’s impossible to remove all references to a secret variable or else it would become garbage collected. I mean, duh, but saying this out loud made me realize I needed to completely reapproach my strategy.&lt;/p&gt;
&lt;h1&gt;True private state in DevTools: the extension way&lt;/h1&gt;
&lt;p&gt;You could argue I’m pushing the limits of the DevTools environment, but I like to think of this as thinking outside the box. Chrome extensions provide a secure sandboxing environment to uphold their security guarantees. We can use this to our advantage.&lt;/p&gt;
&lt;p&gt;Here is an implementation of private state in JavaScript that satisfies all five of my requirements. It utilizes IndexedDB on a Chrome extension background script to store secret variables in an isolated execution context (the &lt;code&gt;chrome.storage&lt;/code&gt; API works too).&lt;/p&gt;
&lt;p&gt;You’ve seen enough code blocks so far, so as to not ruin your patience I’ve taken the liberty of hiding the code implementation in a dropdown.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;The code&lt;/summary&gt;&lt;p&gt;&lt;code&gt;manifest.json&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;Secret&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;An extension that provides private state within DevTools&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;0.1&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;manifest_version&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;host_permissions&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;http://*/*&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;https://*/*&quot;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;background&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;&lt;/span&gt;&lt;span&gt;service_worker&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;background.js&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;&lt;/span&gt;&lt;span&gt;content_scripts&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;&lt;/span&gt;&lt;span&gt;matches&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;&amp;lt;all_urls&amp;gt;&quot;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;&lt;/span&gt;&lt;span&gt;js&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;contentScript.js&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;&lt;/span&gt;&lt;span&gt;matches&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;&amp;lt;all_urls&amp;gt;&quot;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;&lt;/span&gt;&lt;span&gt;js&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;secret.js&quot;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;&lt;/span&gt;&lt;span&gt;world&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;MAIN&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;secret.js&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  static&lt;/span&gt;&lt;span&gt; secretId &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  constructor&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secretId &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secretId&lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;dispatchEvent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      new&lt;/span&gt;&lt;span&gt; CustomEvent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;set&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; detail&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; secretId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secretId &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    )&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  async&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;dispatchEvent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; CustomEvent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;get&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; detail&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secretId &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Promise&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resolve&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addEventListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;getResponse&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          resolve&lt;/span&gt;&lt;span&gt;(e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;detail)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;span&gt; once&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      )&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;contentScript.js&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addEventListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;set&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span&gt; ({&lt;/span&gt;&lt;span&gt; detail&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; secretId&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  chrome&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;runtime&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sendMessage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;set&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; secretId &lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;dispatchEvent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; CustomEvent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;setResponse&quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addEventListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;get&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span&gt; ({&lt;/span&gt;&lt;span&gt; detail&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; secretId&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  chrome&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;runtime&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sendMessage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;get&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; secretId &lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;dispatchEvent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; CustomEvent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;getResponse&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; detail&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; secret &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;background.js&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; DB_NAME &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &quot;SecretsDB&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; DB_VERSION &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; OBJECT_STORE_NAME &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &quot;secrets&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;chrome&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;runtime&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;onMessage&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  message&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;span&gt; documentId&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  sendResponse&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (message&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &quot;set&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    openDbStore&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;readwrite&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;store&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      store&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(documentId)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;onsuccess&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;target&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;result &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; documentId&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; secrets&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        data&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secrets[message&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secretId] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        store&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;put&lt;/span&gt;&lt;span&gt;(data)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;onsuccess &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sendResponse&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span&gt; else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (message&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;type &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &quot;get&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    openDbStore&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;readonly&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;store&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      store&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(documentId)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;onsuccess&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        let&lt;/span&gt;&lt;span&gt; data &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;target&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        sendResponse&lt;/span&gt;&lt;span&gt;(data&lt;/span&gt;&lt;span&gt;?.&lt;/span&gt;&lt;span&gt;secrets[message&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;secretId])&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span&gt; openDbStore&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mode&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  let&lt;/span&gt;&lt;span&gt; request &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; indexedDB&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;(DB_NAME&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; DB_VERSION)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  request&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;onupgradeneeded&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; db &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;target&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    db&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createObjectStore&lt;/span&gt;&lt;span&gt;(OBJECT_STORE_NAME&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; keyPath&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;documentId&quot;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  let&lt;/span&gt;&lt;span&gt; db &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Promise&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resolve&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    request&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;onsuccess&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; resolve&lt;/span&gt;&lt;span&gt;(e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;target&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;result)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  let&lt;/span&gt;&lt;span&gt; store &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; db&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;transaction&lt;/span&gt;&lt;span&gt;(OBJECT_STORE_NAME&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; mode)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;objectStore&lt;/span&gt;&lt;span&gt;(OBJECT_STORE_NAME)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; store&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;p&gt;Instantiate and retrieve the secret like so.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; secret &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Secret&lt;/span&gt;&lt;span&gt;(String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromCharCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;65&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;repeat&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;// Output: AAAAAAAAAA&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have our answer. There’s no way for code on the web page to “directly access” the background script’s IndexedDB. The secret can only be retrieved indirectly, through the &lt;code&gt;get&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;I could just end off over here, but there’s one thing left to address. It’s still &lt;em&gt;possible&lt;/em&gt; to access the secret within Chrome if you navigate to &lt;code&gt;chrome://extensions&lt;/code&gt;, open the background script DevTools window, and run this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; openDbStore&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;readonly&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  (&lt;/span&gt;&lt;span&gt;store&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    new&lt;/span&gt;&lt;span&gt; Promise&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resolve&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      store&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getAll&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;onsuccess&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; resolve&lt;/span&gt;&lt;span&gt;(e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;target&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;result)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For no reason at all, let’s make this even more unnecessarily complicated. Utilizing the native application API, it’s possible to store the secret outside of Chrome entirely! I’ve documented my exact findings in this &lt;a href=&quot;https://github.com/ArhanChaudhary/chrome-secret-js&quot;&gt;GitHub repository&lt;/a&gt;. Instead of providing the code’s source like before, I had some free time and thought it would be cool to diagram how it worked. Some eye candy:&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/secret-diagram.CDwHK6-7_Z2BLXv.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/secret-diagram.CDwHK6-7_k9Cob.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/secret-diagram.CDwHK6-7_Z1ap6fM.png&quot; alt=&quot;An image diagramming the native app secret implementation&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;891&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h1&gt;Closing thoughts&lt;/h1&gt;
&lt;p&gt;It’s time to address the elephant in the room. The correct way to store a secret variable is to use cryptography or networking services.&lt;/p&gt;
&lt;p&gt;First, cryptography. Take your pick. The &lt;a href=&quot;https://webauthn-large-blob.glitch.me/&quot;&gt;WebAuthn large blob&lt;/a&gt; and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Credential_Management_API&quot;&gt;credential management&lt;/a&gt; APIs use your operation system keychain to store credentials, with some obscure &lt;a href=&quot;https://issues.chromium.org/issues/40283676#comment5&quot;&gt;limitations&lt;/a&gt;. The &lt;a href=&quot;https://github.com/w3c/webextensions/issues/154&quot;&gt;browser.secureStorage&lt;/a&gt; API might become a reality soon. SubtleCrypto can be &lt;a href=&quot;https://www.w3.org/TR/WebCryptoAPI/#concepts-key-storage&quot;&gt;used with&lt;/a&gt; IndexedDB for cryptographically secure key management. Common password manager extensions use this method.&lt;/p&gt;
&lt;p&gt;Networking is self-explanatory, and is what 99% websites do. Store the secret on the server, rather than risk the user meddling with its value.&lt;/p&gt;
&lt;p&gt;So… was this blog basically pointless? Yes. I will accept criticism that my requirements for “true” private state are arbitrary. It’s worth pointing out however that these topics are relevant in related fields of cybersecurity, such as in hardware security.&lt;/p&gt;
&lt;p&gt;Was this blog a waste of your time? Maybe. Hopefully you learned something about JavaScript or DevTools debugging or the theory behind object-oriented programming. If you didn’t then I don’t really care. Until next time!&lt;/p&gt;</content:encoded></item><item><title>My GitHub Repository has 100,000 Contributors</title><link>https://arhan.sh/blog/my-github-repository-has-100000-contributors/</link><guid isPermaLink="true">https://arhan.sh/blog/my-github-repository-has-100000-contributors/</guid><description>A parody of &quot;everything&quot; from npm</description><pubDate>Mon, 01 Jul 2024 08:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Table of Contents&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#what&quot;&gt;What?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-plan&quot;&gt;The plan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-script&quot;&gt;The script&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-mystery-of-u_kgdoambr8w&quot;&gt;The mystery of U_kgDOAMbr8w&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-mystery-of-mywebsite&quot;&gt;The mystery of MyWebsite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#100000-contributors&quot;&gt;100,000 Contributors&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;What?&lt;/h1&gt;
&lt;p&gt;Your eyes don’t deceive you. You can check right now: my &lt;a href=&quot;https://github.com/ArhanChaudhary/everyone&quot;&gt;GitHub repository&lt;/a&gt; has 100,000 contributors. If you are on GitHub mobile, the number may not appear. You have to view this repository through GitHub’s web UI.&lt;/p&gt;
&lt;p&gt;Before I explain the why and the how, we first need to go back to a few weeks ago. I was routinely moving around some configuration files, and I accidentally swapped my &lt;code&gt;~/.gitconfig&lt;/code&gt; file with that of my alternate account. When I pushed to one of my repositories, I was surprised to notice that my alt account was added as a contributor! Its rendered profile picture, username, and hyperlink — all neatly displayed under “Contributors”.&lt;/p&gt;
&lt;p&gt;There’s a good chance you’ve already seen something &lt;a href=&quot;https://github.com/Amog-OS/AmogOS/commit/0bb33e31e2a529bfd13c6013d1ad2dffa2485b61&quot;&gt;similar&lt;/a&gt; to this; it isn’t hard or particularly new to fake a commit from another user. But my curiosity was sparked. In my mind, the next logical question to ask was: how many contributors could I fake? And thereafter: could I get to exactly 100,000 contributors? It would be a fireplace of ghosts, a bizarre pit stop of GitHub users.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Before continuing, I would like to point out that users can sign their commits to cryptographically verify their identity, ineffectuating impersonation. Even then, impersonation is against GitHub’s &lt;a href=&quot;https://docs.github.com/en/site-policy/acceptable-use-policies/github-impersonation&quot;&gt;Acceptable Use Policies&lt;/a&gt;. Please be wary.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I wasn’t trying to make 100,000 commits faking a different user each time, so I did some research and found a more efficient way. If you add two new lines under a commit message, you can co-author users with their username and email address as shown.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;~&lt;/span&gt;&lt;span&gt; % git commit -m &lt;/span&gt;&lt;span&gt;&quot;Refactor usability tests.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Co-authored-by: NAME &amp;lt;NAME@EXAMPLE.COM&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Co-authored-by: ANOTHER-NAME &amp;lt;ANOTHER-NAME@EXAMPLE.COM&amp;gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And so on, with seemingly no co-author limit. Luckily for my case, each one is added as a contributor! Armed with this knowledge, I began to formulate a plan.&lt;/p&gt;
&lt;h1&gt;The plan&lt;/h1&gt;
&lt;p&gt;Manually adding this many users to a commit message obviously isn’t practical. I needed to write an API scraper, and a quick check of GitHub’s policies affirms I’m allowed to do this provided that I’m not excessive.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We do allow the use of automated tools so long as they do not produce excessive amounts of traffic. For example, running one nmap scan against one host is allowed, but sending 65,000 requests in two minutes using Burp Suite Intruder is excessive.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, I got to brainstorming. The most important conceptual hurdle was figuring out how to get a user’s email address, as you can’t co-author a user without it. The problem was, even if a user makes their email address address publicly visible on their profile, the GitHub API doesn’t reliably expose it&lt;sup&gt;&lt;a href=&quot;#fn-graphql&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. Surprisingly, there is a very well-known way to circumvent this and find almost anyone’s email address on GitHub.&lt;/p&gt;
&lt;p&gt;Simply navigate to any commit authored by a user on GitHub and append &lt;code&gt;.patch&lt;/code&gt; to the commit’s url. Et voilà! The second line from the top enclosed within angled brackets lies their email address, in full form and glory. It sounds concerning that this type of information is so easy to access, but if you think about it, emails are made public for a reason. Attribution and contact are pretty important from an open source perspective.&lt;/p&gt;
&lt;p&gt;With these types of technical projects that work with big data, social conduct should be taken seriously. I don’t want to end up in a similar situation as &lt;a href=&quot;https://github.com/EpicGames/Signup/pull/24&quot;&gt;this guy&lt;/a&gt; and piss off 100,000 people by publicly leaking their email addresses. So, I decided to only co-author private email addresses that are only valid within GitHub.&lt;/p&gt;
&lt;p&gt;Admittedly, a small amount of real email addresses were committed at the beginning, but only for testing purposes. I believe that this amount is small enough to be insignificant and inconsequential.&lt;/p&gt;
&lt;p&gt;How would I find 100,000 users? GitHub provides a Search API for querying for users, but this was problematic because it had a rate limit of… wait for it… 30 requests per hour. Ba dum, tss! Instead, I opted to use the API endpoint for followers to feed my scraper its users, which had a more reasonable rate limit I could work with.&lt;/p&gt;
&lt;p&gt;Putting everything together, my API scraper will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First use the Search API to find the most followed users on GitHub&lt;/li&gt;
&lt;li&gt;Use the followers API endpoint to loop through each user’s followers &lt;em&gt;(In retrospect, another approach could be utilizing a web crawling algorithm)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Use the “hack” as described earlier to find each follower’s email address&lt;/li&gt;
&lt;li&gt;Filter each email address for private email addresses and format the co-author message&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hopefully you can see that, through some intuitional ingenuity, the idea no longer sounds as Herculean a task as it seems.&lt;/p&gt;
&lt;h1&gt;The script&lt;/h1&gt;
&lt;p&gt;I decided to write the scraper in JavaScript so I could utilize &lt;a href=&quot;https://github.com/octokit/octokit.js&quot;&gt;octokit.js&lt;/a&gt;, an API wrapper that provides useful built-in functionality such as throttling and retrying. I also decided to use GitHub’s GraphQL API instead of their REST API because multiple GraphQL queries could be batched in a single request and other smaller efficiencies.&lt;/p&gt;
&lt;p&gt;After hacking up a prototype, I tested my first commit.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/partially-verified.CUdzrDdy_1Lcrj0.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/partially-verified.CUdzrDdy_Z1BiL1k.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/partially-verified.CUdzrDdy_2cuiLk.png&quot; alt=&quot;A commit with 2,000 contributors&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;118&quot; /&gt;&lt;/picture&gt;&lt;div&gt;In ironic fashion, because I sign my commits, the commit was labeled &quot;Partially verified&quot; in green&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;It works!&lt;/p&gt;
&lt;p&gt;I would spend the next week polishing response edge cases and ironing out inefficiencies, before I was finally ready to run my scraper.&lt;/p&gt;
&lt;p&gt;I didn’t feel like running it locally because I knew from testing it would take a long time. Instead I bought a DigitalOcean VM, imported my script, and ran it as a background process.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;~#&lt;/span&gt;&lt;span&gt; git&lt;/span&gt;&lt;span&gt; clone&lt;/span&gt;&lt;span&gt; https://github.com/ArhanChaudhary/everyone&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;~#&lt;/span&gt;&lt;span&gt; cd&lt;/span&gt;&lt;span&gt; everyone&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;~/everyone#&lt;/span&gt;&lt;span&gt; nohup&lt;/span&gt;&lt;span&gt; node&lt;/span&gt;&lt;span&gt; index.mjs&lt;/span&gt;&lt;span&gt; --co-author-count=100000&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; results.txt&lt;/span&gt;&lt;span&gt; 2&amp;gt;&lt;/span&gt;&lt;span&gt; log.txt&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; 104705&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think it’s worth mentioning how surprisingly lenient the GraphQL API rate limits are, given how &lt;a href=&quot;https://stackoverflow.com/questions/13394077/is-there-a-way-to-increase-the-api-rate-limit-or-to-bypass-it-altogether-for-git&quot;&gt;notoriously restrictive&lt;/a&gt; the Rest API rate limits are. Even though my scraper was continuously and asynchronously parallelizing multiple batched queries at once, the highest I ever saw the GraphQL hourly rate limit quota reach was 1,500 out of 5,000 points.&lt;/p&gt;
&lt;p&gt;Nine hours later, combing through approximately half a million GitHub users, my scraper yielded 100,000 co-authors, each ready to become a contributor. Hooray!&lt;/p&gt;
&lt;p&gt;I’m so sorry if it feels like I’m cutting you off, but I first wanted to discuss a few API anomalies on the error log before we get to the committing. Trust me, what I’ve found is equally, if not more interesting.&lt;/p&gt;
&lt;h1&gt;The mystery of U_kgDOAMbr8w&lt;/h1&gt;
&lt;p&gt;Out of those half a million users, exactly two of them always crash the GraphQL API. That’s a &lt;em&gt;0.0004%&lt;/em&gt; fallthrough rate. Following some investigation, I was able to narrow down the crashing to any valid query containing the substring &lt;code&gt;history(author: {id: &quot;...&quot;})&lt;/code&gt;, where the &lt;code&gt;id&lt;/code&gt; parameter is either of their GraphQL user IDs. If you want to try yourself, execute this on the &lt;a href=&quot;https://docs.github.com/en/graphql/overview/explorer&quot;&gt;GitHub GraphQL explorer&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;query&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  repository(&lt;/span&gt;&lt;span&gt;owner&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;torvalds&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;linux&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    defaultBranchRef &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      target &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ...&lt;/span&gt;&lt;span&gt; on&lt;/span&gt;&lt;span&gt; Commit&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          history(&lt;/span&gt;&lt;span&gt;author&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;U_kgDOAMbr8w&quot;&lt;/span&gt;&lt;span&gt;}) &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            totalCount&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It doesn’t matter which repository you specify, the results are the same.&lt;/p&gt;
&lt;p&gt;I emailed both users to inquire about anything they might know about this issue. The second user responded, equally as puzzled as I was. After exchanging Discords, we spent a few hours discussing theories and possible security concerns, but despite our research we weren’t able to come to a conclusion. I ultimately ended up filing a bug report to GitHub support.&lt;/p&gt;
&lt;p&gt;I would receive this response.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hi Arhan,&lt;/p&gt;
&lt;p&gt;Thanks for reaching out!&lt;/p&gt;
&lt;p&gt;I was able to reproduce the error and it seems the bug is related to some odd
author information associated with user accounts.&lt;/p&gt;
&lt;p&gt;I have filed an internal issue with the engineering team to look into this bug.
While I don’t have an ETA on a fix now, we appreciate you reaching out on how we
can make things better.&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;The mystery of MyWebsite&lt;/h1&gt;
&lt;p&gt;Have you ever seen a corrupted repository?&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/corrupted-repository.Cl_L2PI6_164PkM.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/corrupted-repository.Cl_L2PI6_ZQmW5j.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/corrupted-repository.Cl_L2PI6_Z14Ebvo.png&quot; alt=&quot;A repository that is corrupted&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;562&quot; /&gt;&lt;/picture&gt;&lt;div&gt;I won&apos;t be revealing the author nor the link to respect their privacy&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Well, it ended up crashing my script half way through. Having to re-run it was more annoying than it should have been.&lt;/p&gt;
&lt;p&gt;It turns out you can still clone this repository. Inspecting the commit history presents something interesting.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Desktop&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; git&lt;/span&gt;&lt;span&gt; clone&lt;/span&gt;&lt;span&gt; https://github.com/.../MyWebsite.git&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Desktop&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; cd&lt;/span&gt;&lt;span&gt; MyWebsite&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MyWebsite&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; git&lt;/span&gt;&lt;span&gt; log&lt;/span&gt;&lt;span&gt; -n&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Date:&lt;/span&gt;&lt;span&gt;   Fri&lt;/span&gt;&lt;span&gt; Dec&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; 10:14:22&lt;/span&gt;&lt;span&gt; 3194&lt;/span&gt;&lt;span&gt; +25627400&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From a prior CTF competition, I already knew that GitHub was &lt;a href=&quot;https://github.com/l3rnds/Ft_IRC/commits/main/&quot;&gt;perfectly fine&lt;/a&gt; with future commit dates. I wasn’t sure why this was happening, so I replicated this commit on a test repository.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Test&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; git&lt;/span&gt;&lt;span&gt; commit&lt;/span&gt;&lt;span&gt; --allow-empty&lt;/span&gt;&lt;span&gt; -m&lt;/span&gt;&lt;span&gt; &quot;Testing&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Test&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; commit=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; rev-parse&lt;/span&gt;&lt;span&gt; HEAD&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Test&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; git&lt;/span&gt;&lt;span&gt; cat-file&lt;/span&gt;&lt;span&gt; commit&lt;/span&gt;&lt;span&gt; $commit &lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; commit.txt&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Test&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; vim&lt;/span&gt;&lt;span&gt; commit.txt&lt;/span&gt;&lt;span&gt; # change both timestamps to 38654734462000 +25627400&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Test&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; new_commit=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; hash-object&lt;/span&gt;&lt;span&gt; -t&lt;/span&gt;&lt;span&gt; commit&lt;/span&gt;&lt;span&gt; -w&lt;/span&gt;&lt;span&gt; commit.txt&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Test&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; git&lt;/span&gt;&lt;span&gt; update-ref&lt;/span&gt;&lt;span&gt; refs/heads/main&lt;/span&gt;&lt;span&gt; $new_commit&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Test&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; git&lt;/span&gt;&lt;span&gt; push&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These commands only work on Git v2.38.2 or earlier, don’t ask me how I know that.&lt;/p&gt;
&lt;p&gt;Sure enough, after pushing, my test repository also nuked itself in a similar fashion with the same error message. I was able to pinpoint this behavior to the invalid UTC offset on the commit date, a classic parsing oversight. I took this a step further and wanted to see what would happen if I opened a pull request referencing this commit. Feast your eyes on…&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/github-500.DIQZUGqW_2tH2iL.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/github-500.DIQZUGqW_1FoSON.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/github-500.DIQZUGqW_Z2iGFXY.png&quot; alt=&quot;GitHub throwing an internal server error&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;874&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;I really wish I could say I found a denial-of-service PoC and &lt;a href=&quot;https://hackerone.com/github#user-content-performing-your-research&quot;&gt;became $1,000 (or more) richer&lt;/a&gt;. Imagine how cool of a resolution that would sound! Like before, following triage with some of my friends, I surrendered empty-handed and filed a bug report to GitHub support.&lt;/p&gt;
&lt;p&gt;I would receive this response two days later.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hey Arhan,&lt;/p&gt;
&lt;p&gt;Thanks for getting in touch and flagging this. I take it you’ve been exploring
different ways to edit git commits manually and exploring how they behave on
GitHub? :)&lt;/p&gt;
&lt;p&gt;We’re not able to gracefully handle every possible sort of malformed/corrupted
commit that might occur, as much as we’d like to.&lt;/p&gt;
&lt;p&gt;Given the extensive steps required to achieve this outcome, it’s unlikely this
would be encountered as part of regular work when collaborating on GitHub.
Because of this, it’s unlikely that if I raised this with one of our engineering
teams that it’d be picked up to be worked on/improved.&lt;/p&gt;
&lt;p&gt;I hope you can understand why we’re not always able to work on all bug reports
we receive, but if you identify a way this occurs as part of regular activity,
please write back and let us know - we’d be happy to investigate further.&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Understandable, but nevertheless interesting.&lt;/p&gt;
&lt;h1&gt;100,000 Contributors&lt;/h1&gt;
&lt;p&gt;Where were we? Oh right, apologies for the side-tangents, I tend to get distracted. Now that we have all of our co-authors, let’s get the party started!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;everyone&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; scp&lt;/span&gt;&lt;span&gt; root@147.182.243.54:everyone/results.txt&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;everyone&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; echo&lt;/span&gt;&lt;span&gt; -e&lt;/span&gt;&lt;span&gt; &quot;👀\n\n&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;cat&lt;/span&gt;&lt;span&gt; results.txt&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; git&lt;/span&gt;&lt;span&gt; commit&lt;/span&gt;&lt;span&gt; --allow-empty&lt;/span&gt;&lt;span&gt; -F&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;everyone&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; git&lt;/span&gt;&lt;span&gt; push&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;Thirty minutes later, nothing happens.&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;Uh oh.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/commit-loading.DYNrnYw-_Zup0aK.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/commit-loading.DYNrnYw-_2mDzWv.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/commit-loading.DYNrnYw-_Z16b01x.png&quot; alt=&quot;A screenshot showing GitHub commits unable to load&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;235&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;I’m just messing with you, it wasn’t that dramatic. After force git-resetting, simply splitting up the co-authors into commits of 5,000 at a time did the trick.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;everyone.sh&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;split&lt;/span&gt;&lt;span&gt; -l&lt;/span&gt;&lt;span&gt; 5000&lt;/span&gt;&lt;span&gt; -a&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;span&gt; results.txt&lt;/span&gt;&lt;span&gt; split_&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;FIRST_ITERATION&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; split_*&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt; $FIRST_ITERATION &lt;/span&gt;&lt;span&gt;-eq&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; ];&lt;/span&gt;&lt;span&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        sleep&lt;/span&gt;&lt;span&gt; 120&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    fi&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    FIRST_ITERATION&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    echo&lt;/span&gt;&lt;span&gt; -e&lt;/span&gt;&lt;span&gt; &quot;👀\n\n&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;cat&lt;/span&gt;&lt;span&gt; $i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; git&lt;/span&gt;&lt;span&gt; commit&lt;/span&gt;&lt;span&gt; --allow-empty&lt;/span&gt;&lt;span&gt; -F&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    git&lt;/span&gt;&lt;span&gt; push&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;done&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;rm&lt;/span&gt;&lt;span&gt; split_&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &quot;Co-authors successfully processed!&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After running the script, around half an hour later:&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/100000-contributors.BVMj4dYa_1ocGCC.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/100000-contributors.BVMj4dYa_Z1PFbjQ.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/100000-contributors.BVMj4dYa_Zuj4q1.png&quot; alt=&quot;A screenshot showing 100,000 contributors&quot; loading=&quot;lazy&quot; width=&quot;750&quot; height=&quot;452&quot; /&gt;&lt;/picture&gt;&lt;div&gt;The last 14 contributors are on the icons up top&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Tada! *drops mic*&lt;/p&gt;
&lt;p&gt;Not bad for my second blog, don’t you think? Until next time!&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The situation here is strange. For reasons unknown, the GitHub GraphQL API straight up doesn’t expose the majority of users’ public emails… UNLESS you use the GitHub REST API; in which case only this method works… UNLESS you use the &lt;a href=&quot;https://docs.github.com/en/graphql/overview/explorer&quot;&gt;GitHub GraphQL explorer&lt;/a&gt; which seems to work with the same level of accuracy. I know I’m not going crazy. It’s really weird. &lt;a href=&quot;#fnref-graphql&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Hello World</title><link>https://arhan.sh/blog/hello-world/</link><guid isPermaLink="true">https://arhan.sh/blog/hello-world/</guid><description>Welcome to my blog!</description><pubDate>Sat, 04 May 2024 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When I was younger, I never had the confidence to think of myself as an interesting guy, let alone a writer. But my high school and now collegiate friends have slowly made me more cognizant of the fact that, when it comes to my nerdy interests, I LOVE to talk, typically to an intolerable degree. A day of reckoning later, I asked myself: what if I start a blog?&lt;/p&gt;
&lt;p&gt;I thought I would give a brief life update to honor my celebratory first blog post. I’ve just finished my first year as a Computer Science major at Purdue University! Over the past school year, I…&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/coding.D5i2GMma_Kd6Cx.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/coding.D5i2GMma_Z1F6mQE.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/coding.D5i2GMma_Z19d6G8.jpg&quot; alt=&quot;A picture of my coding setup&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;1200&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;I coded, a &lt;em&gt;lot&lt;/em&gt;. I showed off my hobby project &lt;a href=&quot;https://github.com/ArhanChaudhary/NAND&quot;&gt;NAND&lt;/a&gt; on Hacker News, and they &lt;a href=&quot;https://news.ycombinator.com/item?id=40159278&quot;&gt;really seamed to like it&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/video-games.viZfUAls_nkVWH.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/video-games.viZfUAls_Z1n6wjQ.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/video-games.viZfUAls_1M7660.jpg&quot; alt=&quot;A picture of me playing video games&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;600&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;I got back into video gaming.&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;picture&gt;&lt;source srcset=&quot;/_astro/skateboarding.DfP9qCL1_S20uq.avif&quot; type=&quot;image/avif&quot;&gt;&lt;/source&gt;&lt;source srcset=&quot;/_astro/skateboarding.DfP9qCL1_1toJtW.webp&quot; type=&quot;image/webp&quot;&gt;&lt;/source&gt;&lt;img src=&quot;/_astro/skateboarding.DfP9qCL1_Zv7vyy.jpg&quot; alt=&quot;A picture of my skateboard&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;600&quot; /&gt;&lt;/picture&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;I learned to skateboard and cut my commute time by two-thirds.&lt;/p&gt;
&lt;p&gt;And so much more!&lt;/p&gt;
&lt;p&gt;At the time of writing, the path forwards remains mostly unclear. One thing is for certain — this is far from the last time you’ll hear from me &amp;gt;:)&lt;/p&gt;</content:encoded></item></channel></rss>