mirror of
https://github.com/lavafroth/lavafroth.github.io.git
synced 2026-06-03 06:41:15 -03:00
deploy: e65caed1b1
This commit is contained in:
2
app.min.css
vendored
2
app.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
<!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>
|
||||
<!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 | 5 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>
|
||||
|
||||
13
index.xml
13
index.xml
@@ -1,6 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>lavafroth</title><link>https://lavafroth.is-a.dev/</link><description>Recent content 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/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 <a href="https://peps.python.org/pep-0636/">Python</a>.</p></description></item><item><title>note skta4v7n8h8</title><link>https://lavafroth.is-a.dev/skta4v7n8h8/</link><pubDate>Fri, 31 Oct 2025 20:24:35 +0530</pubDate><guid>https://lavafroth.is-a.dev/skta4v7n8h8/</guid><description><h1 id="grpa-1">GrPA 1</h1>
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>lavafroth</title><link>https://lavafroth.is-a.dev/</link><description>Recent content 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/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>Although Python has the answer to creating structs as
|
||||
<a href="https://peps.python.org/pep-0557/">dataclasses</a>, including support for
|
||||
<a href="https://peps.python.org/pep-0636/">structural match expressions</a> in recent
|
||||
versions, most tutorials will suggest <code>Union</code> types as the equivalent to Rust&rsquo;s
|
||||
enums.</p></description></item><item><title>note skta4v7n8h8</title><link>https://lavafroth.is-a.dev/skta4v7n8h8/</link><pubDate>Fri, 31 Oct 2025 20:24:35 +0530</pubDate><guid>https://lavafroth.is-a.dev/skta4v7n8h8/</guid><description><h1 id="grpa-1">GrPA 1</h1>
|
||||
<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">swap</span>(arr, i, j):
|
||||
</span></span><span style="display:flex;"><span> arr[i], arr[j] <span style="color:#f92672">=</span> arr[j], arr[i]
|
||||
</span></span><span style="display:flex;"><span>
|
||||
|
||||
Binary file not shown.
BIN
pagefind/fragment/en-us_ff9e431.pf_fragment
Normal file
BIN
pagefind/fragment/en-us_ff9e431.pf_fragment
Normal file
Binary file not shown.
BIN
pagefind/index/en-us_18656bc.pf_index
Normal file
BIN
pagefind/index/en-us_18656bc.pf_index
Normal file
Binary file not shown.
Binary file not shown.
BIN
pagefind/index/en-us_569df36.pf_index
Normal file
BIN
pagefind/index/en-us_569df36.pf_index
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
pagefind/index/en-us_ce84bb8.pf_index
Normal file
BIN
pagefind/index/en-us_ce84bb8.pf_index
Normal file
Binary file not shown.
BIN
pagefind/index/en-us_e2f7899.pf_index
Normal file
BIN
pagefind/index/en-us_e2f7899.pf_index
Normal file
Binary file not shown.
BIN
pagefind/index/en-us_eec299e.pf_index
Normal file
BIN
pagefind/index/en-us_eec299e.pf_index
Normal file
Binary file not shown.
BIN
pagefind/index/en-us_f767589.pf_index
Normal file
BIN
pagefind/index/en-us_f767589.pf_index
Normal file
Binary file not shown.
@@ -1 +1 @@
|
||||
{"version":"1.0.3","languages":{"en-us":{"hash":"en-us_6a23f48a599dc","wasm":"en-us","page_count":58}}}
|
||||
{"version":"1.0.3","languages":{"en-us":{"hash":"en-us_f3d6bd8299974","wasm":"en-us","page_count":58}}}
|
||||
Binary file not shown.
BIN
pagefind/pagefind.en-us_f3d6bd8299974.pf_meta
Normal file
BIN
pagefind/pagefind.en-us_f3d6bd8299974.pf_meta
Normal file
Binary file not shown.
@@ -1,6 +1,21 @@
|
||||
<!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.'><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 <a href=https://peps.python.org/pep-0636/>Python</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>
|
||||
<!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.
|
||||
Although Python has the answer to creating structs as
|
||||
dataclasses, including support for
|
||||
structural match expressions in recent
|
||||
versions, most tutorials will suggest Union types as the equivalent to Rust’s
|
||||
enums.'><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 | 5 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>Although Python has the answer to creating structs as
|
||||
<a href=https://peps.python.org/pep-0557/>dataclasses</a>, including support for
|
||||
<a href=https://peps.python.org/pep-0636/>structural match expressions</a> in recent
|
||||
versions, most tutorials will suggest <code>Union</code> types as the equivalent to Rust’s
|
||||
enums.</p><blockquote><p>I highly encourage you to try out the code snippets and follow along with this article.
|
||||
Use the collapse explanation button to copy multiple code blocks in one go.</p></blockquote><h2 id=naive-draft>Naive draft</h2><div class=collapsable-explanation><div class=container><label><input type=checkbox></label></div><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>
|
||||
@@ -19,8 +34,63 @@ Fortunately, since Python 3.8, creating structs has been a breeze using the data
|
||||
</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><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.
|
||||
</span></span></code></pre></div><p>For example</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> Full(<span style=color:#e6db74>'Dr. Pepper'</span>)
|
||||
</span></span><span style=display:flex><span>print(report_drink(dr_pepper))
|
||||
</span></span></code></pre></div><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>:
|
||||
</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>Glass <span style=color:#f92672>=</span> Empty <span style=color:#f92672>|</span> Full
|
||||
</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>(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><span style=display:flex><span>
|
||||
</span></span><span style=display:flex><span>dr_pepper <span style=color:#f92672>=</span> Full(<span style=color:#e6db74>'Dr. Pepper'</span>)
|
||||
</span></span><span style=display:flex><span>print(report_drink(dr_pepper))
|
||||
</span></span></code></pre></div><div class=container></div></div><p>Will output</p><pre tabindex=0><code>Ah a Dr. Pepper, what a fine taste!
|
||||
</code></pre><h2 id=pitfalls>Pitfalls</h2><h3 id=no-direct-variant-access>No direct variant access</h3><div class=collapsable-explanation><div class=container><label><input type=checkbox></label></div><p>What if we had another <code>Union</code> with same variant names in the same file?</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:#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> gold: int
|
||||
</span></span><span style=display:flex><span> gems: int
|
||||
</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>:
|
||||
</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>Inventory <span style=color:#f92672>=</span> Full <span style=color:#f92672>|</span> Empty
|
||||
</span></span><span style=display:flex><span>player_inventory <span style=color:#f92672>=</span> Full(<span style=color:#ae81ff>500</span>, <span style=color:#ae81ff>50</span>)
|
||||
</span></span></code></pre></div><p>Now we try to instantiate a <code>Glass</code> <code>Full</code> of <code>lemonade</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>lemonade <span style=color:#f92672>=</span> Full(<span style=color:#e6db74>"lemonade"</span>)
|
||||
</span></span></code></pre></div><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:#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> gold: int
|
||||
</span></span><span style=display:flex><span> gems: int
|
||||
</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>:
|
||||
</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>Inventory <span style=color:#f92672>=</span> Full <span style=color:#f92672>|</span> Empty
|
||||
</span></span><span style=display:flex><span>player_inventory <span style=color:#f92672>=</span> Full(<span style=color:#ae81ff>500</span>, <span style=color:#ae81ff>50</span>)
|
||||
</span></span><span style=display:flex><span>lemonade <span style=color:#f92672>=</span> Full(<span style=color:#e6db74>"lemonade"</span>)
|
||||
</span></span></code></pre></div><div class=container></div></div><p>Python will error out since <code>Full</code> now refers to the new variant of the
|
||||
union type <code>Inventory</code>.</p><pre tabindex=0><code>Traceback (most recent call last):
|
||||
File "<python-input-11>", line 1, in <module>
|
||||
lemonade = Full("lemonade")
|
||||
TypeError: Full.__init__() missing 1 required positional argument: 'gems'
|
||||
</code></pre><p>We can’t instantiate variants as members of 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 keeping just the <code>Glass</code> 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
|
||||
@@ -30,12 +100,14 @@ access the variants as <code>glass_enum.Empty</code> and <code>glass_enum.Full</
|
||||
</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></code></pre></div><p>Since module namespacing 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>Python also disallows methods from being defined on <code>Union</code> types.
|
||||
In the case of our concrete example, we can’t add methods to the <code>Glass</code> type.</p><p>The following code uses a hypothetical <code>is_empty()</code> method on the <code>Glass</code> union
|
||||
type which is not allowed. Hence the code won’t run.</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></code></pre></div><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 gets tedious for 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>
|
||||
@@ -46,7 +118,7 @@ tedious if there are 3 or more variants.</p><h2 id=python-is-a-sneaky-language>P
|
||||
</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></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=collapsable-explanation><div class=container><label><input type=checkbox></label></div><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):
|
||||
@@ -54,7 +126,8 @@ tedious if there are 3 or more variants.</p><h2 id=python-is-a-sneaky-language>P
|
||||
</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
|
||||
</span></span></code></pre></div><p>The inheritance means all methods of the outer class are available on the nested
|
||||
classes <em>and</em> any object of a nested class <code>isinstance</code> of the outer class.</p><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>
|
||||
@@ -67,22 +140,71 @@ and the variants like <code>Glass.Empty</code> and <code>Glass.Full</code> would
|
||||
</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>def</span> <span style=color:#a6e22e>report_drink</span>(self: <span style=color:#e6db74>'Glass'</span>) <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>def</span> <span style=color:#a6e22e>is_empty</span>(self: <span style=color:#e6db74>'Glass'</span>) <span style=color:#f92672>-></span> bool:
|
||||
</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>
|
||||
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><p>The following code runs just fine.</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>diet_coke <span style=color:#f92672>=</span> Glass<span style=color:#f92672>.</span>Full(<span style=color:#e6db74>'diet coke'</span>)
|
||||
</span></span><span style=display:flex><span>empty <span style=color:#f92672>=</span> Glass<span style=color:#f92672>.</span>Empty()
|
||||
</span></span><span style=display:flex><span>
|
||||
</span></span><span style=display:flex><span>print(diet_coke<span style=color:#f92672>.</span>report_drink())
|
||||
</span></span><span style=display:flex><span>print(empty<span style=color:#f92672>.</span>is_empty())
|
||||
</span></span></code></pre></div><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 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></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><span style=display:flex><span>
|
||||
</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:#e6db74>'Glass'</span>) <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:#e6db74>'Glass'</span>) <span style=color:#f92672>-></span> bool:
|
||||
</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><span style=display:flex><span>
|
||||
</span></span><span style=display:flex><span>
|
||||
</span></span><span style=display:flex><span>diet_coke <span style=color:#f92672>=</span> Glass<span style=color:#f92672>.</span>Full(<span style=color:#e6db74>'diet coke'</span>)
|
||||
</span></span><span style=display:flex><span>empty <span style=color:#f92672>=</span> Glass<span style=color:#f92672>.</span>Empty()
|
||||
</span></span><span style=display:flex><span>
|
||||
</span></span><span style=display:flex><span>print(diet_coke<span style=color:#f92672>.</span>report_drink())
|
||||
</span></span><span style=display:flex><span>print(empty<span style=color:#f92672>.</span>is_empty())
|
||||
</span></span></code></pre></div><div class=container></div></div><pre tabindex=0><code>Ah a diet coke, what a fine taste!
|
||||
True
|
||||
</code></pre><h2 id=closing-thoughts>Closing thoughts</h2><p>Those 6 lines are the bare minimum to get well organized and namespaced
|
||||
algebraic enums in Python that are somewhat comparable to the ones in Rust. These
|
||||
enums also play nicely with static type checkers, <em>goto-definitions</em> will
|
||||
lead you to the correct class definition.</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,4 @@
|
||||
<!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>
|
||||
<!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 | 5 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>
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on lavafroth</title><link>https://lavafroth.is-a.dev/post/</link><description>Recent content in Posts 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/post/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 <a href="https://peps.python.org/pep-0636/">Python</a>.</p></description></item><item><title>NixOS Notes to Self</title><link>https://lavafroth.is-a.dev/post/nixos-notes-to-self/</link><pubDate>Sun, 14 Sep 2025 18:31:52 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/nixos-notes-to-self/</guid><description><p>A dedicated post collecting solutions to minor NixOS headaches.</p>
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on lavafroth</title><link>https://lavafroth.is-a.dev/post/</link><description>Recent content in Posts 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/post/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>Although Python has the answer to creating structs as
|
||||
<a href="https://peps.python.org/pep-0557/">dataclasses</a>, including support for
|
||||
<a href="https://peps.python.org/pep-0636/">structural match expressions</a> in recent
|
||||
versions, most tutorials will suggest <code>Union</code> types as the equivalent to Rust&rsquo;s
|
||||
enums.</p></description></item><item><title>NixOS Notes to Self</title><link>https://lavafroth.is-a.dev/post/nixos-notes-to-self/</link><pubDate>Sun, 14 Sep 2025 18:31:52 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/nixos-notes-to-self/</guid><description><p>A dedicated post collecting solutions to minor NixOS headaches.</p>
|
||||
<h2 id="nixos-rebuild-shows-no-network-activity"><code>nixos-rebuild</code> shows no network activity</h2>
|
||||
<p>On rare occasions, a system rebuild will get stuck while downloading a package from a source.
|
||||
No network activity, no timeout, no writes to the nix store.</p>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!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>
|
||||
<!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 | 5 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>
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
<?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 <a href="https://peps.python.org/pep-0636/">Python</a>.</p></description></item></channel></rss>
|
||||
<?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>Although Python has the answer to creating structs as
|
||||
<a href="https://peps.python.org/pep-0557/">dataclasses</a>, including support for
|
||||
<a href="https://peps.python.org/pep-0636/">structural match expressions</a> in recent
|
||||
versions, most tutorials will suggest <code>Union</code> types as the equivalent to Rust&rsquo;s
|
||||
enums.</p></description></item></channel></rss>
|
||||
@@ -1,4 +1,4 @@
|
||||
<!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>
|
||||
<!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 | 5 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>
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
<?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 <a href="https://peps.python.org/pep-0636/">Python</a>.</p></description></item></channel></rss>
|
||||
<?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>Although Python has the answer to creating structs as
|
||||
<a href="https://peps.python.org/pep-0557/">dataclasses</a>, including support for
|
||||
<a href="https://peps.python.org/pep-0636/">structural match expressions</a> in recent
|
||||
versions, most tutorials will suggest <code>Union</code> types as the equivalent to Rust&rsquo;s
|
||||
enums.</p></description></item></channel></rss>
|
||||
@@ -1,4 +1,4 @@
|
||||
<!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>
|
||||
<!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 | 5 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>
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
<?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 <a href="https://peps.python.org/pep-0636/">Python</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
|
||||
<?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>Although Python has the answer to creating structs as
|
||||
<a href="https://peps.python.org/pep-0557/">dataclasses</a>, including support for
|
||||
<a href="https://peps.python.org/pep-0636/">structural match expressions</a> in recent
|
||||
versions, most tutorials will suggest <code>Union</code> types as the equivalent to Rust&rsquo;s
|
||||
enums.</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,4 @@
|
||||
<!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>
|
||||
<!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 | 5 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>
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
<?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 <a href="https://peps.python.org/pep-0636/">Python</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>
|
||||
<?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>Although Python has the answer to creating structs as
|
||||
<a href="https://peps.python.org/pep-0557/">dataclasses</a>, including support for
|
||||
<a href="https://peps.python.org/pep-0636/">structural match expressions</a> in recent
|
||||
versions, most tutorials will suggest <code>Union</code> types as the equivalent to Rust&rsquo;s
|
||||
enums.</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>
|
||||
|
||||
Reference in New Issue
Block a user