This commit is contained in:
lavafroth
2025-11-02 16:06:58 +00:00
parent 3b0e588b12
commit 1e73958ac5
33 changed files with 126 additions and 21 deletions

View File

@@ -1,4 +1,8 @@
<!doctype html><html lang=en-us><head><meta name=generator content="Hugo 0.152.2"><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=./header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=./about/ aria-label=about style=--url:url(./about.svg)></a><a href=./art/ aria-label=art style=--url:url(./art.svg)></a><a href=./index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=./pagefind/pagefind-ui.css rel=stylesheet><script src=./pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/><h2>Algebraic Python Enums</h2></a><time>Nov 2, 2025 | 2 minutes read</time><br><a class=post-link aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/></a></article><article><a aria-label="NixOS Notes to Self" href=https://lavafroth.is-a.dev/post/nixos-notes-to-self/><h2>NixOS Notes to Self</h2></a><time>Sep 14, 2025 | 1 minute read</time><br><a href=https://lavafroth.is-a.dev/tags/nix class=list-tag>Nix</a>
<!doctype html><html lang=en-us><head><meta name=generator content="Hugo 0.152.2"><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=./header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=./about/ aria-label=about style=--url:url(./about.svg)></a><a href=./art/ aria-label=art style=--url:url(./art.svg)></a><a href=./index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=./pagefind/pagefind-ui.css rel=stylesheet><script src=./pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/><h2>Algebraic Python Enums</h2></a><time>Nov 2, 2025 | 4 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/python class=list-tag>Python</a>
<a href=https://lavafroth.is-a.dev/tags/decorators class=list-tag>Decorators</a>
<a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/algebraic-data-types class=list-tag>Algebraic Data Types</a>
<a class=post-link aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/></a></article><article><a aria-label="NixOS Notes to Self" href=https://lavafroth.is-a.dev/post/nixos-notes-to-self/><h2>NixOS Notes to Self</h2></a><time>Sep 14, 2025 | 1 minute read</time><br><a href=https://lavafroth.is-a.dev/tags/nix class=list-tag>Nix</a>
<a href=https://lavafroth.is-a.dev/tags/nixos class=list-tag>NixOS</a>
<a href=https://lavafroth.is-a.dev/tags/notes class=list-tag>Notes</a>
<a href=https://lavafroth.is-a.dev/tags/troubleshooting class=list-tag>Troubleshooting</a>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1 @@
{"version":"1.0.3","languages":{"en-us":{"hash":"en-us_d717ded6be9d8","wasm":"en-us","page_count":58}}}
{"version":"1.0.3","languages":{"en-us":{"hash":"en-us_7676eaf26e26a","wasm":"en-us","page_count":58}}}

Binary file not shown.

View File

@@ -1,6 +1,8 @@
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Algebraic Python Enums - lavafroth</title><meta name=description content='As much as I like rust for its ergonomic features, University has forced me to use Python for the past couple of months, especially because of the hype for machine learning and data science.
One of the biggest things that I missed from the rust experience was enumerable data types whose variants can wrap around different datatypes.
Fortunately, since Python 3.8, creating structs has been a breeze using the dataclass decorator. There&rsquo;s even support for structural match expressions, like in rust, in recent versions of Python. https://peps.python.org/pep-0636/'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><hgroup data-pagefind-body><p data-pagefind-ignore><time>Nov 2, 2025 | 2 minutes read</time></p><h1 data-pagefind-meta=title>Algebraic Python Enums</h1></hgroup><section class=post-content data-pagefind-body><p>As much as I like rust for its ergonomic features, University has forced me to use Python for the past couple of months, especially because of the hype for machine learning and data science.</p><p>One of the biggest things that I missed from the rust experience was enumerable data types whose variants can wrap around different datatypes.</p><p>Fortunately, since Python 3.8, creating structs has been a breeze using the dataclass decorator. There&rsquo;s even support for structural match expressions, like in rust, in recent versions of Python. <a href=https://peps.python.org/pep-0636/>https://peps.python.org/pep-0636/</a></p><p>To that end, creating the equivalent to Rust&rsquo;s enum types involves Python union types.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#f92672>from</span> dataclasses <span style=color:#f92672>import</span> dataclass
Fortunately, since Python 3.8, creating structs has been a breeze using the dataclass decorator. There&rsquo;s even support for structural match expressions, like in rust, in recent versions of Python. https://peps.python.org/pep-0636/'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><hgroup data-pagefind-body><p data-pagefind-ignore><time>Nov 2, 2025 | 4 minutes read</time></p><h1 data-pagefind-meta=title>Algebraic Python Enums</h1></hgroup><section class=post-content data-pagefind-body><p>As much as I like rust for its ergonomic features, University has forced me to use Python for the past couple of months, especially because of the hype for machine learning and data science.</p><p>One of the biggest things that I missed from the rust experience was enumerable data types whose variants can wrap around different datatypes.</p><p>Fortunately, since Python 3.8, creating structs has been a breeze using the dataclass decorator. There&rsquo;s even support for structural match expressions, like in rust, in recent versions of Python. <a href=https://peps.python.org/pep-0636/>https://peps.python.org/pep-0636/</a></p><p>To that end, creating the equivalent to Rust&rsquo;s enum types involves Python union types.</p><h2 id=first-draft>First draft</h2><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#75715e># glass_enum.py</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#f92672>from</span> dataclasses <span style=color:#f92672>import</span> dataclass
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#a6e22e>@dataclass</span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>class</span> <span style=color:#a6e22e>Empty</span>:
@@ -11,11 +13,76 @@ Fortunately, since Python 3.8, creating structs has been a breeze using the data
</span></span><span style=display:flex><span> drink: str
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>Glass <span style=color:#f92672>=</span> Empty <span style=color:#f92672>|</span> Full
</span></span></code></pre></div><p>This allows us to define functions that ingest the <code>Glass</code> datatype.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>report_drink</span>(glass: Glass):
</span></span></code></pre></div><p>This allows us to define functions that ingest the <code>Glass</code> datatype.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>report_drink</span>(glass: Glass) <span style=color:#f92672>-&gt;</span> str:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>match</span> glass:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>case</span> Empty:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span> <span style=color:#e6db74>&#34;Whoops, looks like you&#39;ve finished your drink!&#34;</span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>case</span> Full(drink):
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span> <span style=color:#e6db74>f</span><span style=color:#e6db74>&#34;Ah a </span><span style=color:#e6db74>{</span>drink<span style=color:#e6db74>}</span><span style=color:#e6db74>, what a fine taste!&#34;</span>
</span></span></code></pre></div><p>The only downside to this is that there&rsquo;s no namespaceing of these union types and as such, methods cannot be defined on the <code>Union</code> of the different variants.</p><p>In the case of our concrete example, we can&rsquo;t add methods to the <code>Glass</code> type.</p><p>Since there is no namespacing, we also can&rsquo;t instantiate variants under the <code>Glass</code> namespace. The following code does not work.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>dr_pepper <span style=color:#f92672>=</span> Glass<span style=color:#f92672>.</span>Full(<span style=color:#e6db74>&#34;Dr. Pepper&#34;</span>)
</span></span></code></pre></div><p>This can be partially solved by putting the entire enumerable type inside a module.</p><p>So now we can access the variants as <code>glass_enum.Empty</code> and <code>glass_enum.Full</code>.</p><p>Even if we use module level namespacing, it&rsquo;s simply not possible to define any message on a union type in Python.</p></section><footer class=post-tags data-pagefind-meta=tags></footer><nav data-post><br><a href=https://lavafroth.is-a.dev/post/nixos-notes-to-self/><span>NixOS Notes to Self</span><span></span></a></nav></main><footer class=footer><p>&copy; 2025 <a href=https://lavafroth.is-a.dev/>lavafroth</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/issues/new/choose>Report an issue</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/discussions/>Discuss</a></p><p><a href=https://lavafroth.is-a.dev/privacy>Privacy</a></p><p><a href=https://creativecommons.org/licenses/by-sa/4.0/legalcode>License</a></p></footer></body></html>
</span></span></code></pre></div><h2 id=pitfalls>Pitfalls</h2><h3 id=no-direct-variant-access>No direct variant access</h3><p>Since there is no namespacing, we also can&rsquo;t instantiate variants under the <code>Glass</code> namespace. The following code does not work.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>dr_pepper <span style=color:#f92672>=</span> Glass<span style=color:#f92672>.</span>Full(<span style=color:#e6db74>&#34;Dr. Pepper&#34;</span>)
</span></span></code></pre></div><p>This can be partially solved by putting the entire enumerable type inside a module.
Here we have saved the file as <code>glass_enum.py</code>. From a different module we can
access the variants as <code>glass_enum.Empty</code> and <code>glass_enum.Full</code>.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-py data-lang=py><span style=display:flex><span><span style=color:#75715e># main.py</span>
</span></span><span style=display:flex><span><span style=color:#f92672>import</span> glass_enum
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>fanta <span style=color:#f92672>=</span> glass_enum<span style=color:#f92672>.</span>Full(<span style=color:#e6db74>&#39;Fanta&#39;</span>)
</span></span><span style=display:flex><span>empty <span style=color:#f92672>=</span> glass_enum<span style=color:#f92672>.</span>Empty()
</span></span></code></pre></div><p>Now any function outside the module has to ingest a rather confusing argument of type <code>glass_enum.Glass</code>.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>refill</span>(glass: glass_enum<span style=color:#f92672>.</span>Glass) <span style=color:#f92672>-&gt;</span> glass_enum<span style=color:#f92672>.</span>Glass:
</span></span><span style=display:flex><span> <span style=color:#75715e># ...</span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span> glass
</span></span></code></pre></div><p>Since using a module namespace only causes more confusion, we will discard this idea.</p><h3 id=no-methods-on-the-enum-itself>No methods on the enum itself</h3><p>With no namespaceing, methods cannot be defined on the <code>Union</code> of the different variants.</p><p>In the case of our concrete example, we can&rsquo;t add methods to the <code>Glass</code> type.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>refill</span>(glass: Glass) <span style=color:#f92672>-&gt;</span> Glass:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>if</span> glass<span style=color:#f92672>.</span>is_empty(): <span style=color:#75715e># can&#39;t implement on type `Glass` directly</span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span> Full(<span style=color:#e6db74>&#39;water&#39;</span>)
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span> glass
</span></span></code></pre></div><p>Even if we use module level namespacing, it&rsquo;s simply not possible to define any method on a <code>Union</code> type in Python.</p><p>To define a method like <code>is_empty()</code>, it must be implemented on both the classes <code>Full</code> and <code>Empty</code>. This can get
tedious if there are 3 or more variants.</p><h2 id=python-is-a-sneaky-language>Python is a sneaky language</h2><p>Last week I discovered that Python allows creating nested classes to keep things organized.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#f92672>from</span> dataclasses <span style=color:#f92672>import</span> dataclass
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>class</span> <span style=color:#a6e22e>Glass</span>:
</span></span><span style=display:flex><span> <span style=color:#a6e22e>@dataclass</span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>class</span> <span style=color:#a6e22e>Empty</span>:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>pass</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#a6e22e>@dataclass</span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>class</span> <span style=color:#a6e22e>Full</span>:
</span></span><span style=display:flex><span> drink: str
</span></span></code></pre></div><p>Python will happily run the above code and we can access the &ldquo;variants&rdquo; under the <code>Glass</code> namespace.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>lemonade <span style=color:#f92672>=</span> Glass<span style=color:#f92672>.</span>Full(<span style=color:#e6db74>&#39;lemonade&#39;</span>)
</span></span></code></pre></div><p>If only we could register the variants as the <code>Glass</code> type itself and inherit all its methods.</p><h3 id=redecorate>Redecorate</h3><p>We can define a decorator that takes all of the nested dataclasses and makes them inherit the outer class.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#f92672>import</span> inspect
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>AlgebraicEnum</span>(cls):
</span></span><span style=display:flex><span> <span style=color:#66d9ef>for</span> subclass_name, subclass <span style=color:#f92672>in</span> inspect<span style=color:#f92672>.</span>getmembers(cls, predicate<span style=color:#f92672>=</span>inspect<span style=color:#f92672>.</span>isclass):
</span></span><span style=display:flex><span> <span style=color:#66d9ef>if</span> subclass_name <span style=color:#f92672>!=</span> <span style=color:#e6db74>&#34;__class__&#34;</span>:
</span></span><span style=display:flex><span> setattr(cls, subclass_name, type(subclass_name, (cls, subclass), {}))
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span> cls
</span></span></code></pre></div><p>That&rsquo;s all there is to the magic! Now we can simply add this decorator above the previous class declaration
and the variants like <code>Glass.Empty</code> and <code>Glass.Full</code> would be of the type <code>Glass</code>.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#f92672>from</span> dataclasses <span style=color:#f92672>import</span> dataclass
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#a6e22e>@AlgebraicEnum</span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>class</span> <span style=color:#a6e22e>Glass</span>:
</span></span><span style=display:flex><span> <span style=color:#a6e22e>@dataclass</span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>class</span> <span style=color:#a6e22e>Empty</span>:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>pass</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#a6e22e>@dataclass</span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>class</span> <span style=color:#a6e22e>Full</span>:
</span></span><span style=display:flex><span> drink: str
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>def</span> <span style=color:#a6e22e>report_drink</span>(self) <span style=color:#f92672>-&gt;</span> str:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>match</span> self:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>case</span> Glass<span style=color:#f92672>.</span>Empty:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span> <span style=color:#e6db74>&#34;Whoops, looks like you&#39;ve finished your drink!&#34;</span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>case</span> Glass<span style=color:#f92672>.</span>Full(drink):
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span> <span style=color:#e6db74>f</span><span style=color:#e6db74>&#34;Ah a </span><span style=color:#e6db74>{</span>drink<span style=color:#e6db74>}</span><span style=color:#e6db74>, what a fine taste!&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>def</span> <span style=color:#a6e22e>is_empty</span>(self) <span style=color:#f92672>-&gt;</span> str:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>match</span> self:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>case</span> Glass<span style=color:#f92672>.</span>Empty:
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span> <span style=color:#66d9ef>True</span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span> <span style=color:#66d9ef>False</span>
</span></span></code></pre></div><p>As a bonus, the variants will also inherit any methods defined on the <code>Glass</code> type.</p><p>Note how the <code>report_drink</code> method accepts a <code>self</code> of type <code>Glass</code> and the match arms
compare it with <code>Glass.Empty</code> and <code>Glass.Full</code>.</p><p>These methods get automatically called via the method resolution order chain due to the inheritance.</p><h2 id=closing-thoughts>Closing thoughts</h2><p>Those 6 lines are the bare minimum of what you can do right now to have well organized and namespaced algebraic enums in Python
which are somewhat comparable to those in Rust. These enums also play nicely with static type checkers
and <em>goto-definitions</em> will also lead you to the correct class defining a variant or the enum itself.</p><p>I have packaged this decorator with a couple more typing restrictions into a library at <a href=https://github.com/lavafroth/ape>github:lavafroth/ape</a>.</p><p>I hope you enjoyed this foray into contorting Python.</p></section><footer class=post-tags data-pagefind-meta=tags><a href=https://lavafroth.is-a.dev/tags/python class=list-tag>Python</a>
<a href=https://lavafroth.is-a.dev/tags/decorators class=list-tag>Decorators</a>
<a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/algebraic-data-types class=list-tag>Algebraic Data Types</a></footer><nav data-post><br><a href=https://lavafroth.is-a.dev/post/nixos-notes-to-self/><span>NixOS Notes to Self</span><span></span></a></nav></main><footer class=footer><p>&copy; 2025 <a href=https://lavafroth.is-a.dev/>lavafroth</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/issues/new/choose>Report an issue</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/discussions/>Discuss</a></p><p><a href=https://lavafroth.is-a.dev/privacy>Privacy</a></p><p><a href=https://creativecommons.org/licenses/by-sa/4.0/legalcode>License</a></p></footer></body></html>

View File

@@ -1,4 +1,8 @@
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Posts - lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/post/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=../pagefind/pagefind-ui.css rel=stylesheet><script src=../pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/><h2>Algebraic Python Enums</h2></a><time>Nov 2, 2025 | 2 minutes read</time><br><a class=post-link aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/></a></article><article><a aria-label="NixOS Notes to Self" href=https://lavafroth.is-a.dev/post/nixos-notes-to-self/><h2>NixOS Notes to Self</h2></a><time>Sep 14, 2025 | 1 minute read</time><br><a href=https://lavafroth.is-a.dev/tags/nix class=list-tag>Nix</a>
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Posts - lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/post/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=../pagefind/pagefind-ui.css rel=stylesheet><script src=../pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/><h2>Algebraic Python Enums</h2></a><time>Nov 2, 2025 | 4 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/python class=list-tag>Python</a>
<a href=https://lavafroth.is-a.dev/tags/decorators class=list-tag>Decorators</a>
<a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/algebraic-data-types class=list-tag>Algebraic Data Types</a>
<a class=post-link aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/></a></article><article><a aria-label="NixOS Notes to Self" href=https://lavafroth.is-a.dev/post/nixos-notes-to-self/><h2>NixOS Notes to Self</h2></a><time>Sep 14, 2025 | 1 minute read</time><br><a href=https://lavafroth.is-a.dev/tags/nix class=list-tag>Nix</a>
<a href=https://lavafroth.is-a.dev/tags/nixos class=list-tag>NixOS</a>
<a href=https://lavafroth.is-a.dev/tags/notes class=list-tag>Notes</a>
<a href=https://lavafroth.is-a.dev/tags/troubleshooting class=list-tag>Troubleshooting</a>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Algebraic Data Types - lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/tags/algebraic-data-types/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=../../pagefind/pagefind-ui.css rel=stylesheet><script src=../../pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/><h2>Algebraic Python Enums</h2></a><time>Nov 2, 2025 | 4 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/python class=list-tag>Python</a>
<a href=https://lavafroth.is-a.dev/tags/decorators class=list-tag>Decorators</a>
<a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/algebraic-data-types class=list-tag>Algebraic Data Types</a>
<a class=post-link aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/></a></article><script>window.addEventListener("DOMContentLoaded",e=>{new PagefindUI({element:"search"})})</script></main><footer class=footer><p>&copy; 2025 <a href=https://lavafroth.is-a.dev/>lavafroth</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/issues/new/choose>Report an issue</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/discussions/>Discuss</a></p><p><a href=https://lavafroth.is-a.dev/privacy>Privacy</a></p><p><a href=https://creativecommons.org/licenses/by-sa/4.0/legalcode>License</a></p></footer></body></html>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Algebraic Data Types on lavafroth</title><link>https://lavafroth.is-a.dev/tags/algebraic-data-types/</link><description>Recent content in Algebraic Data Types on lavafroth</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 02 Nov 2025 19:08:46 +0530</lastBuildDate><atom:link href="https://lavafroth.is-a.dev/tags/algebraic-data-types/index.xml" rel="self" type="application/rss+xml"/><item><title>Algebraic Python Enums</title><link>https://lavafroth.is-a.dev/post/algebraic-python-enums/</link><pubDate>Sun, 02 Nov 2025 19:08:46 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/algebraic-python-enums/</guid><description>&lt;p&gt;As much as I like rust for its ergonomic features, University has forced me to use Python for the past couple of months, especially because of the hype for machine learning and data science.&lt;/p&gt;
&lt;p&gt;One of the biggest things that I missed from the rust experience was enumerable data types whose variants can wrap around different datatypes.&lt;/p&gt;
&lt;p&gt;Fortunately, since Python 3.8, creating structs has been a breeze using the dataclass decorator. There&amp;rsquo;s even support for structural match expressions, like in rust, in recent versions of Python. &lt;a href="https://peps.python.org/pep-0636/"&gt;https://peps.python.org/pep-0636/&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>

View File

@@ -0,0 +1 @@
<!doctype html><html lang=en-us><head><title>https://lavafroth.is-a.dev/tags/algebraic-data-types/</title><link rel=canonical href=https://lavafroth.is-a.dev/tags/algebraic-data-types/><meta charset=utf-8><meta http-equiv=refresh content="0; url=https://lavafroth.is-a.dev/tags/algebraic-data-types/"></head></html>

View File

@@ -0,0 +1,5 @@
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Decorators - lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/tags/decorators/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=../../pagefind/pagefind-ui.css rel=stylesheet><script src=../../pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/><h2>Algebraic Python Enums</h2></a><time>Nov 2, 2025 | 4 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/python class=list-tag>Python</a>
<a href=https://lavafroth.is-a.dev/tags/decorators class=list-tag>Decorators</a>
<a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/algebraic-data-types class=list-tag>Algebraic Data Types</a>
<a class=post-link aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/></a></article><script>window.addEventListener("DOMContentLoaded",e=>{new PagefindUI({element:"search"})})</script></main><footer class=footer><p>&copy; 2025 <a href=https://lavafroth.is-a.dev/>lavafroth</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/issues/new/choose>Report an issue</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/discussions/>Discuss</a></p><p><a href=https://lavafroth.is-a.dev/privacy>Privacy</a></p><p><a href=https://creativecommons.org/licenses/by-sa/4.0/legalcode>License</a></p></footer></body></html>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Decorators on lavafroth</title><link>https://lavafroth.is-a.dev/tags/decorators/</link><description>Recent content in Decorators on lavafroth</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 02 Nov 2025 19:08:46 +0530</lastBuildDate><atom:link href="https://lavafroth.is-a.dev/tags/decorators/index.xml" rel="self" type="application/rss+xml"/><item><title>Algebraic Python Enums</title><link>https://lavafroth.is-a.dev/post/algebraic-python-enums/</link><pubDate>Sun, 02 Nov 2025 19:08:46 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/algebraic-python-enums/</guid><description>&lt;p&gt;As much as I like rust for its ergonomic features, University has forced me to use Python for the past couple of months, especially because of the hype for machine learning and data science.&lt;/p&gt;
&lt;p&gt;One of the biggest things that I missed from the rust experience was enumerable data types whose variants can wrap around different datatypes.&lt;/p&gt;
&lt;p&gt;Fortunately, since Python 3.8, creating structs has been a breeze using the dataclass decorator. There&amp;rsquo;s even support for structural match expressions, like in rust, in recent versions of Python. &lt;a href="https://peps.python.org/pep-0636/"&gt;https://peps.python.org/pep-0636/&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>

View File

@@ -0,0 +1 @@
<!doctype html><html lang=en-us><head><title>https://lavafroth.is-a.dev/tags/decorators/</title><link rel=canonical href=https://lavafroth.is-a.dev/tags/decorators/><meta charset=utf-8><meta http-equiv=refresh content="0; url=https://lavafroth.is-a.dev/tags/decorators/"></head></html>

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,8 @@
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Python - lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/tags/python/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=../../pagefind/pagefind-ui.css rel=stylesheet><script src=../../pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="PicoCTF SansAlpha Writeup" href=https://lavafroth.is-a.dev/post/picoctf-sansalpha-writeup/><h2>PicoCTF SansAlpha Writeup</h2></a><time>Jan 5, 2025 | 7 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/picoctf class=list-tag>PicoCTF</a>
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Python - lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/tags/python/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=../../pagefind/pagefind-ui.css rel=stylesheet><script src=../../pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/><h2>Algebraic Python Enums</h2></a><time>Nov 2, 2025 | 4 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/python class=list-tag>Python</a>
<a href=https://lavafroth.is-a.dev/tags/decorators class=list-tag>Decorators</a>
<a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/algebraic-data-types class=list-tag>Algebraic Data Types</a>
<a class=post-link aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/></a></article><article><a aria-label="PicoCTF SansAlpha Writeup" href=https://lavafroth.is-a.dev/post/picoctf-sansalpha-writeup/><h2>PicoCTF SansAlpha Writeup</h2></a><time>Jan 5, 2025 | 7 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/picoctf class=list-tag>PicoCTF</a>
<a href=https://lavafroth.is-a.dev/tags/bash class=list-tag>Bash</a>
<a href=https://lavafroth.is-a.dev/tags/sandbox-escape class=list-tag>Sandbox Escape</a>
<a href=https://lavafroth.is-a.dev/tags/python class=list-tag>Python</a>

View File

@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Python on lavafroth</title><link>https://lavafroth.is-a.dev/tags/python/</link><description>Recent content in Python on lavafroth</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 05 Jan 2025 11:55:52 +0530</lastBuildDate><atom:link href="https://lavafroth.is-a.dev/tags/python/index.xml" rel="self" type="application/rss+xml"/><item><title>PicoCTF SansAlpha Writeup</title><link>https://lavafroth.is-a.dev/post/picoctf-sansalpha-writeup/</link><pubDate>Sun, 05 Jan 2025 11:55:52 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/picoctf-sansalpha-writeup/</guid><description>&lt;p&gt;Hey everyone, since 2024 hasn&amp;rsquo;t seen a lot of posts on this blog, I plan to
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Python on lavafroth</title><link>https://lavafroth.is-a.dev/tags/python/</link><description>Recent content in Python on lavafroth</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 02 Nov 2025 19:08:46 +0530</lastBuildDate><atom:link href="https://lavafroth.is-a.dev/tags/python/index.xml" rel="self" type="application/rss+xml"/><item><title>Algebraic Python Enums</title><link>https://lavafroth.is-a.dev/post/algebraic-python-enums/</link><pubDate>Sun, 02 Nov 2025 19:08:46 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/algebraic-python-enums/</guid><description>&lt;p&gt;As much as I like rust for its ergonomic features, University has forced me to use Python for the past couple of months, especially because of the hype for machine learning and data science.&lt;/p&gt;
&lt;p&gt;One of the biggest things that I missed from the rust experience was enumerable data types whose variants can wrap around different datatypes.&lt;/p&gt;
&lt;p&gt;Fortunately, since Python 3.8, creating structs has been a breeze using the dataclass decorator. There&amp;rsquo;s even support for structural match expressions, like in rust, in recent versions of Python. &lt;a href="https://peps.python.org/pep-0636/"&gt;https://peps.python.org/pep-0636/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>PicoCTF SansAlpha Writeup</title><link>https://lavafroth.is-a.dev/post/picoctf-sansalpha-writeup/</link><pubDate>Sun, 05 Jan 2025 11:55:52 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/picoctf-sansalpha-writeup/</guid><description>&lt;p&gt;Hey everyone, since 2024 hasn&amp;rsquo;t seen a lot of posts on this blog, I plan to
start this year off by going back to the roots.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll be focusing on posting more CTF writeups again! Today&amp;rsquo;s challenge is
&lt;em&gt;SansAlpha&lt;/em&gt; from PicoCTF. The challenge description states&lt;/p&gt;

View File

@@ -1,4 +1,8 @@
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Rust - lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/tags/rust/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=../../pagefind/pagefind-ui.css rel=stylesheet><script src=../../pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="Wrapping up GSoC 2024" href=https://lavafroth.is-a.dev/post/the-gsoc-grand-finale/><h2>Wrapping up GSoC 2024</h2></a><time>Aug 24, 2024 | 6 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/ebnf class=list-tag>EBNF</a>
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Rust - lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/tags/rust/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=../../pagefind/pagefind-ui.css rel=stylesheet><script src=../../pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/><h2>Algebraic Python Enums</h2></a><time>Nov 2, 2025 | 4 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/python class=list-tag>Python</a>
<a href=https://lavafroth.is-a.dev/tags/decorators class=list-tag>Decorators</a>
<a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/algebraic-data-types class=list-tag>Algebraic Data Types</a>
<a class=post-link aria-label="Algebraic Python Enums" href=https://lavafroth.is-a.dev/post/algebraic-python-enums/></a></article><article><a aria-label="Wrapping up GSoC 2024" href=https://lavafroth.is-a.dev/post/the-gsoc-grand-finale/><h2>Wrapping up GSoC 2024</h2></a><time>Aug 24, 2024 | 6 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/ebnf class=list-tag>EBNF</a>
<a href=https://lavafroth.is-a.dev/tags/google-summer-of-code class=list-tag>Google Summer of Code</a>
<a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/swhkd class=list-tag>SWHKD</a>
@@ -52,11 +56,5 @@
<a href=https://lavafroth.is-a.dev/tags/swhkd class=list-tag>SWHKD</a>
<a href=https://lavafroth.is-a.dev/tags/waycrate class=list-tag>Waycrate</a>
<a href=https://lavafroth.is-a.dev/tags/wayland class=list-tag>Wayland</a>
<a class=post-link aria-label="Timing is Key: A Tale of Keystrokes and Timings" href=https://lavafroth.is-a.dev/post/timing-is-key/></a></article><article><a aria-label="Keep the Keys Clackin'" href=https://lavafroth.is-a.dev/post/keep-the-keys-clackin/><h2>Keep the Keys Clackin'</h2></a><time>May 27, 2024 | 5 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/ebnf class=list-tag>EBNF</a>
<a href=https://lavafroth.is-a.dev/tags/google-summer-of-code class=list-tag>Google Summer of Code</a>
<a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/swhkd class=list-tag>SWHKD</a>
<a href=https://lavafroth.is-a.dev/tags/waycrate class=list-tag>Waycrate</a>
<a href=https://lavafroth.is-a.dev/tags/wayland class=list-tag>Wayland</a>
<a class=post-link aria-label="Keep the Keys Clackin'" href=https://lavafroth.is-a.dev/post/keep-the-keys-clackin/></a></article><nav data-main><a href=#>Previous Page</a>
<a class=post-link aria-label="Timing is Key: A Tale of Keystrokes and Timings" href=https://lavafroth.is-a.dev/post/timing-is-key/></a></article><nav data-main><a href=#>Previous Page</a>
<a href=../../tags/rust/page/2/>Next Page</a></nav><script>window.addEventListener("DOMContentLoaded",e=>{new PagefindUI({element:"search"})})</script></main><footer class=footer><p>&copy; 2025 <a href=https://lavafroth.is-a.dev/>lavafroth</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/issues/new/choose>Report an issue</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/discussions/>Discuss</a></p><p><a href=https://lavafroth.is-a.dev/privacy>Privacy</a></p><p><a href=https://creativecommons.org/licenses/by-sa/4.0/legalcode>License</a></p></footer></body></html>

View File

@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Rust on lavafroth</title><link>https://lavafroth.is-a.dev/tags/rust/</link><description>Recent content in Rust on lavafroth</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sat, 24 Aug 2024 10:28:50 +0530</lastBuildDate><atom:link href="https://lavafroth.is-a.dev/tags/rust/index.xml" rel="self" type="application/rss+xml"/><item><title>Wrapping up GSoC 2024</title><link>https://lavafroth.is-a.dev/post/the-gsoc-grand-finale/</link><pubDate>Sat, 24 Aug 2024 10:28:50 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/the-gsoc-grand-finale/</guid><description>&lt;h1 id="overview"&gt;Overview&lt;/h1&gt;
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Rust on lavafroth</title><link>https://lavafroth.is-a.dev/tags/rust/</link><description>Recent content in Rust on lavafroth</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 02 Nov 2025 19:08:46 +0530</lastBuildDate><atom:link href="https://lavafroth.is-a.dev/tags/rust/index.xml" rel="self" type="application/rss+xml"/><item><title>Algebraic Python Enums</title><link>https://lavafroth.is-a.dev/post/algebraic-python-enums/</link><pubDate>Sun, 02 Nov 2025 19:08:46 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/algebraic-python-enums/</guid><description>&lt;p&gt;As much as I like rust for its ergonomic features, University has forced me to use Python for the past couple of months, especially because of the hype for machine learning and data science.&lt;/p&gt;
&lt;p&gt;One of the biggest things that I missed from the rust experience was enumerable data types whose variants can wrap around different datatypes.&lt;/p&gt;
&lt;p&gt;Fortunately, since Python 3.8, creating structs has been a breeze using the dataclass decorator. There&amp;rsquo;s even support for structural match expressions, like in rust, in recent versions of Python. &lt;a href="https://peps.python.org/pep-0636/"&gt;https://peps.python.org/pep-0636/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Wrapping up GSoC 2024</title><link>https://lavafroth.is-a.dev/post/the-gsoc-grand-finale/</link><pubDate>Sat, 24 Aug 2024 10:28:50 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/the-gsoc-grand-finale/</guid><description>&lt;h1 id="overview"&gt;Overview&lt;/h1&gt;
&lt;p&gt;Hello and welcome to the final GSoC post for 2024! My task was to formalize the SWHKD parser using context-free EBNF notation. This post is to serve as a birdseye view of what
I have developed over this summer.&lt;/p&gt;
&lt;h1 id="report"&gt;Report&lt;/h1&gt;

View File

@@ -1,4 +1,10 @@
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Rust - lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/tags/rust/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../../../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../../../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=../../../../pagefind/pagefind-ui.css rel=stylesheet><script src=../../../../pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="2 Afternoons, 2 Languages, 2 TUIs" href=https://lavafroth.is-a.dev/post/2-afternoons-2-languages-2-tuis/><h2>2 Afternoons, 2 Languages, 2 TUIs</h2></a><time>May 23, 2024 | 5 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Rust - lavafroth</title><meta name=description content='smol creator'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png><link rel=alternate type=application/rss+xml href=https://lavafroth.is-a.dev/tags/rust/index.xml title=lavafroth></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../../../about/ aria-label=about style=--url:url(./about.svg)></a><a href=../../../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><link href=../../../../pagefind/pagefind-ui.css rel=stylesheet><script src=../../../../pagefind/pagefind-ui.js type=text/javascript></script><search></search><section class=post-content></section><article><a aria-label="Keep the Keys Clackin'" href=https://lavafroth.is-a.dev/post/keep-the-keys-clackin/><h2>Keep the Keys Clackin'</h2></a><time>May 27, 2024 | 5 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/ebnf class=list-tag>EBNF</a>
<a href=https://lavafroth.is-a.dev/tags/google-summer-of-code class=list-tag>Google Summer of Code</a>
<a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/swhkd class=list-tag>SWHKD</a>
<a href=https://lavafroth.is-a.dev/tags/waycrate class=list-tag>Waycrate</a>
<a href=https://lavafroth.is-a.dev/tags/wayland class=list-tag>Wayland</a>
<a class=post-link aria-label="Keep the Keys Clackin'" href=https://lavafroth.is-a.dev/post/keep-the-keys-clackin/></a></article><article><a aria-label="2 Afternoons, 2 Languages, 2 TUIs" href=https://lavafroth.is-a.dev/post/2-afternoons-2-languages-2-tuis/><h2>2 Afternoons, 2 Languages, 2 TUIs</h2></a><time>May 23, 2024 | 5 minutes read</time><br><a href=https://lavafroth.is-a.dev/tags/rust class=list-tag>Rust</a>
<a href=https://lavafroth.is-a.dev/tags/go class=list-tag>Go</a>
<a href=https://lavafroth.is-a.dev/tags/terminal class=list-tag>Terminal</a>
<a href=https://lavafroth.is-a.dev/tags/ui class=list-tag>UI</a>