<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Shenawy&apos;s Blog</title><description>All my thoughts</description><link>https://shenawy29.github.io/en/</link><language>en</language><atom:link href="https://shenawy29.github.io/en/rss.xml" rel="self" type="application/rss+xml" xmlns:atom="http://www.w3.org/2005/Atom"/><item><title>Why Neovim in the Age of Agentic Coding?</title><link>https://shenawy29.github.io/en/2026-07-16/nvim</link><guid isPermaLink="true">https://shenawy29.github.io/en/2026-07-16/nvim</guid><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I’ve been writing code for about 4 years now. In that time, I started like any CS student, with VSCode. If I wanted to write code, I’d type it like any other text. If I wanted to run my code, I’d hit a shortcut and VSCode would run it. I didn’t really understand how the code worked. I just knew it ran.&lt;/p&gt;
&lt;h2&gt;How Neovim and I met&lt;/h2&gt;
&lt;p&gt;A while ago, I started watching a YouTuber named ThePrimeagen. He was a Software Engineer at Netflix at the time, and every time I watched his streams on Twitch or YouTube, my eyes couldn’t keep up with what he was doing. Aside from his absurdly fast typing speed and his unusual keyboard (&lt;a href=&quot;https://en.wikipedia.org/wiki/Dvorak_keyboard_layout&quot;&gt;dvorak&lt;/a&gt;), that wasn’t the main reason he was fast. The main reason was his text editor: Neovim.&lt;/p&gt;
&lt;h2&gt;What is Neovim&lt;/h2&gt;
&lt;p&gt;In case you don’t know, Neovim is a fork of another text editor called Vim. Vim is very old, created in 1991. It was itself an improvement over an even older text editor called Vi.&lt;/p&gt;
&lt;p&gt;There used to be a war between Vim and Emacs, but those battles are mostly over, though they still linger in programming culture. If you Google “Vim” for example, it’ll ask “Did you mean emacs?”, and vice versa.&lt;/p&gt;
&lt;p&gt;Neovim runs in the terminal. This means there’s essentially no GUI, and it draws its UI on the terminal.&lt;/p&gt;
&lt;p&gt;For several reasons, Neovim is very fast. It starts in under 100ms depending on your CPU, even with dozens of plugins installed.&lt;/p&gt;
&lt;p&gt;Neovim is a modal text editor. You switch between different modes to do different things. You can’t just hold Shift and arrow down to make a selection; you need to enter Visual Selection Mode. If you want to type, you enter Insert Mode. If you want to navigate, you use Normal Mode. That’s why the learning curve can be a bit steep.&lt;/p&gt;
&lt;p&gt;The goal of this article isn’t to teach you how to use Neovim. There’s a saying: “You don’t know what you don’t know.” It sounds obvious, but it’s true. You would never try Neovim if no one told you about it, because you do not know it exists.&lt;/p&gt;
&lt;p&gt;It’s like someone who has only ever used a regular screwdriver; they wouldn’t think to ask about an electric screwdriver. The job gets done; that’s enough. It’s the same with Neovim: if you only use VSCode, you won’t know there’s a completely different way to write code, and you’ll keep thinking VSCode is the ultimate truth.&lt;/p&gt;
&lt;p&gt;And since I believe a picture is worth a thousand words, I decided to show you some things you can do with Neovim that are hard to do in other editors.&lt;/p&gt;
&lt;h2&gt;Practical Examples&lt;/h2&gt;
&lt;p&gt;Here’s something practical. You’ve probably needed something like this before, using Visual Block Mode to edit multiple lines at once:&lt;/p&gt;

&lt;p&gt;Or, for example, quickly changing if statements to a switch statement using the substitution command:&lt;/p&gt;

&lt;p&gt;You can also add new plugins. For instance, if you want to exchange function arguments, you can use the &lt;a href=&quot;https://github.com/nvim-mini/mini.ai&quot;&gt;&lt;code&gt;mini.ai&lt;/code&gt;&lt;/a&gt; plugin:&lt;/p&gt;

&lt;p&gt;There’s also a plugin called &lt;a href=&quot;https://github.com/folke/flash.nvim&quot;&gt;&lt;code&gt;flash.nvim&lt;/code&gt;&lt;/a&gt;. It lets you do remote operations, for example, you can go delete something somewhere else and come back to paste it where you were:&lt;/p&gt;

&lt;h2&gt;Any Agent Could Do This…&lt;/h2&gt;
&lt;p&gt;All these movements are really cool and make you fast and all. If you were to write a single prompt, all of these things could be done anyway. Of course, by the time you finish writing the prompt, it’d probably take longer than actually doing it yourself, but it would still get done, and you wouldn’t have to learn a new text editor from scratch.&lt;/p&gt;
&lt;p&gt;The benefits of Neovim are not about speed. That’s a big factor, but for me, it was not the biggest benefit.&lt;/p&gt;
&lt;p&gt;The biggest benefit is the ecosystem. Once you start using Vim motions, you will not want to use anything that does not support them. You’ll find them everywhere: your Browser (Vimium), your File Manager (ranger/lf/yazi), your Shell (&lt;code&gt;set -o vi&lt;/code&gt; in zsh/bash), tmux, git, and even other IDEs (VS Code Vim extension, JetBrains IDEAVim). They all support Vim motions. It’s one unified movement system for everything you do on your computer.&lt;/p&gt;
&lt;p&gt;Another benefit is that you get used to the CLI. You basically live in it; you start feeling like anything else is slow and bloated. You’ll be comfortable combining different CLI tools with pipes, managing sessions with tmux, searching and replacing with grep and sed, handling git quickly, working on remote servers over SSH without opening another application. The CLI gives you complete control over everything.&lt;/p&gt;
&lt;p&gt;Another thing is the community. Whatever you’re building, you’ll find massive support. I made &lt;a href=&quot;https://github.com/shenawy29/xdg-nvfilechooser.nvim&quot;&gt;xdg-nvfilechooser&lt;/a&gt;, for example, and even though the project isn’t complete, I got a lot of support because people liked the idea.&lt;/p&gt;
&lt;p&gt;There’s a big overlap between the Neovim community and other “cracked” programmer communities. You’ll often find that Neovim users are people with deep experience in their field. I’ve noticed this, and these are people you can actually learn from.&lt;/p&gt;
&lt;p&gt;For example, I would never have gotten good at Rust without &lt;a href=&quot;https://www.YouTube.com/c/JonGjengset&quot;&gt;Jon Gjengset&lt;/a&gt;’s YouTube channel and his books. Guess what editor he uses.&lt;/p&gt;
&lt;p&gt;There’s also &lt;a href=&quot;https://www.YouTube.com/@sphaerophoria&quot;&gt;sphaerophoria&lt;/a&gt;. He uses Zig and Rust all the time, and I don’t understand 99% of the code he writes because he’s on another level entirely. Guess his editor too.&lt;/p&gt;
&lt;p&gt;You’ll also find overlap between the Neovim community and Nix. If you don’t know, Nix is a Linux package manager. One resource that helped me was the &lt;a href=&quot;https://www.YouTube.com/@tweag&quot;&gt;Tweag&lt;/a&gt; YouTube channel. Guess their editor.&lt;/p&gt;
&lt;p&gt;This doesn’t mean that once you use and master Neovim, you’ll automatically become a code master with no equal. The point is that people who like using Neovim tend to have a certain mindset, and I enjoy learning from people with that mindset. They have passion, a love for what they do.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If you want to learn more about Neovim, I’d advise you not to start with the editor itself. Start with any extension that implements Vim motions in the editor you already use. Once you get used to it, you can dive into the text editor itself.&lt;/p&gt;</content:encoded></item><item><title>Enter the Arena</title><link>https://shenawy29.github.io/en/2026-07-12/arenas</link><guid isPermaLink="true">https://shenawy29.github.io/en/2026-07-12/arenas</guid><description>Manual Memory Management Without the Headache</description><pubDate>Sun, 12 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Why do we use Python? JavaScript? Java? Dart? Any first-year CS student can tell you these languages are slow compared to languages like C. If we want our software to run as fast as possible, why do we use these languages at all when we could just use C++ for everything?&lt;/p&gt;
&lt;p&gt;The answer is simple: ease of use. These languages are very easy to use, their syntax is simple, they read almost like English, they’re usually portable, and, most importantly, they’re garbage collected.&lt;/p&gt;
&lt;p&gt;Garbage collected means the coder doesn’t have to think about memory. They can (ironically) forget about it entirely. If I write a program that uses 100 kilobytes, I don’t need to &lt;code&gt;free&lt;/code&gt; that 100 kilobytes myself, because I know my language’s runtime will save me and free that memory at some point on its own.&lt;/p&gt;
&lt;p&gt;It wasn’t always like this. Most coders in the past had to use manual memory management. You’d tell the computer: I’m going to make an object. This object, all together, is 100 kilobytes. The computer’s only job is to hand you back that memory so you can put your data in it. It’s not the computer’s job to free that memory later, that’s on you.&lt;/p&gt;
&lt;p&gt;For this article, I’ll assume you already have some idea of what the heap, the stack, and &lt;code&gt;malloc&lt;/code&gt;/&lt;code&gt;free&lt;/code&gt; are.&lt;/p&gt;
&lt;h2&gt;Stack Based Allocations&lt;/h2&gt;
&lt;p&gt;When you first learn to program, you learn there are two ways to allocate memory: on the stack or on the heap. You probably learned that the stack is faster because memory sits contiguously, while the heap is slower because memory is scattered around. And that you use the heap when you don’t know ahead of time how big an object needs to be, that’s when you reach for dynamic memory. That’s not entirely accurate, you can easily use the stack for dynamic memory too as we’ll later see.&lt;/p&gt;
&lt;p&gt;Take a look at the code below:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; three&lt;/span&gt;&lt;span&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    e &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    f &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    g &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; two&lt;/span&gt;&lt;span&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    b &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    c &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; one&lt;/span&gt;&lt;span&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    a &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    two&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    one&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; __name__ &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 class=&quot;line&quot;&gt;&lt;span&gt;    main&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we look at Python’s bytecode for this on Godbolt, and focus on &lt;code&gt;three&lt;/code&gt;, we get this:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Disassembly of &amp;lt;code object three at &lt;/span&gt;&lt;span&gt;0x5676616f8980&lt;/span&gt;&lt;span&gt;, file &quot;example.py&quot;, line &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;&amp;gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  1&lt;/span&gt;&lt;span&gt;           RESUME                   &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  2&lt;/span&gt;&lt;span&gt;           LOAD_SMALL_INT           &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              STORE_FAST               &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; (e)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  3&lt;/span&gt;&lt;span&gt;           LOAD_SMALL_INT           &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              STORE_FAST               &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; (f)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  4&lt;/span&gt;&lt;span&gt;           LOAD_SMALL_INT           &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              STORE_FAST               &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; (g)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              LOAD_CONST               &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; (None)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              RETURN_VALUE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice there are 3 stores (allocations) but no deallocation at all. That’s because the whole stack frame gets torn down at once, and that counts as your deallocation.
&lt;img alt=&quot;Diagram of a call stack showing stack frames being deallocated automatically when a function returns&quot; src=&quot;/_astro/call_stack.MPyGQvZ0_2rALzP.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;All the variables we create get wiped out together, because the entire stack frame gets torn down together.&lt;/p&gt;
&lt;p&gt;So here’s a question: why don’t we just use the stack for everything? The stack is extremely efficient. It does a single allocation per object, and a single deallocation for all the objects at once, once the stack frame’s lifetime ends.&lt;/p&gt;
&lt;p&gt;The whole point isn’t really that we don’t want dynamic memory, dynamic memory is actually possible on the stack, through a C stdlib API called &lt;a href=&quot;https://man7.org/linux/man-pages/man3/alloca.3.html&quot;&gt;&lt;code&gt;alloca&lt;/code&gt;&lt;/a&gt;. What we actually want is for our memory to outlive the stack frame. We don’t want the memory we allocate to disappear the moment the function call ends.&lt;/p&gt;
&lt;h2&gt;Heap Based Allocations&lt;/h2&gt;
&lt;p&gt;On the other side, we have the heap. The usual way to allocate on the heap is through the C API &lt;code&gt;malloc&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Their API isn’t hard to understand, and the point of this article isn’t to teach you &lt;code&gt;malloc&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt;, it’s to teach you advanced memory allocation techniques.&lt;/p&gt;
&lt;p&gt;The idea behind &lt;code&gt;malloc&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt; is simple. Need memory? Ask for it with &lt;code&gt;malloc&lt;/code&gt;. Don’t need it anymore? Free it with &lt;code&gt;free&lt;/code&gt;. If you’re disciplined about this pattern, your program can never leak memory.&lt;/p&gt;
&lt;p&gt;This paradigm is nice. Every &lt;code&gt;malloc&lt;/code&gt; should be paired with a &lt;code&gt;free&lt;/code&gt;. But in practice, it’s not always this simple.&lt;/p&gt;
&lt;h3&gt;Manual Memory Management: Problems&lt;/h3&gt;
&lt;p&gt;Our friends in cybersecurity know that a big part of their field exists just to find code that misuses &lt;code&gt;malloc&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt;. Things like freeing memory twice (a double free), which can end up letting you write to memory that’s now been reallocated for something else entirely without you even realizing it. Or &lt;code&gt;malloc&lt;/code&gt;-ing a buffer that’s smaller than the data you’re about to put in it, so you write past the buffer’s bounds and corrupt whatever memory is next to it. So you really have to be careful when using this API.&lt;/p&gt;
&lt;p&gt;Even so, every &lt;code&gt;free&lt;/code&gt; still has to search for the right chunk of space, update its internal metadata, and deal with issues like fragmentation. In other words, even without a syscall, it’s still not a free operation.&lt;/p&gt;
&lt;p&gt;The fact that the operation can be somewhat expensive isn’t the only downside of this paradigm. If you have a graph made entirely of objects, figuring out which node to free first can be genuinely hard, especially if the graph is cyclic.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;A network of interconnected nodes in a chaotic pattern, each resembling a mesh sphere. Pink text at the top reads, &amp;quot;Which to free first?&amp;quot;&quot; src=&quot;/_astro/which.B1fqoHsn_1VXikb.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Even if you use the API perfectly, there’s still a cost you pay. The allocator might need to request fresh memory from the OS, which tends to be expensive since it usually involves a system call. But most modern allocators don’t make a syscall for every single &lt;code&gt;malloc&lt;/code&gt;. Instead, they request one big chunk of memory upfront, and then divide it up themselves across the smaller allocations your program asks for.&lt;/p&gt;
&lt;h3&gt;300,000 Rats&lt;/h3&gt;
&lt;p&gt;Imagine you’re building a game. Something like A Plague Tale: Requiem. &lt;a href=&quot;https://en.wikipedia.org/wiki/A_Plague_Tale:_Requiem#:~:text=The%20release%20of%20a%20new%20generation%20of%20consoles%20allowed%20the%20game%20to%20render%20more%20than%20300%2C000%20rats%20at%20once.&quot;&gt;It can have more than 300,000 rats on screen at once&lt;/a&gt;. Setting aside how hard that already is to render on the GPU, the CPU still needs to track each object individually for the rat’s own logic. In reality, not every rat is its own object (there’s merging involved most definitely) but let’s assume that in our hypothetical game, every rat has to be its own object.&lt;/p&gt;
&lt;p&gt;How would we create these objects? If we did 300,000 allocations one by one, we’d literally never finish in time. Now imagine there’s also an ability in the game that lets you kill every enemy on screen at once. When you kill them, they all disappear. Are we going to do 300,000 calls to &lt;code&gt;free&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;The better solution here: since these enemies are spawned all at once, and disappear all at once too, we should do a single allocation for all the enemies, and a single deallocation for all of them as well. Because these enemies’ entire lifespans are tied together. Their &lt;a href=&quot;https://en.wikipedia.org/wiki/Object_lifetime&quot;&gt;lifetimes&lt;/a&gt; are linked.&lt;/p&gt;
&lt;h2&gt;Lifetimes&lt;/h2&gt;
&lt;p&gt;Anyone who’s learned Rust probably just got PTSD flashbacks seeing that subtitle. We won’t go too deep into lifetimes since they’re a complicated topic, but let’s talk about them at a high level.&lt;/p&gt;
&lt;p&gt;Put simply: an object’s lifetime is the span of time during which that object is considered valid and usable.&lt;/p&gt;
&lt;p&gt;For example, I can’t use &lt;code&gt;a_1&lt;/code&gt; or &lt;code&gt;a_2&lt;/code&gt; after their scope (the closing bracket) ends.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; a_1 &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 class=&quot;line&quot;&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; a_2 &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;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; a_1 &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 class=&quot;line&quot;&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; a_2 &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;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// Invalid.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&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;a_1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Setting aside JavaScript’s own scoping quirks, this concept exists in pretty much every programming language today.&lt;/p&gt;
&lt;p&gt;If we want to create a new lifetime, we start a new scope. So we can track our lifetimes, let’s name them say, &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// lifetime a start&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; a_1 &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 class=&quot;line&quot;&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; a_2 &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;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// lifetime a end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// lifetime b start&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; b_1 &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 class=&quot;line&quot;&gt;&lt;span&gt;    let&lt;/span&gt;&lt;span&gt; b_2 &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;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// lifetime b end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice something? The two numbers inside each scope are tied to each other. Their lifetimes are linked. The moment both numbers go out of scope, we can discard them all at once, since neither one will outlive the other anyway. If one of the two numbers reaches the end of its lifetime, the other one necessarily has to end its lifetime too, because they were both created in the same scope.&lt;/p&gt;
&lt;p&gt;The stack works exactly this way, as we saw earlier. Every variable inside a stack frame has its lifetime tied to the lifetime of the frame itself.&lt;/p&gt;
&lt;p&gt;Here’s what we actually want: &lt;strong&gt;we want a way to tie the lifetimes of our objects together, the same way the stack does, avoid the headaches of &lt;code&gt;malloc&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt;, and still decide for ourselves exactly when that lifetime ends.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;The Arena Allocator&lt;/h2&gt;
&lt;p&gt;The solution to our problem is arena allocation. The whole idea is that you start by doing a single &lt;code&gt;malloc&lt;/code&gt; for one big buffer, and then you use that region to add your objects into. The objects can be of any type, and any size. And when you’re done with the arena, you just reset that memory in one go.&lt;/p&gt;
&lt;p&gt;There are many techniques for building arenas, we’ll implement the most well-known kind, called a bump allocator. We’ll use C.&lt;/p&gt;
&lt;h3&gt;The Arena Struct&lt;/h3&gt;
&lt;p&gt;This is the first thing we’ll build. All we need inside our struct is a buffer to hold our data, and we need to know the size of that buffer.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;include&lt;/span&gt;&lt;span&gt; &amp;lt;stddef.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;typedef&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Arena &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    unsigned&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; buffer&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    size_t&lt;/span&gt;&lt;span&gt; buffer_size&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; Arena&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; argc&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; argv&lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To create an arena, we need a function. We’ll call it &lt;code&gt;Arena_malloc&lt;/code&gt;, and it’ll return a pointer to the struct we’re creating.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Arena&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; Arena_malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size_t&lt;/span&gt;&lt;span&gt; buffer_size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // One malloc to create the struct.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Arena&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; arena &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Arena&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    arena&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_size &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; buffer_size&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // Another malloc to create the buffer.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    arena&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buffer_size&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; arena&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if we want to create a new arena, this is all it takes:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; argc&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; argv&lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Arena&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; Arena_malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1024&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates a buffer that’s 1024 bytes in size.&lt;/p&gt;
&lt;p&gt;Right now, the buffer looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Diagram of an empty 1024-byte arena allocator buffer before any memory has been allocated&quot; src=&quot;/_astro/buffer.CtKDk4Q8_ybNRo.webp&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Arena Allocation&lt;/h3&gt;
&lt;p&gt;Now, how do we actually use our arena?&lt;/p&gt;
&lt;p&gt;We’ll write another function called &lt;code&gt;Arena_allocate&lt;/code&gt;. All this function does is take a size parameter, and with that size, it places the memory we need into the buffer we’ve created.&lt;/p&gt;
&lt;p&gt;If, say, we go and allocate a struct called Player that’s 120 bytes, the buffer would end up looking like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Diagram of an arena allocator buffer after allocating a 120-byte Player struct&quot; src=&quot;/_astro/buffer_fill_2.pVgEg-Ta_2bD05a.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now we need something that tells us how full our buffer currently is. We’ll add a &lt;code&gt;buffer_offset&lt;/code&gt; field to the Arena struct.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;typedef&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Arena &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    size_t&lt;/span&gt;&lt;span&gt; buffer_offset&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; Arena&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;CPU Alignment&lt;/h3&gt;
&lt;p&gt;Now, there’s one more thing we need to learn: CPU alignment.&lt;/p&gt;
&lt;p&gt;CPUs like to read memory in a specific way. If you have an &lt;code&gt;int&lt;/code&gt; (usually 4 bytes), the address of its first byte needs to be an address divisible by 4.&lt;/p&gt;
&lt;p&gt;So if we picture our memory as addresses running from 0 to 1024, and we’ve used up to address 493, then the next address where we’re allowed to place our &lt;code&gt;int&lt;/code&gt; is 496, since that’s the nearest address divisible by 4.&lt;/p&gt;
&lt;p&gt;So what happens with the 3 addresses right after 493? We need to fill them with something, we fill them with what’s called padding.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Diagram of an arena buffer with padding bytes inserted to satisfy CPU memory alignment requirements&quot; src=&quot;/_astro/buffer_in_use.CUd3bYZc_ZEox3c.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So how do we calculate the alignment of our data types? You might think that since a data type’s address needs to be divisible by its size, we could just use &lt;code&gt;sizeof&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, it’s not quite that simple. Imagine you have something like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt; Player &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    char&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    int&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And our memory ends up looking like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;0    x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1    padding&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2    padding&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3    padding&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;4    y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;5    y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;7    y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;8    y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;sizeof&lt;/code&gt; on this struct gives us 8. But in reality, we need this struct’s address to start on an address divisible by 4.&lt;/p&gt;
&lt;p&gt;The general rule of thumb for alignment is that a struct’s alignment equals the size of the largest data type inside it, in this case, the largest data type is the &lt;code&gt;int&lt;/code&gt;, so the alignment is 4, meaning this struct needs to start on an address divisible by 4.&lt;/p&gt;
&lt;p&gt;Back to allocation. To allocate inside our buffer, we need to know both the size of the struct we’re allocating and its alignment, so we know exactly which address to place it at within our buffer.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; Arena_allocate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Arena&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; size_t&lt;/span&gt;&lt;span&gt; struct_size&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; size_t&lt;/span&gt;&lt;span&gt; struct_alignment&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need a better way to visualize our buffer. Our buffer doesn’t exist in memory all by itself.&lt;/p&gt;
&lt;p&gt;If, say, our memory is 4096 bytes total, and the buffer itself is 1024 bytes, it might look something like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Diagram showing a 1024-byte arena allocator buffer positioned within a larger 4096-byte memory allocation&quot; src=&quot;/_astro/actual.DPb0gfSQ_1jM682.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So, what do we actually need to do to allocate? We need to start from the very beginning of the buffer’s address, add the offset (how much of the buffer is already used), and also add padding, so the struct ends up properly aligned.&lt;/p&gt;
&lt;p&gt;The first thing we need to do is figure out, starting from the offset, how much we need to add to become aligned. Say our offset is 5, and the alignment is 4, we calculate &lt;code&gt;5 % 4 = 1&lt;/code&gt;. That means our current offset is 1 byte past the correct alignment. So, to reach the next valid alignment, we need to subtract that result from the alignment itself: &lt;code&gt;4 - 1 = 3&lt;/code&gt;. That means we need to add 3 bytes to our current offset to land on the correct address.&lt;/p&gt;
&lt;p&gt;But what happens if you’re already at a valid alignment? Say the offset is 8, and the alignment is 4. You’d calculate &lt;code&gt;8 % 4 = 0&lt;/code&gt;, and subtract that from the alignment, giving you &lt;code&gt;4&lt;/code&gt;, but that’s wrong. That’s why, at the very end, we need to take the mod of our result one more time: &lt;code&gt;4 % 4 = 0&lt;/code&gt;. And that’s our correct answer.&lt;/p&gt;
&lt;p&gt;The code ends up looking like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; Arena_allocate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Arena&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; size_t&lt;/span&gt;&lt;span&gt; struct_size&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; size_t&lt;/span&gt;&lt;span&gt; struct_alignment&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    size_t&lt;/span&gt;&lt;span&gt; padding &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        (&lt;/span&gt;&lt;span&gt;struct_alignment &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_offset &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt; struct_alignment&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        struct_alignment&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives us the padding needed to make the address aligned.&lt;/p&gt;
&lt;h3&gt;Arena Allocation: Continued&lt;/h3&gt;
&lt;p&gt;We want to make sure our struct will actually fit inside our arena. We check whether our offset plus the padding plus the struct’s own size is less than the arena’s total size.&lt;/p&gt;
&lt;p&gt;We’ll write this line:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_offset &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; padding &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; struct_size &lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; NULL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To calculate the address, we do some pointer arithmetic. We add the padding to the address of the buffer’s pointer. We also add the current offset, which tells us how much of the buffer we’ve already used.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; placement_address &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_offset &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; padding&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, we add the padding we just calculated to our offset, plus the size of the struct we’re adding.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_offset &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; padding &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; struct_size&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we return our address.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; placement_address&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here’s the complete implementation of the allocation function:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; Arena_allocate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Arena&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; size_t&lt;/span&gt;&lt;span&gt; struct_size&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; size_t&lt;/span&gt;&lt;span&gt; struct_alignment&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    size_t&lt;/span&gt;&lt;span&gt; padding &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        (&lt;/span&gt;&lt;span&gt;struct_alignment &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_offset &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt; struct_alignment&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        struct_alignment&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_offset &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; padding &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; struct_size &lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; NULL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    void&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; placement_address &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_offset &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; padding&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_offset &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; padding &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; struct_size&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; placement_address&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s it. That’s the whole implementation of our allocator.&lt;/p&gt;
&lt;h3&gt;Reset &amp;amp; Free&lt;/h3&gt;
&lt;p&gt;What do we do if we want to reuse our arena for something else? We’ll write another function called &lt;code&gt;Arena_reset&lt;/code&gt;. You’d probably expect this implementation to be complicated, but it’s not. Here’s the whole thing:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; Arena_reset&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Arena&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;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer_offset &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 class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Think about it this way: if we reset our offset back to zero, what happens? The next time we allocate, we’ll simply write over whatever data used to be there. You could think of it as treating our old data as garbage values, and just writing right over it.&lt;/p&gt;
&lt;p&gt;That said, we still haven’t freed the buffer’s memory itself. We need a function for that too.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; Arena_free&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Arena&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;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // Free the buffer owned by the arena first&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    free&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // Free the arena struct itself&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    free&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 class=&quot;line&quot;&gt;&lt;span&gt;    // `a` is now dangling.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Arena Usage&lt;/h3&gt;
&lt;p&gt;Now for the fun part, how do we actually use our arena? Imagine we’re building a game. On every frame of the game, we need to allocate some ammo, say, some bullets.&lt;/p&gt;
&lt;p&gt;The first thing we’ll do is create a struct called Bullet.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;typedef&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Bullet &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    float&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; Bullet&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we wanted to allocate one, we’d do something like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; argc&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; argv&lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Arena&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; Arena_malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1024&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Bullet&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;Bullet&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;Arena_allocate&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; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Bullet&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; _Alignof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Bullet&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    b&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;x &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 10.0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The odd-looking thing in this code is &lt;code&gt;_Alignof&lt;/code&gt;. It gives us the alignment of any type.&lt;/p&gt;
&lt;p&gt;We start by creating our arena, and &lt;code&gt;Arena_allocate&lt;/code&gt; gives us back an address inside the buffer as a &lt;code&gt;void*&lt;/code&gt;. All we need to do is cast that address to a pointer of our own type. What that’s really saying is: “I don’t want to treat this address as raw bytes anymore, this address is meant to hold the bytes of a &lt;code&gt;Bullet&lt;/code&gt; struct.”&lt;/p&gt;
&lt;p&gt;After that, we write the data we want into that address. In this case, we set &lt;code&gt;x&lt;/code&gt; to 10.0.&lt;/p&gt;
&lt;p&gt;Writing this code out is a bit annoying, so we can make a macro to make it easier to write.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;define&lt;/span&gt;&lt;span&gt; ARENA_ALLOCATE&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;arena&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;
&lt;span class=&quot;line&quot;&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;Arena_allocate&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;arena&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; sizeof&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; _Alignof&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 class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; argc&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; argv&lt;/span&gt;&lt;span&gt;[]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Arena&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; Arena_malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1024&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Bullet&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; ARENA_ALLOCATE&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; Bullet&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    b&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;x &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 10.0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let’s write our game loop.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Arena&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; Arena_malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;MAX_BULLETS &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Bullet&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; +&lt;/span&gt;&lt;span&gt; 64&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // so gcc doesn&apos;t optimize this out.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    volatile&lt;/span&gt;&lt;span&gt; float&lt;/span&gt;&lt;span&gt; sink &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 class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; frame &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; frame &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; FRAME_COUNT&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; frame&lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        int&lt;/span&gt;&lt;span&gt; bullet_count &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;frame &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt; MAX_BULLETS&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 class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        Bullet&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; bullets &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Bullet&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;Arena_allocate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Bullet&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt; bullet_count&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; _Alignof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Bullet&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;int&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; bullet_count&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 class=&quot;line&quot;&gt;&lt;span&gt;            bullets&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;x &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; 10.0&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            bullets&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;y &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; frame &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; 5.0&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        sink &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; bullets&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;bullet_count &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;x&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        Arena_reset&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 class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;done, sink = &lt;/span&gt;&lt;span&gt;%f&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; sink&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Arena_free&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 class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We create a single arena before the loop starts. On every frame, we allocate the bullets specific to that frame, use them, and then reset the arena at the end of the loop.&lt;/p&gt;
&lt;p&gt;Then, we reuse that same arena on the next frame.&lt;/p&gt;
&lt;h2&gt;Benchmark: Arena vs malloc&lt;/h2&gt;
&lt;p&gt;Now, let’s compare our allocator against &lt;code&gt;malloc&lt;/code&gt;. This is the exact same version, but using &lt;code&gt;malloc&lt;/code&gt; instead.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;include&lt;/span&gt;&lt;span&gt; &amp;lt;stddef.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;include&lt;/span&gt;&lt;span&gt; &amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;include&lt;/span&gt;&lt;span&gt; &amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;typedef&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; Bullet &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    float&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; Bullet&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;define&lt;/span&gt;&lt;span&gt; FRAME_COUNT&lt;/span&gt;&lt;span&gt; 2000000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;define&lt;/span&gt;&lt;span&gt; MAX_BULLETS&lt;/span&gt;&lt;span&gt; 50&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // same thing&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    volatile&lt;/span&gt;&lt;span&gt; float&lt;/span&gt;&lt;span&gt; sink &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 class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; frame &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; frame &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; FRAME_COUNT&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; frame&lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        int&lt;/span&gt;&lt;span&gt; bullet_count &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;frame &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt; MAX_BULLETS&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 class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        Bullet&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; bullets &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Bullet&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Bullet&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt; bullet_count&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;int&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; bullet_count&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 class=&quot;line&quot;&gt;&lt;span&gt;            bullets&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;x &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; 10.0&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            bullets&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;y &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; frame &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; 5.0&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        sink &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; bullets&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;bullet_count &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;x&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        free&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;bullets&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;done, sink = &lt;/span&gt;&lt;span&gt;%f&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; sink&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We’ll use &lt;a href=&quot;https://github.com/sharkdp/hyperfine&quot;&gt;&lt;code&gt;hyperfine&lt;/code&gt;&lt;/a&gt; to compare the two.&lt;/p&gt;
&lt;p&gt;Here are the compile commands we’ll use:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;gcc&lt;/span&gt;&lt;span&gt; -O2&lt;/span&gt;&lt;span&gt; -std=c11&lt;/span&gt;&lt;span&gt; -o&lt;/span&gt;&lt;span&gt; arena_bin&lt;/span&gt;&lt;span&gt; arena.c&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;gcc&lt;/span&gt;&lt;span&gt; -O2&lt;/span&gt;&lt;span&gt; -std=c11&lt;/span&gt;&lt;span&gt; -o&lt;/span&gt;&lt;span&gt; malloc_bin&lt;/span&gt;&lt;span&gt; malloc.c&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the run command:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;hyperfine&lt;/span&gt;&lt;span&gt; --warmup&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt; ./malloc_bin&lt;/span&gt;&lt;span&gt; ./arena_bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are our results:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Benchmark&lt;/span&gt;&lt;span&gt; 1:&lt;/span&gt;&lt;span&gt; ./malloc_bin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Time&lt;/span&gt;&lt;span&gt; (mean &lt;/span&gt;&lt;span&gt;±&lt;/span&gt;&lt;span&gt; σ&lt;/span&gt;&lt;span&gt;):      19.0 ms ±   1.9 ms    &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;User: &lt;/span&gt;&lt;span&gt;18.6&lt;/span&gt;&lt;span&gt; ms, System: &lt;/span&gt;&lt;span&gt;0.5&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Range&lt;/span&gt;&lt;span&gt; (min &lt;/span&gt;&lt;span&gt;…&lt;/span&gt;&lt;span&gt; max&lt;/span&gt;&lt;span&gt;):    17.9 ms …  36.8 ms    141 runs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Benchmark&lt;/span&gt;&lt;span&gt; 2:&lt;/span&gt;&lt;span&gt; ./arena_bin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Time&lt;/span&gt;&lt;span&gt; (mean &lt;/span&gt;&lt;span&gt;±&lt;/span&gt;&lt;span&gt; σ&lt;/span&gt;&lt;span&gt;):      10.0 ms ±   0.3 ms    &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;User: &lt;/span&gt;&lt;span&gt;9.7&lt;/span&gt;&lt;span&gt; ms, System: &lt;/span&gt;&lt;span&gt;0.5&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Range&lt;/span&gt;&lt;span&gt; (min &lt;/span&gt;&lt;span&gt;…&lt;/span&gt;&lt;span&gt; max&lt;/span&gt;&lt;span&gt;):     9.5 ms …  12.0 ms    244 runs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Summary&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  ./arena_bin&lt;/span&gt;&lt;span&gt; ran&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    1.90&lt;/span&gt;&lt;span&gt; ±&lt;/span&gt;&lt;span&gt; 0.20&lt;/span&gt;&lt;span&gt; times&lt;/span&gt;&lt;span&gt; faster&lt;/span&gt;&lt;span&gt; than&lt;/span&gt;&lt;span&gt; ./malloc_bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Credits&lt;/h3&gt;
&lt;p&gt;This article wouldn’t have been possible without &lt;a href=&quot;https://youtu.be/TZ5a3gCCZYo?si=CY3XiIMTV-CTSyyE&quot;&gt;this&lt;/a&gt; fantastic talk by Ryan Fleury.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=qTba8azvZQs&quot;&gt;This&lt;/a&gt; C++ implementation was also extremely helpful.&lt;/p&gt;</content:encoded></item><item><title>Imaginary Numbers Are Real</title><link>https://shenawy29.github.io/en/2026-03-23/imaginary</link><guid isPermaLink="true">https://shenawy29.github.io/en/2026-03-23/imaginary</guid><pubDate>Mon, 23 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Math as a field has existed since the beginning of history. From the moment humanity started building civilization, numbers existed, but not all the numbers we know today existed. We started with the integers: &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;,&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;,&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;,&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mo&gt;,&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;,&lt;/mo&gt;&lt;mi&gt;.&lt;/mi&gt;&lt;mi&gt;.&lt;/mi&gt;&lt;mi&gt;.&lt;/mi&gt;&lt;/mrow&gt;1, 2, 3, 4, 5, ...&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;These numbers were enough until we started running into problems calculating ratios. Around that time, fractional numbers, Fractions, came into existence to solve some of the problems we were facing.&lt;/p&gt;
&lt;p&gt;Later we discovered that not every number can be written as a fraction, like &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;\sqrt{2}&lt;/math&gt;&lt;/span&gt; for example. This period was a bit rough, because some cultures considered whole numbers sacred, believing that everything in the universe could be written as whole numbers and fractions.&lt;/p&gt;
&lt;h2&gt;The Evolution of Numbers&lt;/h2&gt;
&lt;p&gt;There’s an old story that tells of the Greeks, where a group followed a philosophical and religious school called the “Pythagoreans”. They discovered something that shocked them: the length of the diagonal of any square with a side length of 1 equals &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;\sqrt{2}&lt;/math&gt;&lt;/span&gt;. It can’t be written as a fraction. An irrational number. The person who discovered this was named “Hippasus”, and the story goes that the Pythagoreans killed him for saying so (most likely by drowning him).&lt;/p&gt;
&lt;p&gt;And this is the pattern we’ll keep seeing throughout this story: every time a new kind of number was discovered, people resisted it at first.&lt;/p&gt;
&lt;p&gt;After that, our next new invention of numbers was negative numbers and zero. These numbers also faced resistance, because if you really think about it: what does it even mean to have -5 of something?&lt;/p&gt;
&lt;p&gt;People tried as hard as they could to avoid writing anything as negative. So if you had, say, &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;a + b - c = 0&lt;/math&gt;&lt;/span&gt;, you’d write it as &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;/mrow&gt;a + b = c&lt;/math&gt;&lt;/span&gt; instead.&lt;/p&gt;
&lt;p&gt;I have 5 apples. There’s nothing in the universe that’s negative something of something.&lt;/p&gt;
&lt;p&gt;Anyway, that’s the new system of numbers we have. Positive numbers, negative numbers, irrational numbers, and zero.&lt;/p&gt;
&lt;h2&gt;The Equation&lt;/h2&gt;
&lt;p&gt;We stayed like this for a while. And mathematicians, as usual, kept solving more and more complex equations. Until one of them arrived at an equation that no one could solve with any existing numbers, and was left standing in front of it not knowing what to do. That equation was:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;f(x) = x^2 + 1&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now we have a problem. Roots are the values that, when you plug them into the equation, make the equation equal zero. Someone once proved this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Polynomials of degree &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mrow&gt;n&lt;/math&gt;&lt;/span&gt; have exactly &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mrow&gt;n&lt;/math&gt;&lt;/span&gt; roots.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This proof is so important that it was named the Fundamental Theorem of Algebra. They called it that because it’s one of the most important facts that all of algebra is built on.&lt;/p&gt;
&lt;p&gt;This proof says that this equation must have two numbers that make it equal zero. No argument.&lt;/p&gt;
&lt;p&gt;But if you look at the graph, you won’t find any point that equals zero. That means the Roots exist, just not among the numbers we know. That’s exactly the problem.&lt;/p&gt;
&lt;p&gt;If we look at the function, we won’t find any point where it equals zero.&lt;/p&gt;
&lt;p&gt;See how this function never touches the X axis at all:&lt;/p&gt;

&lt;p&gt;If we try to solve:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;x^2 + 1 = 0&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;x^2 = -1&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;±&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;x = \pm\sqrt{-1}&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We get some very strange numbers.&lt;/p&gt;
&lt;h2&gt;Imaginary Numbers&lt;/h2&gt;
&lt;p&gt;The root of negative one? Even worse, negative the root of negative one? Well, there are two solutions to the equation, but unfortunately neither one makes sense. These numbers kept showing up in mathematical solutions all the time. Some people got used to them, and others assumed that whenever these numbers showed up, it meant there was no solution to the equation they were solving.&lt;/p&gt;
&lt;p&gt;We called these numbers imaginary numbers. One of the worst names on the planet, because if you tell someone a number is “imaginary,” they’ll assume it “doesn’t exist” or that it’s some kind of hack you use just to solve your equations. Some people have suggested we call them “lateral numbers” or “elevated numbers” instead, for reasons that will become clear soon.&lt;/p&gt;
&lt;p&gt;Since these numbers keep showing up everywhere, what if we added them to our number system? It wouldn’t be the first time we’ve had to adjust our system. But we can’t just add anything willy-nilly. If these numbers are actually going to be useful, they need to obey the existing laws of algebra.&lt;/p&gt;
&lt;p&gt;With ordinary numbers, we can split up roots like this&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;/mrow&gt;\sqrt{2\times3} = \sqrt{2} \times \sqrt{3}&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Does that work for imaginary numbers?&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;25&lt;/mn&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;25&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;\sqrt{-25} = \sqrt{25}\times \sqrt{-1} = 5\sqrt{-1}&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;What about addition and subtraction?&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;2x + 3x = 5x&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;And for imaginary numbers?&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;2\sqrt{-1} + 3\sqrt{-1} = 5\sqrt{-1}&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It looks like our strange new numbers work perfectly fine with every mathematical operation we’ve tried. But how do we write them?&lt;/p&gt;
&lt;p&gt;People agreed on a way to write imaginary numbers. Every imaginary number can be written as a real number multiplied by &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;\sqrt{-1}&lt;/math&gt;&lt;/span&gt;. This number is so special that we gave it its own symbol: &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;i&lt;/math&gt;&lt;/span&gt;&lt;a href=&quot;#user-content-fn-1&quot;&gt;1&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The Complex Plane&lt;/h2&gt;
&lt;p&gt;Now, we want a way to add our numbers to the system so that we can write functions and graph them. We’ll sacrifice our Y axis and put our imaginary numbers on it like this:&lt;/p&gt;
&lt;p&gt;This is our new coordinate system, with real numbers on the horizontal axis and imaginary numbers on the vertical one:&lt;/p&gt;

&lt;p&gt;Notice something about this system.&lt;/p&gt;
&lt;p&gt;Take &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;1&lt;/math&gt;&lt;/span&gt; as an example. What happens if you multiply this number by &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;i&lt;/math&gt;&lt;/span&gt;, or by &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt; \sqrt{-1}&lt;/math&gt;&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;You’d get &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;1 \times \sqrt{-1}&lt;/math&gt;&lt;/span&gt;, which is &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;\sqrt{-1}&lt;/math&gt;&lt;/span&gt;. Now what if you multiply &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;\sqrt{-1}&lt;/math&gt;&lt;/span&gt; by &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;\sqrt{-1}&lt;/math&gt;&lt;/span&gt;? You’d get &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;\sqrt{-1}^2&lt;/math&gt;&lt;/span&gt;, which is -1. What if you do it again? You’d get -&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;\sqrt{-1}&lt;/math&gt;&lt;/span&gt;. Multiply once more and it goes back to 1.&lt;/p&gt;
&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;        &lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;       &lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;              &lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt; &lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;\begin{aligned}
1          &amp;amp;\times \sqrt{-1} &amp;amp;&amp;amp;\;\;\;\;= \sqrt{-1} \\
\sqrt{-1}  &amp;amp;\times \sqrt{-1} &amp;amp;&amp;amp;\:\;\;\;= -1 \\
-1         &amp;amp;\times \sqrt{-1} &amp;amp;&amp;amp;\;\;\;\;\;\;\;= -\sqrt{-1} \\
-\sqrt{-1} &amp;amp;\times \sqrt{-1} &amp;amp;&amp;amp;\,= 1
\end{aligned}&lt;/math&gt;&lt;/span&gt;
&lt;p&gt;In other words&lt;/p&gt;
&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;       &lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;      &lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt; &lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;\begin{aligned}
1          &amp;amp;\times i &amp;amp;&amp;amp;= i \\
i  &amp;amp;\times i &amp;amp;&amp;amp;\:\;\;\;= -1 \\
-1         &amp;amp;\times i &amp;amp;&amp;amp;\;\;\;= -i \\
-i &amp;amp;\times i &amp;amp;&amp;amp;\,= 1
\end{aligned}&lt;/math&gt;&lt;/span&gt;&lt;p&gt;or&lt;/p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;    &lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;    &lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;    &lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;\begin{aligned}
    i^1 =&amp;amp;\;\; i\\
    i^2 =&amp;amp; -1\\
    i^3 =&amp;amp; -i\\
    i^4 =&amp;amp;\;\;1\\
    i^5 =&amp;amp;\;\;i\\
\end{aligned}&lt;/math&gt;&lt;/span&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;.&lt;/mi&gt;&lt;mi&gt;.&lt;/mi&gt;&lt;mi&gt;.&lt;/mi&gt;&lt;/mrow&gt;...&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And this pattern repeats forever.&lt;/p&gt;
&lt;p&gt;See how multiplying by &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;i&lt;/math&gt;&lt;/span&gt; rotates the numbers in a full circle:&lt;/p&gt;

&lt;h2&gt;Complex Numbers&lt;/h2&gt;
&lt;p&gt;Now we have two kinds of numbers: real numbers, whose set is denoted &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;R&lt;/mi&gt;&lt;/mrow&gt;\Reals&lt;/math&gt;&lt;/span&gt;, and imaginary numbers, whose set is denoted &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;ℑ&lt;/mi&gt;&lt;/mrow&gt;\Im&lt;/math&gt;&lt;/span&gt;. The set of imaginary numbers looks a lot cooler, I know. And when we combine them together, we get a third kind called complex numbers, &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;C&lt;/mi&gt;&lt;/mrow&gt;\mathbb{C}&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;We found a way to combine these two sets by placing real numbers on the X axis and imaginary numbers on the Y axis. But how exactly do we place a point on this graph of ours?&lt;/p&gt;
&lt;p&gt;The notation everyone uses is to add the two numbers together. This makes the algebra for these numbers much easier.&lt;/p&gt;
&lt;p&gt;For example, if we want the point at &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;,&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;(2,3)&lt;/math&gt;&lt;/span&gt;, we’d write it as &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;2 + 3i&lt;/math&gt;&lt;/span&gt;. Combining a real number with an imaginary number like this gives you a &lt;strong&gt;complex&lt;/strong&gt; number.&lt;/p&gt;
&lt;p&gt;For example, the point &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;2 + 3i&lt;/math&gt;&lt;/span&gt; is placed on the graph like this:&lt;/p&gt;

&lt;h2&gt;Operations on Complex Numbers&lt;/h2&gt;
&lt;p&gt;Now that we know what complex numbers are, let’s look at how we work with them. We won’t be talking about real numbers alone, or imaginary numbers alone. We’ll talk about the complex whole, both parts together.&lt;/p&gt;
&lt;p&gt;The basic rule is simple: &lt;strong&gt;real with real, and imaginary with imaginary.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Addition&lt;/h3&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;(2 + 3i) + (1 + 2i)&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;= (2 + 1) + (3i + 2i)&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;= 3 + 5i&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Exactly like adding any two things of the same kind. Real numbers together, and imaginary numbers together.&lt;/p&gt;

&lt;h3&gt;Subtraction&lt;/h3&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;(5 + 4i) - (3 + 2i)&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;= (5 - 3) + (4i - 2i)&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;= 2 + 2i&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The exact same idea.&lt;/p&gt;

&lt;h3&gt;Multiplication&lt;/h3&gt;
&lt;p&gt;Multiplication is a bit more interesting. We multiply just like we would any two binomials, but we need to remember that &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;i^2 = -1&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;(2 + 3i)(1 + 2i)&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;= 2 + 4i + 3i + 6i^2&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;= 2 + 7i + 6(-1)&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;/mrow&gt;= 2 + 7i - 6&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;= -4 + 7i&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Notice that &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;6i^2&lt;/math&gt;&lt;/span&gt; turned into &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;/mrow&gt;-6&lt;/math&gt;&lt;/span&gt;, meaning an ordinary real number. This isn’t a mistake, this is exactly what’s supposed to happen. The imaginary and real numbers mix together during multiplication in a perfectly consistent way.&lt;/p&gt;

&lt;h2&gt;The Elephant in the Room&lt;/h2&gt;
&lt;p&gt;We now understand the basic operations on complex numbers. So here’s a question: where are the roots we were talking about &lt;a href=&quot;#eq&quot;&gt;here&lt;/a&gt;? If our equation is supposed to equal zero at two points, where are those two points?&lt;/p&gt;
&lt;p&gt;Look at our equation:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;f(x) = x^2 + 1&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;How many variables are in this equation of ours? We have one, &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;x&lt;/math&gt;&lt;/span&gt;, which is our input, and we have &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;f(x)&lt;/math&gt;&lt;/span&gt;, which is our output. If &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;x&lt;/math&gt;&lt;/span&gt; equals 2, for example, then &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;f(x)&lt;/math&gt;&lt;/span&gt; equals &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;2^2 + 1&lt;/math&gt;&lt;/span&gt;, which is &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;/mrow&gt;5&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;If we bring in our imaginary numbers, then we now have an extra variable. So the number of variables we have becomes 3. Two of them are input, and only one is output.&lt;/p&gt;
&lt;p&gt;Our function is now called a complex function, because it takes a complex number rather than a real one.&lt;/p&gt;
&lt;p&gt;To understand the idea, let’s take a simpler function as an example:&lt;/p&gt;
&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;/mrow&gt;f(x + iy) = x + 5&lt;/math&gt;&lt;/span&gt;
&lt;p&gt;Notice that our imaginary part is now &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;y&lt;/math&gt;&lt;/span&gt;, not &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;x&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;So how would we graph this function? First, let’s plug in a few numbers.&lt;/p&gt;
&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;8&lt;/mn&gt;&lt;/mrow&gt;\begin{aligned}
f(\textcolor{#4488ff}{0} + \textcolor{#ff4444}{0i}) &amp;amp;= \textcolor{#4488ff}{0} + 5 = \textcolor{#44cc88}{5} \\
f(\textcolor{#4488ff}{1} + \textcolor{#ff4444}{1i}) &amp;amp;= \textcolor{#4488ff}{1} + 5 = \textcolor{#44cc88}{6}  \\
f(\textcolor{#4488ff}{2} + \textcolor{#ff4444}{2i}) &amp;amp;= \textcolor{#4488ff}{2} + 5 = \textcolor{#44cc88}{7}   \\
f(\textcolor{#4488ff}{3} + \textcolor{#ff4444}{3i}) &amp;amp;= \textcolor{#4488ff}{3} + 5 = \textcolor{#44cc88}{8}
\end{aligned}&lt;/math&gt;&lt;/span&gt;
&lt;p&gt;As you can see, we have 3 numbers changing. 3 Variables. If we want to graph this function of ours, we’ll need to draw it as a 3D graph, and it’ll look like this:&lt;/p&gt;
x&lt;span class=&quot;slice-label3 x-label3&quot;&gt;x&lt;/span&gt;y&lt;span class=&quot;slice-label3 y-label3&quot;&gt;y&lt;/span&gt;
&lt;p&gt;Notice that the output of this function depends only on the real part, which is &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;x&lt;/math&gt;&lt;/span&gt;. No matter how much you change &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;y&lt;/math&gt;&lt;/span&gt;, the output won’t change, because the nature of this function’s output is that it depends only on the real part, even though it takes the imaginary part as input as well.&lt;/p&gt;
&lt;p&gt;Let’s go back to our original function, which we agreed would be &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;f(x + iy) = (x + iy)^2 + 1&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Let’s plug in numbers the same way we did with the previous function, but this time with some random numbers.&lt;/p&gt;
&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;12&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;10&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;40&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;\begin{alignedat}{2}
f(\textcolor{#4488ff}{2} + \textcolor{#ff4444}{1i}) &amp;amp;= (\textcolor{#4488ff}{2} + \textcolor{#ff4444}{1i})^2 + 1 &amp;amp;&amp;amp;= (\textcolor{#44cc88}{4} + \textcolor{#ffcc00}{4i}) \\
f(\textcolor{#4488ff}{1} + \textcolor{#ff4444}{3i}) &amp;amp;= (\textcolor{#4488ff}{1} + \textcolor{#ff4444}{3i})^2 + 1 &amp;amp;&amp;amp;= (\textcolor{#44cc88}{-7} + \textcolor{#ffcc00}{6i}) \\
f(\textcolor{#4488ff}{3} + \textcolor{#ff4444}{2i}) &amp;amp;= (\textcolor{#4488ff}{3} + \textcolor{#ff4444}{2i})^2 + 1 &amp;amp;&amp;amp;= (\textcolor{#44cc88}{6} + \textcolor{#ffcc00}{12i}) \\
f(\textcolor{#4488ff}{5} + \textcolor{#ff4444}{4i}) &amp;amp;= (\textcolor{#4488ff}{5} + \textcolor{#ff4444}{4i})^2 + 1 &amp;amp;&amp;amp;= (\textcolor{#44cc88}{10} + \textcolor{#ffcc00}{40i})
\end{alignedat}&lt;/math&gt;&lt;/span&gt;
&lt;p&gt;Now we have a problem. Our output is made up of two numbers, and our Input is made up of two numbers as well. That means these count as 4 Variables. In other words, we’d need 4 dimensions to graph this equation. Since we live in a three-dimensional world, we can’t graph this output of ours in a single drawing.&lt;/p&gt;
&lt;p&gt;Our solution is to “model” this output of ours into a single number that represents the distance from the origin.&lt;/p&gt;
&lt;p&gt;So instead of the equation with its output looking like this:&lt;/p&gt;
&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;\begin{alignedat}{2}
f(\textcolor{#4488ff}{1} + \textcolor{#ff4444}{3i}) &amp;amp;= (\textcolor{#4488ff}{1} + \textcolor{#ff4444}{3i})^2 + 1 &amp;amp;&amp;amp;= (\textcolor{#44cc88}{-7} + \textcolor{#ffcc00}{6i}) \\
\end{alignedat}&lt;/math&gt;&lt;/span&gt;
&lt;p&gt;It’ll look like this:&lt;/p&gt;
&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;85&lt;/mn&gt;&lt;/mrow&gt;\begin{aligned}
f(\textcolor{#4488ff}{1} + \textcolor{#ff4444}{3i})
&amp;amp;= (\textcolor{#4488ff}{1} + \textcolor{#ff4444}{3i})^2 + 1 \\
&amp;amp;= \sqrt{\textcolor{#44cc88}{-7}^2 + \textcolor{#ffcc00}{6}^2} \\
&amp;amp;= \textcolor{#44cc88}{\sqrt{85}}
\end{aligned}&lt;/math&gt;&lt;/span&gt;
&lt;p&gt;And just like that, our output is now a single number, and we have 3 variables we can graph.&lt;/p&gt;
&lt;p&gt;Just one small adjustment: instead of writing the function like this:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;f(x + iy) = (x + iy)^2 + 1&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;There’s a standard where we define &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt; z = x + iy&lt;/math&gt;&lt;/span&gt; and write it like this instead:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;f(z) = z^2 + 1&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And since the output of the function is a length, we’ll add the magnitude symbol:&lt;/p&gt;
&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;∣&lt;/mi&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mi&gt;∣&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;∣&lt;/mi&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;∣&lt;/mi&gt;&lt;/mrow&gt;|f(z)| = |z^2 + 1|&lt;/math&gt;&lt;/span&gt;
&lt;p&gt;That’s the complete transformation of our function.&lt;/p&gt;
&lt;p&gt;Notice now that our Imaginary axis is &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;y&lt;/math&gt;&lt;/span&gt;, not &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;x&lt;/math&gt;&lt;/span&gt; as it was in the original equation.&lt;/p&gt;
&lt;p&gt;Also notice that our whole equation equals zero when our real part, &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;x&lt;/math&gt;&lt;/span&gt;, equals zero, and our imaginary part, &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;y&lt;/math&gt;&lt;/span&gt;, equals &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;i&lt;/math&gt;&lt;/span&gt; or &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;-i&lt;/math&gt;&lt;/span&gt;, in other words, at the point &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;0 + i&lt;/math&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;0 -i&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
x&lt;span class=&quot;slice-label x-label&quot;&gt;x&lt;/span&gt;y&lt;span class=&quot;slice-label y-label&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;root-hint&quot;&gt;● Roots&lt;/span&gt;
&lt;h2 class=&quot;sr-only&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;You’ll sometimes see it written as &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;j&lt;/mi&gt;&lt;/mrow&gt;j&lt;/math&gt;&lt;/span&gt;, particularly in engineering fields, since &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;i&lt;/math&gt;&lt;/span&gt; is reserved for current. &lt;a href=&quot;#user-content-fnref-1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Vector Fields</title><link>https://shenawy29.github.io/en/2026-03-13/vectors</link><guid isPermaLink="true">https://shenawy29.github.io/en/2026-03-13/vectors</guid><pubDate>Fri, 13 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the most beautiful concepts in mathematics in general, and in vector calculus in particular, is vector fields. Vector fields represent many things: gravity, electromagnetic fields, and neural networks.&lt;/p&gt;
&lt;p&gt;Play around with the tool below. Try different numbers and see what results you get. You can choose from the presets if you need some inspiration.&lt;/p&gt;
fieldstreamRun&lt;span class=&quot;mr-1 font-mono text-xs text-[#727169]&quot;&gt;presets&lt;/span&gt;rotationsinksaddlesourcespiral outsine wavesgravitytwo vortices</content:encoded></item><item><title>Euler&apos;s Number</title><link>https://shenawy29.github.io/en/2026-03-06/euler</link><guid isPermaLink="true">https://shenawy29.github.io/en/2026-03-06/euler</guid><pubDate>Fri, 06 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Imagine you have a coin, and I tell you, “Give me this coin, and in a year I’ll give you &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;100&lt;/mn&gt;&lt;mi&gt;%&lt;/mi&gt;&lt;/mrow&gt;100\%&lt;/math&gt;&lt;/span&gt; of the value you put in.” That means in a year, you’ll get another coin.&lt;/p&gt;
&lt;p&gt;So after a year, you’ll have &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;1 + 1&lt;/math&gt;&lt;/span&gt; coins. Now, if I told you I wouldn’t give you the full &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;100&lt;/mn&gt;&lt;mi&gt;%&lt;/mi&gt;&lt;/mrow&gt;100\%&lt;/math&gt;&lt;/span&gt; right away, but would give you &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;50&lt;/mn&gt;&lt;mi&gt;%&lt;/mi&gt;&lt;/mrow&gt;50\%&lt;/math&gt;&lt;/span&gt; after 6 months, and another &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;50&lt;/mn&gt;&lt;mi&gt;%&lt;/mi&gt;&lt;/mrow&gt;50\%&lt;/math&gt;&lt;/span&gt; after another 6 months, how much would you have after a year?&lt;/p&gt;
&lt;p&gt;After 6 months, you’ll have&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.5&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1.5&lt;/mn&gt;&lt;/mrow&gt;1 \times 1.5 = 1.5&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And after the next 6 months, you’ll have&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1.5&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.5&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2.25&lt;/mn&gt;&lt;/mrow&gt;1.5 \times 1.5 = 2.25&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Okay, what if I said 3 months? That means you’ll get &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;25&lt;/mn&gt;&lt;mi&gt;%&lt;/mi&gt;&lt;/mrow&gt;25\%&lt;/math&gt;&lt;/span&gt; every 3 months until a year is up. How much will you have?&lt;/p&gt;
&lt;p&gt;After 3 months, you’ll have &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;/mrow&gt;1 \times 1.25&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;After 6 months, you’ll have &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;/mrow&gt;1\times 1.25 \times 1.25&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;After 9 months, it will be &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;/mrow&gt;1 \times 1.25 \times 1.25 \times 1.25&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;After 12 months, it will be &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;/mrow&gt;1 \times 1.25 \times 1.25 \times 1.25 \times 1.25&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We can see a pattern. Ultimately, the number will equal &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;/mrow&gt;1.25^4&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We can express &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;/mrow&gt;1.25&lt;/math&gt;&lt;/span&gt; as &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1.25&lt;/mn&gt;&lt;/mrow&gt;1 + 1.25&lt;/math&gt;&lt;/span&gt;, which is &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;/mrow&gt;(1 + \frac{1}{4})^4&lt;/math&gt;&lt;/span&gt;, and that equals &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;2.44140625&lt;/mn&gt;&lt;/mrow&gt;2.44140625&lt;/math&gt;&lt;/span&gt;. Notice that our amount grows every time we calculate our interest over a longer period.&lt;/p&gt;
&lt;p&gt;Suppose we want to do the same thing every month, every week, or every day, all the way down to every second and nanosecond, to get the largest possible value?&lt;/p&gt;
&lt;p&gt;Our formula will be &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mrow&gt;(1 + \frac{1}{n})^n&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;If we keep doing this forever and use a very large number—&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mn&gt;100000&lt;/mn&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;100000&lt;/mn&gt;&lt;/mrow&gt;(1 + \frac{1}{100000})^{100000}&lt;/math&gt;&lt;/span&gt;, for example—we’ll notice that our number approaches a specific value: &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mn&gt;2.71828&lt;/mn&gt;&lt;/mrow&gt;2.71828&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;It turns out that this number is so important that we’ve given it a special symbol: &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;/mrow&gt;e&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;One of the most interesting things about this number is that it has no end. As proof of this, I’d like to introduce you to Euler’s number.&lt;/p&gt;
&lt;h1&gt;&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;/mrow&gt;e&lt;/math&gt;&lt;/span&gt;&lt;/p&gt;&lt;/h1&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title>The Memory Canister is Leaking</title><link>https://shenawy29.github.io/en/2025-08-10/raii</link><guid isPermaLink="true">https://shenawy29.github.io/en/2025-08-10/raii</guid><pubDate>Sun, 10 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since most of the languages we use have some form of garbage collection, very few people actually think about memory in a practical way. Who cares when you call &lt;code&gt;new Foo()&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;You’re right. If you’re using a language like Java or Go, you probably don’t think about it much. However, if you’re using C++, it’s a different story. Any heap allocation you make with &lt;code&gt;new&lt;/code&gt; &lt;strong&gt;must&lt;/strong&gt; be freed with &lt;code&gt;delete&lt;/code&gt;. It’s simple, right? When I’m done with something, I delete it!&lt;/p&gt;
&lt;p&gt;Although the concept seems simple on the surface, humans are, by nature, fallible. Because of this, Microsoft says that &lt;a href=&quot;https://www.zdnet.com/article/microsoft-70-percent-of-all-security-bugs-are-memory-safety-issues/&quot;&gt;70% of the security bugs in its products are caused by memory-related bugs&lt;/a&gt;. Most of these bugs are caused by “use after free,” which means you use a &lt;code&gt;vector&lt;/code&gt; allocated with &lt;code&gt;new&lt;/code&gt;, for example, after you’ve called &lt;code&gt;delete&lt;/code&gt; on it.&lt;/p&gt;
&lt;p&gt;This in itself proves that the &lt;code&gt;new&lt;/code&gt; and &lt;code&gt;delete&lt;/code&gt; approach isn’t ideal, because even when you remember to call &lt;code&gt;delete&lt;/code&gt;, you might forget and accidentally use the memory you’ve already &lt;code&gt;delete&lt;/code&gt;d again!&lt;/p&gt;
&lt;p&gt;Languages with garbage collection don’t have these kinds of problems, but you pay another price: garbage collection itself.&lt;/p&gt;
&lt;p&gt;Yes, you probably won’t have memory bugs, but garbage collection itself isn’t free. The language’s runtime takes time to identify unused resources and free them up!&lt;/p&gt;
&lt;p&gt;Discord solved the garbage collection problem in their services (which use Go) by &lt;a href=&quot;https://discord.com/blog/why-discord-is-switching-from-go-to-rust&quot;&gt;adjusting the settings of the garbage collector itself&lt;/a&gt;, but they didn’t stick with that decision and chose to use a different language because the solution wasn’t ideal.&lt;/p&gt;
&lt;p&gt;So we have a problem. We want a language fast enough to meet our needs, but at the same time, we want to make it difficult to accidentally create vulnerabilities due to how we use memory.&lt;/p&gt;
&lt;h2&gt;RAII - Resource Acquisition Is Initialization&lt;/h2&gt;
&lt;p&gt;RAII. Resource Acquisition Is Initialization. It might be the worst name in the world, but it’s self-explanatory.&lt;/p&gt;
&lt;p&gt;To understand what RAII is and how to use it, we need to talk in somewhat abstract terms.&lt;/p&gt;
&lt;p&gt;If we think about what we do in most object-oriented languages, we declare variables and perform certain operations on them, whether they’re functions, methods, or whatever. But the key point is that we &lt;strong&gt;&lt;em&gt;can’t use something unless we give it a name&lt;/em&gt;&lt;/strong&gt;. The &lt;code&gt;vector&lt;/code&gt; we’re creating could be named &lt;code&gt;v&lt;/code&gt;, for example. How can we use something if it doesn’t exist in the program itself?&lt;/p&gt;
&lt;p&gt;RAII is based on this idea. Every “name” in the program is responsible for freeing the memory it uses.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;*&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this code, &lt;code&gt;x&lt;/code&gt; is the name, and it’s responsible for freeing the &lt;code&gt;vector&lt;/code&gt;’s memory.&lt;/p&gt;
&lt;p&gt;What about this?&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; y &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;p&gt;There’s a difference here.
The difference is that &lt;code&gt;x&lt;/code&gt; is responsible for freeing something allocated on the heap. Anything dynamically allocated with &lt;code&gt;new&lt;/code&gt; &lt;strong&gt;must&lt;/strong&gt; remain in its own memory location so it can survive beyond its scope.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;include&lt;/span&gt;&lt;span&gt; &amp;lt;vector&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; foo&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;*&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The vector’s memory won’t be freed after the function call finishes, because you’re using &lt;code&gt;new&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But here:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; foo&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    int&lt;/span&gt;&lt;span&gt; y &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 class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This variable is on the stack. It’s not dynamically allocated. We didn’t use &lt;code&gt;new&lt;/code&gt;, so its memory will be freed when the function call ends.&lt;/p&gt;
&lt;p&gt;RAII uses this concept for heap-allocated resources.&lt;/p&gt;
&lt;p&gt;As soon as its scope ends, for example, when the function call it’s in finishes, it’s responsible for freeing the memory associated with the resource it holds.&lt;/p&gt;
&lt;p&gt;So, how do we use RAII in C++? The Standard Library provides this capability in the &lt;code&gt;&amp;lt;memory&amp;gt;&lt;/code&gt; library. The basic type you can use is &lt;code&gt;unique_ptr&lt;/code&gt;. Its name might sound a bit suspicious, like RAII, but it actually explains exactly what it does. It is a pointer, yes, but a “unique” one, distinct in that it is &lt;strong&gt;the only entity responsible for freeing its own resource&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;include&lt;/span&gt;&lt;span&gt; &amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;include&lt;/span&gt;&lt;span&gt; &amp;lt;vector&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;include&lt;/span&gt;&lt;span&gt; &amp;lt;memory&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int&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 class=&quot;line&quot;&gt;&lt;span&gt;    std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;unique_ptr&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; vec &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;make_unique&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // The memory is freed here.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice there isn’t a single &lt;code&gt;new&lt;/code&gt; keyword in the code? Yet the &lt;code&gt;vector&lt;/code&gt; is indeed dynamically allocated.&lt;/p&gt;
&lt;p&gt;Want proof? Take a look at the assembly code.&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave has-focused&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        push&lt;/span&gt;&lt;span&gt;    rbp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        mov&lt;/span&gt;&lt;span&gt;     rbp&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;rsp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        push&lt;/span&gt;&lt;span&gt;    rbx&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        sub&lt;/span&gt;&lt;span&gt;     rsp&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        mov&lt;/span&gt;&lt;span&gt;     DWORD&lt;/span&gt;&lt;span&gt; PTR [&lt;/span&gt;&lt;span&gt;rbp&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;5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        lea&lt;/span&gt;&lt;span&gt;     rax&lt;/span&gt;&lt;span&gt;, [&lt;/span&gt;&lt;span&gt;rbp&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        lea&lt;/span&gt;&lt;span&gt;     rdx&lt;/span&gt;&lt;span&gt;, [&lt;/span&gt;&lt;span&gt;rbp&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;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        mov&lt;/span&gt;&lt;span&gt;     rsi&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;rdx&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        mov&lt;/span&gt;&lt;span&gt;     rdi&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;rax&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line focused&quot;&gt;&lt;span&gt;        call&lt;/span&gt;&lt;span&gt;    std&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;:_MakeUniq&amp;lt;&lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::vector&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::allocator&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt;::__single_object &lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::make_unique&amp;lt;&lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::vector&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::allocator&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;, &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        mov&lt;/span&gt;&lt;span&gt;     ebx&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        lea&lt;/span&gt;&lt;span&gt;     rax&lt;/span&gt;&lt;span&gt;, [&lt;/span&gt;&lt;span&gt;rbp&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        mov&lt;/span&gt;&lt;span&gt;     rdi&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;rax&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line focused&quot;&gt;&lt;span&gt;        call&lt;/span&gt;&lt;span&gt;    std&lt;/span&gt;&lt;span&gt;::unique_ptr&amp;lt;&lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::vector&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::allocator&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;, &lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::default_delete&amp;lt;&lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::vector&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::allocator&amp;lt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;::~unique_ptr() [complete object destructor] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        mov&lt;/span&gt;&lt;span&gt;     eax&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;ebx&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        mov&lt;/span&gt;&lt;span&gt;     rbx&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;QWORD&lt;/span&gt;&lt;span&gt; PTR [&lt;/span&gt;&lt;span&gt;rbp&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 class=&quot;line&quot;&gt;&lt;span&gt;        leave&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        ret&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;LC0&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        .string “cannot create &lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;::vector larger than max_size()”&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’ll notice that the second line uses something called &lt;code&gt;std::default_delete&lt;/code&gt;. If we look at the &lt;a href=&quot;https://en.cppreference.com/w/cpp/memory/default_delete.html&quot;&gt;Documentation&lt;/a&gt;, we’ll find that it says this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The non-specialized &lt;code&gt;default_delete&lt;/code&gt; uses &lt;code&gt;delete&lt;/code&gt; to deallocate memory for a single object&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This means that since this type uses &lt;code&gt;delete&lt;/code&gt;, the resource is dynamically allocated!&lt;/p&gt;
&lt;p&gt;Here, we were assuming we’re using dynamic memory on the heap. However, you can use it in a more general way. For example, a file you’ve used and want to close when you no longer need it.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The goal of this post is to further illustrate the concept of RAII, but there are many things I haven’t covered. Suppose I want a single user to own a single resource and need that resource to be used in multiple places?&lt;/p&gt;
&lt;p&gt;In that case, you’d use &lt;a href=&quot;https://en.cppreference.com/w/cpp/memory/shared_ptr.html&quot;&gt;&lt;code&gt;shared_ptr&lt;/code&gt;&lt;/a&gt;. This type uses a technique called &lt;a href=&quot;https://en.wikipedia.org/wiki/Reference_counting&quot;&gt;Reference Counting&lt;/a&gt;. Keep in mind that this technique is relatively slow!&lt;/p&gt;
&lt;p&gt;Fun Fact: Every object you create in Python uses Reference Counting by default to determine when the object’s memory should be freed!&lt;/p&gt;</content:encoded></item><item><title>Hello World!</title><link>https://shenawy29.github.io/en/2025-08-09/astro</link><guid isPermaLink="true">https://shenawy29.github.io/en/2025-08-09/astro</guid><pubDate>Sat, 09 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;If a hammer is all you have, everything looks like a nail&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This will probably be the first post on this blog.&lt;/p&gt;
&lt;p&gt;If you ask most people to build a simple website, they’ll slowly gravitate toward React&lt;a href=&quot;#user-content-fn-1&quot;&gt;1&lt;/a&gt;, Angular, Vue, or one of the million other frameworks currently available.&lt;/p&gt;
&lt;p&gt;Honestly, when I first thought about starting this blog, I turned to what I knew best: React. But then I thought about it a bit more and remembered reading about Astro. It’s designed for static sites, the kind that don’t require much interactivity.&lt;/p&gt;
&lt;p&gt;Before I started, I had a few specific requirements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The site needs to be fast. I’m literally not building anything amazing that would make it slow. It’s just HTML and CSS, nothing more.&lt;/li&gt;
&lt;li&gt;Writing posts needs to be easy. If writing posts is difficult, I won’t feel motivated to write.&lt;/li&gt;
&lt;li&gt;I need to build it quickly. I don’t want to start from scratch, but I do want to get things done!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I’m not going to explain Astro itself. If you want to learn more about it, the &lt;a href=&quot;https://docs.astro.build/en/getting-started/&quot;&gt;documentation&lt;/a&gt; explains it much better than I can. However, I’ll explain how Astro solves the problems I mentioned above.&lt;/p&gt;
&lt;h2&gt;Fast&lt;/h2&gt;
&lt;p&gt;If you’re building a static site, you probably don’t need JavaScript. Or, to be more precise, the client doesn’t need JavaScript.&lt;/p&gt;
&lt;p&gt;Astro is fast because, by default, it doesn’t send any JavaScript to the client. However, Astro works as a compiler. You write everything you want in &lt;code&gt;.astro&lt;/code&gt; files, and in the end, this is converted into a small HTML file that’s sent to the client.&lt;/p&gt;
&lt;p&gt;For example, take a look at this code. It’s the code that fetches all the posts on the &lt;a href=&quot;/tags&quot;&gt;&lt;code&gt;/tags&lt;/code&gt;&lt;/a&gt; page. It’s empty right now, but it’ll fill up (hopefully).&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import &lt;/span&gt;&lt;span&gt;BaseLayout&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; &quot;$lib/layouts/base_layout.astro&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; getCollection&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; &quot;astro:content&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; pages &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; getCollection&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;posts&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; tagMap &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; new&lt;/span&gt;&lt;span&gt; Map&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; page &lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt; pages&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; tag &lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt; page&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;tags&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;tagMap&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;has&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;tag&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            tagMap&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;tag&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; []);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        tagMap&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;tag&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;page&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; uniqueTags &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt;tagMap&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;keys&lt;/span&gt;&lt;span&gt;()];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;BaseLayout&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;lt;&lt;/span&gt;&lt;span&gt;h1&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;Tags&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;h1&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        uniqueTags&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;tag&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 class=&quot;line&quot;&gt;&lt;span&gt;            &amp;lt;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;lt;&lt;/span&gt;&lt;span&gt;h2&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;tag&lt;/span&gt;&lt;span&gt;}&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    &amp;lt;&lt;/span&gt;&lt;span&gt;span&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;tag&lt;/span&gt;&lt;span&gt;}&amp;lt;/&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;lt;/&lt;/span&gt;&lt;span&gt;h2&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;lt;&lt;/span&gt;&lt;span&gt;ul&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    {&lt;/span&gt;&lt;span&gt;tagMap&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;tag&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;post&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 class=&quot;line&quot;&gt;&lt;span&gt;                        &amp;lt;&lt;/span&gt;&lt;span&gt;li&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                            &amp;lt;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                href&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;`/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;post&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;pubDate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toISOString&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;substring&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; 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;${&lt;/span&gt;&lt;span&gt;post&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 class=&quot;line&quot;&gt;&lt;span&gt;                            &amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                &amp;lt;&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                    {&lt;/span&gt;&lt;span&gt;post&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;pubDate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                        .&lt;/span&gt;&lt;span&gt;toISOString&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                        .&lt;/span&gt;&lt;span&gt;substring&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; 10&lt;/span&gt;&lt;span&gt;)}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                &amp;lt;/&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                &amp;lt;&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                &amp;lt;&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;{&lt;/span&gt;&lt;span&gt;post&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;title&lt;/span&gt;&lt;span&gt;}&amp;lt;/&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                            &amp;lt;/&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                        &amp;lt;/&lt;/span&gt;&lt;span&gt;li&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    ))}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;lt;/&lt;/span&gt;&lt;span&gt;ul&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &amp;lt;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        ))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;BaseLayout&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What is this? Are you kidding me?! This is JavaScript! And what’s this, too? Two nested for loops!&lt;/p&gt;
&lt;p&gt;This is &lt;span class=&quot;katex&quot;&gt;&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;O&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;O(n \times t)&lt;/math&gt;&lt;/span&gt;!&lt;a href=&quot;#user-content-fn-2&quot;&gt;2&lt;/a&gt; How could this possibly be fast?&lt;/p&gt;
&lt;p&gt;You’re right… this isn’t exactly efficient… if it were executed at runtime. The idea is that Astro sees this code and converts everything to static HTML. Ultimately, it compiles the JavaScript you write and converts it to HTML &amp;amp; CSS. This way, Astro preserves the DX by letting you write in a scripting language, while at the same time preventing the client from sending it things it doesn’t need!&lt;/p&gt;
&lt;p&gt;This contrasts with the concept behind popular frontend frameworks, where a single HTML page is dynamically updated by JavaScript (these are &lt;a href=&quot;https://en.wikipedia.org/wiki/Single-page_application&quot;&gt;Single-Page Applications&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Don’t believe me? Check the Network tab in Chrome DevTools. There aren’t even any JavaScript resources.&lt;/p&gt;
&lt;h2&gt;Writing Posts Made Easy&lt;/h2&gt;
&lt;p&gt;One of the easiest languages you can use and learn &lt;a href=&quot;https://www.markdownguide.org/basic-syntax/&quot;&gt;in literally an hour&lt;/a&gt; is Markdown. It’s also one of the least known languages in terms of syntax, I don’t know why. It feels like everyone collectively decided decided to write their README files using AI.&lt;/p&gt;
&lt;p&gt;Most of the time, you’ll write your content in Markdown in Astro, and that Markdown will eventually be converted to HTML so your browser can read it.&lt;/p&gt;
&lt;p&gt;Why not just write in HTML from the start? You can do that, sure, but you’re basically punishing yourself. If given the choice, would you want to write this:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;lt;!&lt;/span&gt;&lt;span&gt;doctype&lt;/span&gt;&lt;span&gt; html&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;html&lt;/span&gt;&lt;span&gt; lang&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;en&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;lt;&lt;/span&gt;&lt;span&gt;head&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;lt;&lt;/span&gt;&lt;span&gt;meta&lt;/span&gt;&lt;span&gt; charset&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;lt;&lt;/span&gt;&lt;span&gt;meta&lt;/span&gt;&lt;span&gt; name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;viewport&quot;&lt;/span&gt;&lt;span&gt; content&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;width=device-width, initial-scale=1&quot;&lt;/span&gt;&lt;span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;lt;&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;lt;/&lt;/span&gt;&lt;span&gt;head&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;lt;&lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;lt;&lt;/span&gt;&lt;span&gt;h1&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;Hello, World!&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;h1&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;lt;/&lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;html&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or this?&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt; Hello, World!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Quick DX&lt;/h2&gt;
&lt;p&gt;I’m not a fan of building UIs. For me, it’s the most tedious part of writing any software. So I use tools that make it easier for me whenever I get the chance, and the first one I usually turn to is &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Another thing I might use is any component library that uses Tailwind. If I were using React or Next.js, I’d probably choose &lt;a href=&quot;https://ui.shadcn.com/&quot;&gt;ShadCn&lt;/a&gt;, but I had a specific vision for how the blog would look, and unfortunately, I couldn’t find anything that matched exactly what I wanted and didn’t use JavaScript, so I had to write my own components from scratch (yikes).&lt;/p&gt;
&lt;p&gt;It wasn’t too hard, though, because Astro also lets you create your own components. Any &lt;code&gt;.astro&lt;/code&gt; file is considered a component from Astro’s perspective.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; post &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; Astro&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;props&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;w-full&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;lt;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;flex flex-wrap gap-x-3 divide-dotted text-xl text-wrap opacity-70&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;lt;&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt; class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;text-wrap&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            {&lt;/span&gt;&lt;span&gt;post&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;pubDate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toISOString&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;substring&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; 10&lt;/span&gt;&lt;span&gt;)}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;lt;/&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            post&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;tags&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;t&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 class=&quot;line&quot;&gt;&lt;span&gt;                &amp;lt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    &amp;lt;&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; • &lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    &amp;lt;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt; href&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;`/tags#&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;t&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 class=&quot;line&quot;&gt;&lt;span&gt;                        &amp;lt;&lt;/span&gt;&lt;span&gt;span&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;t&lt;/span&gt;&lt;span&gt;}&amp;lt;/&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    &amp;lt;/&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                &amp;lt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            ))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;lt;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;lt;&lt;/span&gt;&lt;span&gt;h1&lt;/span&gt;&lt;span&gt; class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;mb-0&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;lt;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            href&lt;/span&gt;&lt;span&gt;={&lt;/span&gt;&lt;span&gt;`/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;post&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;pubDate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toISOString&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;substring&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; 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;${&lt;/span&gt;&lt;span&gt;post&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 class=&quot;line&quot;&gt;&lt;span&gt;        &amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            {&lt;/span&gt;&lt;span&gt;post&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;title&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        &amp;lt;/&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;lt;/&lt;/span&gt;&lt;span&gt;h1&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;lt;&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt; class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;italic&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;{&lt;/span&gt;&lt;span&gt;post&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;subtitle&lt;/span&gt;&lt;span&gt;}&amp;lt;/&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the code that displays the Title, Subtitle, Date, and Tags for each post. The component takes a &lt;code&gt;Post&lt;/code&gt; prop and renders this information based on each post.&lt;/p&gt;
&lt;p&gt;You can use it like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code kanagawa-wave has-highlighted&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; getCollection&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; &quot;astro:content&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span&gt;import &lt;/span&gt;&lt;span&gt;PostHeader&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; &quot;./post-header.astro&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; allPosts &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; await&lt;/span&gt;&lt;span&gt; getCollection&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;posts&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;flex h-full w-full flex-col gap-y-12&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        allPosts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span&gt;sort&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&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; b&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;pubDate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getTime&lt;/span&gt;&lt;span&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;data&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;pubDate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getTime&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;post&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 class=&quot;line highlighted&quot;&gt;&lt;span&gt;                &amp;lt;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;flex flex-col&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;{&amp;lt;&lt;/span&gt;&lt;span&gt;PostHeader&lt;/span&gt;&lt;span&gt; post&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;post&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; /&amp;gt;}&amp;lt;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            ))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You use it just like any other component you’ve used in your life (most likely).&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Astro isn’t the only Static Site Generator. There’s also &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;, &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;11ty&lt;/a&gt;, &lt;a href=&quot;https://gohugo.io/&quot;&gt;Hugo&lt;/a&gt;, and others. Of course, I haven’t used them all, and I might very well end up liking an SSG other than Astro, but it’s hard to imagine a developer experience (DX) easier than Astro’s.&lt;/p&gt;
&lt;p&gt;I hope I’ve encouraged you to use Astro for a project, and if you do use it because of this post, send me a link!&lt;/p&gt;
&lt;h2 class=&quot;sr-only&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;React is a library, not a framework… I know… I know. &lt;a href=&quot;#user-content-fnref-1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The “O” looks cool, right? These are Astro plugins &lt;a href=&quot;https://docs.astro.build/en/guides/markdown-content/#markdown-plugins&quot;&gt;that it supports&lt;/a&gt;: &lt;a href=&quot;https://github.com/remarkjs/remark-math/tree/main/packages/remark-math&quot;&gt;remark-math&lt;/a&gt; and &lt;a href=&quot;https://github.com/remarkjs/remark-math/tree/main/packages/rehype-katex&quot;&gt;rehype-katex&lt;/a&gt;. Astro also &lt;a href=&quot;https://docs.astro.build/en/guides/syntax-highlighting/&quot;&gt;supports syntax highlighting&lt;/a&gt; for code using &lt;a href=&quot;https://shiki.style/&quot;&gt;Shiki&lt;/a&gt; and &lt;a href=&quot;https://prismjs.com/&quot;&gt;Prism&lt;/a&gt;. &lt;a href=&quot;#user-content-fnref-2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item></channel></rss>