mirror of
https://github.com/lavafroth/lavafroth.github.io.git
synced 2026-05-21 11:31:16 -03:00
deploy: 2a52df10b6
This commit is contained in:
@@ -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>
|
||||
|
||||
BIN
pagefind/fragment/en-us_45b0836.pf_fragment
Normal file
BIN
pagefind/fragment/en-us_45b0836.pf_fragment
Normal file
Binary file not shown.
Binary file not shown.
BIN
pagefind/index/en-us_432dc71.pf_index
Normal file
BIN
pagefind/index/en-us_432dc71.pf_index
Normal file
Binary file not shown.
BIN
pagefind/index/en-us_49a388c.pf_index
Normal file
BIN
pagefind/index/en-us_49a388c.pf_index
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
pagefind/index/en-us_68c9511.pf_index
Normal file
BIN
pagefind/index/en-us_68c9511.pf_index
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
pagefind/index/en-us_afd81dc.pf_index
Normal file
BIN
pagefind/index/en-us_afd81dc.pf_index
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
pagefind/index/en-us_f8dc361.pf_index
Normal file
BIN
pagefind/index/en-us_f8dc361.pf_index
Normal file
Binary file not shown.
BIN
pagefind/index/en-us_fce5781.pf_index
Normal file
BIN
pagefind/index/en-us_fce5781.pf_index
Normal file
Binary file not shown.
@@ -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}}}
|
||||
BIN
pagefind/pagefind.en-us_7676eaf26e26a.pf_meta
Normal file
BIN
pagefind/pagefind.en-us_7676eaf26e26a.pf_meta
Normal file
Binary file not shown.
Binary file not shown.
@@ -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’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’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’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’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’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’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>-></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>"Whoops, looks like you've finished your drink!"</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>"Ah a </span><span style=color:#e6db74>{</span>drink<span style=color:#e6db74>}</span><span style=color:#e6db74>, what a fine taste!"</span>
|
||||
</span></span></code></pre></div><p>The only downside to this is that there’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’t add methods to the <code>Glass</code> type.</p><p>Since there is no namespacing, we also can’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>"Dr. Pepper"</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’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>© 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’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>"Dr. Pepper"</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>'Fanta'</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>-></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’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>-></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'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>'water'</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’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 “variants” 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>'lemonade'</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>"__class__"</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’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>-></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>"Whoops, looks like you've finished your drink!"</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>"Ah a </span><span style=color:#e6db74>{</span>drink<span style=color:#e6db74>}</span><span style=color:#e6db74>, what a fine taste!"</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>-></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>© 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>
|
||||
@@ -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
5
tags/algebraic-data-types/index.html
Normal file
5
tags/algebraic-data-types/index.html
Normal 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>© 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>
|
||||
3
tags/algebraic-data-types/index.xml
Normal file
3
tags/algebraic-data-types/index.xml
Normal 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><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></description></item></channel></rss>
|
||||
1
tags/algebraic-data-types/page/1/index.html
Normal file
1
tags/algebraic-data-types/page/1/index.html
Normal 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>
|
||||
5
tags/decorators/index.html
Normal file
5
tags/decorators/index.html
Normal 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>© 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>
|
||||
3
tags/decorators/index.xml
Normal file
3
tags/decorators/index.xml
Normal 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><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></description></item></channel></rss>
|
||||
1
tags/decorators/page/1/index.html
Normal file
1
tags/decorators/page/1/index.html
Normal 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
@@ -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>
|
||||
|
||||
@@ -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><p>Hey everyone, since 2024 hasn&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><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></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><p>Hey everyone, since 2024 hasn&rsquo;t seen a lot of posts on this blog, I plan to
|
||||
start this year off by going back to the roots.</p>
|
||||
<p>I&rsquo;ll be focusing on posting more CTF writeups again! Today&rsquo;s challenge is
|
||||
<em>SansAlpha</em> from PicoCTF. The challenge description states</p>
|
||||
|
||||
@@ -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>© 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>
|
||||
@@ -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><h1 id="overview">Overview</h1>
|
||||
<?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><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></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><h1 id="overview">Overview</h1>
|
||||
<p>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.</p>
|
||||
<h1 id="report">Report</h1>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user