diff --git a/app.min.css b/app.min.css index 73449877..76b62e61 100644 --- a/app.min.css +++ b/app.min.css @@ -1 +1 @@ -:root{--small-gap:2rem;--gap:2.5rem;--y-gap:8rem;--wide:140rem;--narrow:80rem;--side:calc((var(--wide) - var(--narrow)) / 2);--header:10rem;--footer:calc(8rem + var(--safe-bottom));--code-bg:#282828;--narrow-separator:0.2rem;color-scheme:light dark;--light:light-dark(#efefef, #161616);--dark:light-dark(#161616, #efefef);--safe-bottom:0}@supports(bottom:constant(safe-area-inset-bottom)){:root{--safe-bottom:constant(safe-area-inset-bottom)}}@supports(bottom:env(safe-area-inset-bottom)){:root{--safe-bottom:env(safe-area-inset-bottom)}}.site-name>svg{width:18rem;fill:var(--dark)}.math{padding:var(--gap);text-align:center}*,*::before,*::after{box-sizing:border-box;padding:0;margin:0;border:0}math *{padding:revert}html,body{height:100%}html{-webkit-tap-highlight-color:transparent;font-size:8px}search{margin-bottom:var(--gap);button { background: transparent; } input::placeholder { opacity: .5; }}body{--white:var(--light);--black:var(--dark);--pro:var(--dark);--lit:color-mix(in lab, var(--dark) 64%, transparent);--air:color-mix(in lab, var(--dark) 48%, transparent);--fog:color-mix(in lab, var(--dark) 12%, transparent);--faint:color-mix(in lab, var(--dark) 5%, transparent);--pagefind-ui-text:var(--pro) !important;--pagefind-ui-primary:var(--pro) !important;--pagefind-ui-background:var(--white) !important;--pagefind-ui-border:var(--fog) !important;--pagefind-ui-font:-apple-system, BlinkMacSystemFont, segoe ui, Roboto, Oxygen, Ubuntu, Cantarell, open sans, helvetica neue, sans-serif !important;--pagefind-ui-tag:var(--faint) !important;display:flex;flex-direction:column;padding:0 var(--gap);font-family:-apple-system,BlinkMacSystemFont,segoe ui,Roboto,Oxygen,Ubuntu,Cantarell,open sans,helvetica neue,sans-serif;font-size:2rem;line-height:1.8;color:var(--pro);word-break:break-word;background:var(--white)}body>*{flex-shrink:0;width:100%;margin-inline:auto}@media(max-width:1199px){html{font-size:7px}}abbr[title]{border-bottom:var(--narrow-separator)dotted;text-decoration:none}video{border-radius:1rem}math{font-family:LatinModern;font-size:2.5rem}.katex:has(math[display=block]){display:block;overflow-x:auto;overflow-y:clip}.collapsable-explanation{input { opacity: 0; position: absolute; } div:nth-last-child(1 of .highlight) { display: none; } &:has(input:checked) { div:nth-last-child(1 of .highlight) { display: block; } p, .highlight { display: none; } .container label { border: var(--narrow-separator) solid var(--pro); &::after { content: 'Expand explanation'; } } } .container { display: flex; justify-content: flex-end; align-items: center; gap: 1rem; label { transition: border-color 200ms; border: var(--narrow-separator) solid var(--fog); padding: var(--narrow-separator) var(--small-gap); border-radius: var(--gap); &::after { content: 'Collapse explanation'; } } &:first-child { margin-bottom: var(--gap); } &:last-child { margin: var(--gap) 0 var(--y-gap) 0; } &::before { content: ''; height: var(--narrow-separator); flex: 1; background: var(--fog); } }}.list-tag{background:var(--faint);color:var(--lit);padding:.25rem .75rem;border-radius:.5rem;z-index:3;position:relative;&::before { content:' '; position:absolute; z-index:1; }}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:700;line-height:1.2}strong,b{font-weight:700}a{color:inherit;text-decoration:none}table{width:100%;border-collapse:collapse}button,input,textarea{font:inherit;background:0 0;outline:none!important}button,input[type=button],input[type=submit]{cursor:pointer}input:-webkit-autofill,textarea:-webkit-autofill{box-shadow:0 0 0 6rem var(--white)inset}img{display:block;max-width:100%}header{max-width:var(--wide);margin-top:var(--gap);display:flex;align-items:center;border-radius:1rem;outline:.25rem solid var(--fog);position:relative;padding:var(--small-gap);gap:1rem;justify-content:space-between;nav { gap: 1rem; a { width: 4rem; height: 4rem; position: relative; &:after { width: 3rem; height: 3rem; top: .5rem; left: .5rem; background: var(--black); mask-image: var(--url); mask-repeat: no-repeat; mask-size: cover; } } } nav a:after, &:after { z-index: -100; content: ""; position: absolute; } &:after { width: 100%; height: 100%; left: 0; background: var(--fog); mask-image: url('header.svg'); mask-size: 24rem; } a.active { outline: 2px solid var(--air); border-radius: 50%; }}main{max-width:var(--narrow);flex:1;padding-top:var(--gap);padding-bottom:var(--y-gap)}nav[data-main]{justify-content:space-between;margin-top:var(--gap);a { font-size: 1.8rem; line-height: 5.5rem; font-weight: 500; background: var(--faint); color: var(--lit); border-radius: 0.5rem; padding-inline: 3rem; &[href="#"] { visibility: hidden; } }}article{position:relative;padding-block:2rem;transition:transform .1s;&:active { transform:scale(0.99); } h2 { margin-bottom:0.2rem; font-size:3rem; } time { flex-shrink:0; font-size:1.7rem; color:var(--air); }}.post-link{position:absolute;inset:0}hgroup{margin-bottom:var(--y-gap);p { display: flex; margin-top: 0.4rem; margin-bottom: 1.1rem; font-size: 1.6rem; color: var(--air); } p span::before { content: '·'; margin-inline: 0.8rem; } h1 { font-size: 5rem; }}.post-tags{margin-top:var(--y-gap);a { display: inline-block; font-weight: 500; line-height: 5rem; color: var(--lit); background: var(--faint); border-radius: 0.5rem; padding-inline: 2rem; } a+a { margin-left: 0.5rem; margin-bottom: 0.8rem; }}nav{display:flex}nav[data-post]{justify-content:space-between;margin-top:var(--y-gap);background:var(--faint);border-radius:.5rem;a { display: flex; gap: 1rem; align-items: center; width: 50%; padding: var(--gap); font-size: 2.4rem; font-weight: 700; line-height: 1.2; padding-inline: 1rem; } a:nth-child(2) { justify-content: flex-end; margin-left: auto; }}.post-comments{margin-top:var(--y-gap)}@media(max-width:1199px){.post-title{display:block;aside { flex-direction: row; width: auto; padding-right: 0; margin-bottom: 0.5rem; margin-left: 0; transform: none; span::before { content: '·'; margin-inline: 0.5rem; } }}}.post-content{font-size:2.2rem;h1, h2, h3, h4, h5, h6 { margin-block: 2rem; } h1 { margin-top: var(--y-gap); font-size: 4.5rem; } h2 { margin-top: 6rem; font-size: 3.5rem; } h3 { font-size: 2.5rem; } h4 { font-size: 2.2rem; } h5 { font-size: 1.8rem; } h6 { font-size: 1.5rem; } img { margin-inline: auto; } a { padding-bottom: 0.2rem; font-weight: 500; border-bottom: 2px solid var(--pro); code { margin-inline: 0; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } } del { text-decoration: none; background: linear-gradient(to right, var(--pro) 100%, transparent 0) 0 50% / 1px 1px repeat-x; } p, ul, ol, dl, details { margin-bottom: 3rem; } ul, ol { padding-left: 2.5rem; } li { margin-top: 0.6rem; } dl { display: flex; flex-wrap: wrap; margin: 0; } dt { width: 25%; font-weight: 500; } dd { width: 75%; padding-left: 1.3rem; margin-left: 0; } dt~dt, dd~dd { margin-top: 1.3rem; } table { margin-bottom: 4rem; th { font-size: 2.6rem; text-align: left; } th, td { word-break: normal; padding: 1.5rem 1rem; line-height: 1.5; border-bottom: 1px solid var(--fog); } td:has(code) { inline-size: var(--wide); word-break: break-all; overflow-wrap: break-word; } td code:only-of-type { margin-inline: 0; } } .highlight, pre { margin: 0 calc(var(--gap) * -1) 4rem; overflow-x: auto; background: var(--code-bg) !important; border-radius: 0.5rem; } ul pre { margin-left: calc(var(--gap) * -2); } .highlight pre { margin-inline: 0; margin-bottom: 0; } code { padding: 0.5rem 1rem; margin-inline: 0.5rem; font-family: Menlo, Monaco, 'Courier New', Courier, monospace; font-size: 0.8em; line-height: 1.5; background: var(--faint); border-radius: 0.3rem; } pre code { display: block; padding: var(--gap); margin-inline: 0; color: rgba(255, 255, 255, 0.8); background: transparent; border-radius: 0; } blockquote { padding: 0 0 0 calc(var(--gap) - 0.4rem); margin: 0 0 0 calc(var(--gap) * -1); border-left: 0.4rem solid var(--pro); } hr { height: var(--narrow-separator); background: var(--fog); margin-block: 12rem; } iframe { width: 100%; background: var(--black); }}.footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;max-width:var(--narrow);height:var(--footer);padding-bottom:var(--safe-bottom);margin-top:auto;font-size:1.6rem;color:var(--lit);border-top:1px solid var(--fog);p+p::before { content: '·'; margin-inline: 0.6rem; } a:hover { color: var(--pro); border-bottom: 1px solid var(--pro); }}.title-404{align-content:center;text-align:center;height:100%;font-size:16rem}@font-face{font-family:LatinModern;src:url(latinmodern-math.otf);font-display:swap} \ No newline at end of file +:root{--small-gap:2rem;--gap:2.5rem;--y-gap:8rem;--wide:140rem;--narrow:80rem;--side:calc((var(--wide) - var(--narrow)) / 2);--header:10rem;--footer:calc(8rem + var(--safe-bottom));--code-bg:#282828;--narrow-separator:0.2rem;color-scheme:light dark;--light:light-dark(#efefef, #161616);--dark:light-dark(#161616, #efefef);--safe-bottom:0}@supports(bottom:constant(safe-area-inset-bottom)){:root{--safe-bottom:constant(safe-area-inset-bottom)}}@supports(bottom:env(safe-area-inset-bottom)){:root{--safe-bottom:env(safe-area-inset-bottom)}}.site-name>svg{width:18rem;fill:var(--dark)}.math{padding:var(--gap);text-align:center}*,*::before,*::after{box-sizing:border-box;padding:0;margin:0;border:0}math *{padding:revert}html,body{height:100%}html{-webkit-tap-highlight-color:transparent;font-size:8px}search{margin-bottom:var(--gap);button { background: transparent; } input::placeholder { opacity: .5; }}body{--white:var(--light);--black:var(--dark);--pro:var(--dark);--lit:color-mix(in lab, var(--dark) 64%, transparent);--air:color-mix(in lab, var(--dark) 48%, transparent);--fog:color-mix(in lab, var(--dark) 12%, transparent);--faint:color-mix(in lab, var(--dark) 5%, transparent);--pagefind-ui-text:var(--pro) !important;--pagefind-ui-primary:var(--pro) !important;--pagefind-ui-background:var(--white) !important;--pagefind-ui-border:var(--fog) !important;--pagefind-ui-font:-apple-system, BlinkMacSystemFont, segoe ui, Roboto, Oxygen, Ubuntu, Cantarell, open sans, helvetica neue, sans-serif !important;--pagefind-ui-tag:var(--faint) !important;display:flex;flex-direction:column;padding:0 var(--gap);font-family:-apple-system,BlinkMacSystemFont,segoe ui,Roboto,Oxygen,Ubuntu,Cantarell,open sans,helvetica neue,sans-serif;font-size:2rem;line-height:1.8;color:var(--pro);word-break:break-word;background:var(--white)}body>*{flex-shrink:0;width:100%;margin-inline:auto}@media(max-width:1199px){html{font-size:7px}}abbr[title]{border-bottom:var(--narrow-separator)dotted;text-decoration:none}video{border-radius:1rem}math{font-family:LatinModern;font-size:2.5rem}.katex:has(math[display=block]){display:block;overflow-x:auto;overflow-y:clip}.collapsable-explanation{input { opacity: 0; position: absolute; } div:nth-last-child(1 of .highlight) { display: none; } &:has(input:checked) { div:nth-last-child(1 of .highlight) { display: block; } p, .highlight { display: none; } .container label { border: var(--narrow-separator) solid var(--pro); &::after { content: 'Expand explanation'; } } } .container { display: flex; justify-content: flex-end; align-items: center; gap: 1rem; label { transition: border-color 200ms; border: var(--narrow-separator) solid var(--fog); padding: var(--narrow-separator) var(--small-gap); border-radius: var(--gap); &::after { content: 'Collapse explanation'; } } &:first-child { margin-bottom: var(--gap); } &:last-child { margin: var(--gap) 0 var(--y-gap) 0; } &::before { content: ''; height: var(--narrow-separator); flex: 1; background: var(--fog); } }}.list-tag{background:var(--faint);color:var(--lit);padding:.25rem .75rem;border-radius:.5rem;z-index:3;position:relative;&::before { content:' '; position:absolute; z-index:1; }}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:700;line-height:1.2}strong,b{font-weight:700}a{color:inherit;text-decoration:none}table{width:100%;border-collapse:collapse}button,input,textarea{font:inherit;background:0 0;outline:none!important}button,input[type=button],input[type=submit]{cursor:pointer}input:-webkit-autofill,textarea:-webkit-autofill{box-shadow:0 0 0 6rem var(--white)inset}img{display:block;max-width:100%}header{max-width:var(--wide);margin-top:var(--gap);display:flex;align-items:center;border-radius:1rem;outline:.25rem solid var(--fog);position:relative;padding:var(--small-gap);gap:1rem;justify-content:space-between;nav { gap: 1rem; a { width: 4rem; height: 4rem; position: relative; &:after { width: 3rem; height: 3rem; top: .5rem; left: .5rem; background: var(--black); mask-image: var(--url); mask-repeat: no-repeat; mask-size: cover; } } } nav a:after, &:after { z-index: -100; content: ""; position: absolute; } &:after { width: 100%; height: 100%; left: 0; background: var(--fog); mask-image: url('header.svg'); mask-size: 24rem; } a.active { outline: 2px solid var(--air); border-radius: 50%; }}main{max-width:var(--narrow);flex:1;padding-top:var(--gap);padding-bottom:var(--y-gap)}nav[data-main]{justify-content:space-between;margin-top:var(--gap);a { font-size: 1.8rem; line-height: 5.5rem; font-weight: 500; background: var(--faint); color: var(--lit); border-radius: 0.5rem; padding-inline: 3rem; &[href="#"] { visibility: hidden; } }}article{position:relative;padding-block:2rem;transition:transform .1s;&:active { transform:scale(0.99); } h2 { margin-bottom:0.2rem; font-size:3rem; } time { flex-shrink:0; font-size:1.7rem; color:var(--air); }}.post-link{position:absolute;inset:0}hgroup{margin-bottom:var(--y-gap);p { display: flex; margin-top: 0.4rem; margin-bottom: 1.1rem; font-size: 1.6rem; color: var(--air); } p span::before { content: '·'; margin-inline: 0.8rem; } h1 { font-size: 5rem; }}.post-tags{margin-top:var(--y-gap);a { display: inline-block; font-weight: 500; line-height: 5rem; color: var(--lit); background: var(--faint); border-radius: 0.5rem; padding-inline: 2rem; } a+a { margin-left: 0.5rem; margin-bottom: 0.8rem; }}nav{display:flex}nav[data-post]{justify-content:space-between;margin-top:var(--y-gap);background:var(--faint);border-radius:.5rem;a { display: flex; gap: 1rem; align-items: center; width: 50%; padding: var(--gap); font-size: 2.4rem; font-weight: 700; line-height: 1.2; padding-inline: 1rem; } a:nth-child(2) { justify-content: flex-end; margin-left: auto; }}.post-comments{margin-top:var(--y-gap)}@media(max-width:1199px){.post-title{display:block;aside { flex-direction: row; width: auto; padding-right: 0; margin-bottom: 0.5rem; margin-left: 0; transform: none; span::before { content: '·'; margin-inline: 0.5rem; } }}}.post-content{font-size:2.2rem;h1, h2, h3, h4, h5, h6 { margin-block: 2rem; } h1 { margin-top: var(--y-gap); font-size: 4.5rem; } h2 { margin-top: 6rem; font-size: 3.5rem; } h3 { font-size: 3rem; } h4 { font-size: 2.5rem; } h5 { font-size: 2.2rem; } h6 { font-size: 1.8rem; } img { margin-inline: auto; } a { padding-bottom: 0.2rem; font-weight: 500; border-bottom: 2px solid var(--pro); code { margin-inline: 0; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } } del { text-decoration: none; background: linear-gradient(to right, var(--pro) 100%, transparent 0) 0 50% / 1px 1px repeat-x; } p, ul, ol, dl, details { margin-bottom: 3rem; } ul, ol { padding-left: 2.5rem; } li { margin-top: 0.6rem; } dl { display: flex; flex-wrap: wrap; margin: 0; } dt { width: 25%; font-weight: 500; } dd { width: 75%; padding-left: 1.3rem; margin-left: 0; } dt~dt, dd~dd { margin-top: 1.3rem; } table { margin-bottom: 4rem; th { font-size: 2.6rem; text-align: left; } th, td { word-break: normal; padding: 1.5rem 1rem; line-height: 1.5; border-bottom: 1px solid var(--fog); } td:has(code) { inline-size: var(--wide); word-break: break-all; overflow-wrap: break-word; } td code:only-of-type { margin-inline: 0; } } .highlight, pre { margin: 0 calc(var(--gap) * -1) 4rem; overflow-x: auto; background: var(--code-bg) !important; border-radius: 0.5rem; } ul pre { margin-left: calc(var(--gap) * -2); } .highlight pre { margin-inline: 0; margin-bottom: 0; } code { padding: 0.5rem 1rem; margin-inline: 0.5rem; font-family: Menlo, Monaco, 'Courier New', Courier, monospace; font-size: 0.8em; line-height: 1.5; background: var(--faint); border-radius: 0.3rem; } pre code { display: block; padding: var(--gap); margin-inline: 0; color: rgba(255, 255, 255, 0.8); background: transparent; border-radius: 0; } blockquote { padding: 0 0 0 calc(var(--gap) - 0.4rem); margin: 0 0 0 calc(var(--gap) * -1); border-left: 0.4rem solid var(--pro); } hr { height: var(--narrow-separator); background: var(--fog); margin-block: 12rem; } iframe { width: 100%; background: var(--black); }}.footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;max-width:var(--narrow);height:var(--footer);padding-bottom:var(--safe-bottom);margin-top:auto;font-size:1.6rem;color:var(--lit);border-top:1px solid var(--fog);p+p::before { content: '·'; margin-inline: 0.6rem; } a:hover { color: var(--pro); border-bottom: 1px solid var(--pro); }}.title-404{align-content:center;text-align:center;height:100%;font-size:16rem}@font-face{font-family:LatinModern;src:url(latinmodern-math.otf);font-display:swap} \ No newline at end of file diff --git a/index.html b/index.html index b84e3862..e70c06af 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ -lavafroth

Algebraic Python Enums


Python +lavafroth

Algebraic Python Enums


Python Decorators Rust Algebraic Data Types diff --git a/index.xml b/index.xml index a77e1b59..a39475a2 100644 --- a/index.xml +++ b/index.xml @@ -1,6 +1,13 @@ -lavafrothhttps://lavafroth.is-a.dev/Recent content on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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>note skta4v7n8h8https://lavafroth.is-a.dev/skta4v7n8h8/Fri, 31 Oct 2025 20:24:35 +0530https://lavafroth.is-a.dev/skta4v7n8h8/<h1 id="grpa-1">GrPA 1</h1> +lavafrothhttps://lavafroth.is-a.dev/Recent content on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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>note skta4v7n8h8https://lavafroth.is-a.dev/skta4v7n8h8/Fri, 31 Oct 2025 20:24:35 +0530https://lavafroth.is-a.dev/skta4v7n8h8/<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> diff --git a/pagefind/fragment/en-us_37caf2f.pf_fragment b/pagefind/fragment/en-us_37caf2f.pf_fragment deleted file mode 100644 index 35aeccd4..00000000 Binary files a/pagefind/fragment/en-us_37caf2f.pf_fragment and /dev/null differ diff --git a/pagefind/fragment/en-us_ff9e431.pf_fragment b/pagefind/fragment/en-us_ff9e431.pf_fragment new file mode 100644 index 00000000..3a2632cc Binary files /dev/null and b/pagefind/fragment/en-us_ff9e431.pf_fragment differ diff --git a/pagefind/index/en-us_18656bc.pf_index b/pagefind/index/en-us_18656bc.pf_index new file mode 100644 index 00000000..cd282d43 Binary files /dev/null and b/pagefind/index/en-us_18656bc.pf_index differ diff --git a/pagefind/index/en-us_2b3b249.pf_index b/pagefind/index/en-us_2b3b249.pf_index deleted file mode 100644 index b9f76df6..00000000 Binary files a/pagefind/index/en-us_2b3b249.pf_index and /dev/null differ diff --git a/pagefind/index/en-us_569df36.pf_index b/pagefind/index/en-us_569df36.pf_index new file mode 100644 index 00000000..e65b2a34 Binary files /dev/null and b/pagefind/index/en-us_569df36.pf_index differ diff --git a/pagefind/index/en-us_72a0d44.pf_index b/pagefind/index/en-us_72a0d44.pf_index deleted file mode 100644 index 9d465615..00000000 Binary files a/pagefind/index/en-us_72a0d44.pf_index and /dev/null differ diff --git a/pagefind/index/en-us_8a17e7e.pf_index b/pagefind/index/en-us_8a17e7e.pf_index deleted file mode 100644 index 6c9751c3..00000000 Binary files a/pagefind/index/en-us_8a17e7e.pf_index and /dev/null differ diff --git a/pagefind/index/en-us_93e47fa.pf_index b/pagefind/index/en-us_93e47fa.pf_index deleted file mode 100644 index f90e3f4e..00000000 Binary files a/pagefind/index/en-us_93e47fa.pf_index and /dev/null differ diff --git a/pagefind/index/en-us_979d23c.pf_index b/pagefind/index/en-us_979d23c.pf_index deleted file mode 100644 index ede4e094..00000000 Binary files a/pagefind/index/en-us_979d23c.pf_index and /dev/null differ diff --git a/pagefind/index/en-us_c668e46.pf_index b/pagefind/index/en-us_c668e46.pf_index deleted file mode 100644 index c4ec96ad..00000000 Binary files a/pagefind/index/en-us_c668e46.pf_index and /dev/null differ diff --git a/pagefind/index/en-us_ce84bb8.pf_index b/pagefind/index/en-us_ce84bb8.pf_index new file mode 100644 index 00000000..46364028 Binary files /dev/null and b/pagefind/index/en-us_ce84bb8.pf_index differ diff --git a/pagefind/index/en-us_e2f7899.pf_index b/pagefind/index/en-us_e2f7899.pf_index new file mode 100644 index 00000000..654d7d69 Binary files /dev/null and b/pagefind/index/en-us_e2f7899.pf_index differ diff --git a/pagefind/index/en-us_eec299e.pf_index b/pagefind/index/en-us_eec299e.pf_index new file mode 100644 index 00000000..e24c54f8 Binary files /dev/null and b/pagefind/index/en-us_eec299e.pf_index differ diff --git a/pagefind/index/en-us_f767589.pf_index b/pagefind/index/en-us_f767589.pf_index new file mode 100644 index 00000000..26663b88 Binary files /dev/null and b/pagefind/index/en-us_f767589.pf_index differ diff --git a/pagefind/pagefind-entry.json b/pagefind/pagefind-entry.json index c9741368..7e7597e5 100644 --- a/pagefind/pagefind-entry.json +++ b/pagefind/pagefind-entry.json @@ -1 +1 @@ -{"version":"1.0.3","languages":{"en-us":{"hash":"en-us_6a23f48a599dc","wasm":"en-us","page_count":58}}} \ No newline at end of file +{"version":"1.0.3","languages":{"en-us":{"hash":"en-us_f3d6bd8299974","wasm":"en-us","page_count":58}}} \ No newline at end of file diff --git a/pagefind/pagefind.en-us_6a23f48a599dc.pf_meta b/pagefind/pagefind.en-us_6a23f48a599dc.pf_meta deleted file mode 100644 index 776eee72..00000000 Binary files a/pagefind/pagefind.en-us_6a23f48a599dc.pf_meta and /dev/null differ diff --git a/pagefind/pagefind.en-us_f3d6bd8299974.pf_meta b/pagefind/pagefind.en-us_f3d6bd8299974.pf_meta new file mode 100644 index 00000000..2b7e0adb Binary files /dev/null and b/pagefind/pagefind.en-us_f3d6bd8299974.pf_meta differ diff --git a/post/algebraic-python-enums/index.html b/post/algebraic-python-enums/index.html index 73a5a9b2..e92c96dd 100644 --- a/post/algebraic-python-enums/index.html +++ b/post/algebraic-python-enums/index.html @@ -1,6 +1,21 @@ -Algebraic Python Enums - lavafroth

Algebraic Python Enums

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.

To that end, creating the equivalent to Rust’s enum types involves Python union types.

First draft

# glass_enum.py
+Algebraic Python Enums - lavafroth

Algebraic Python Enums

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.

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.

Naive draft

# glass_enum.py
 
 from dataclasses import dataclass
 
@@ -19,8 +34,63 @@ Fortunately, since Python 3.8, creating structs has been a breeze using the data
       return "Whoops, looks like you've finished your drink!"
     case Full(drink):
       return f"Ah a {drink}, what a fine taste!"
-

Pitfalls

No direct variant access

Since there is no namespacing, we also can’t instantiate variants under the Glass namespace. The following code does not work.

dr_pepper = Glass.Full("Dr. Pepper")
-

This can be partially solved by putting the entire enumerable type inside a module. +

For example

dr_pepper = Full('Dr. Pepper')
+print(report_drink(dr_pepper))
+
# glass_enum.py
+
+from dataclasses import dataclass
+
+@dataclass
+class Empty:
+  pass
+
+@dataclass
+class Full:
+  drink: str
+
+Glass = Empty | Full
+
+def report_drink(glass: Glass) -> str:
+  match glass:
+    case Empty():
+      return "Whoops, looks like you've finished your drink!"
+    case Full(drink):
+      return f"Ah a {drink}, what a fine taste!"
+
+dr_pepper = Full('Dr. Pepper')
+print(report_drink(dr_pepper))
+

Will output

Ah a Dr. Pepper, what a fine taste!
+

Pitfalls

No direct variant access

What if we had another Union with same variant names in the same file?

@dataclass
+class Full:
+  gold: int
+  gems: int
+
+@dataclass
+class Empty:
+  pass
+
+Inventory = Full | Empty
+player_inventory = Full(500, 50)
+

Now we try to instantiate a Glass Full of lemonade.

lemonade = Full("lemonade")
+
@dataclass
+class Full:
+  gold: int
+  gems: int
+
+@dataclass
+class Empty:
+  pass
+
+Inventory = Full | Empty
+player_inventory = Full(500, 50)
+lemonade = Full("lemonade")
+

Python will error out since Full now refers to the new variant of the +union type Inventory.

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'
+

We can’t instantiate variants as members of the Glass namespace. The following code does not work.

dr_pepper = Glass.Full("Dr. Pepper")
+

This can be partially solved by keeping just the Glass type inside a module. Here we have saved the file as glass_enum.py. From a different module we can access the variants as glass_enum.Empty and glass_enum.Full.

# main.py
 import glass_enum
@@ -30,12 +100,14 @@ access the variants as glass_enum.Empty and glass_enum.Full

Now any function outside the module has to ingest a rather confusing argument of type glass_enum.Glass.

def refill(glass: glass_enum.Glass) -> glass_enum.Glass:
   # ...
   return glass
-

Since using a module namespace only causes more confusion, we will discard this idea.

No methods on the enum itself

With no namespaceing, methods cannot be defined on the Union of the different variants.

In the case of our concrete example, we can’t add methods to the Glass type.

def refill(glass: Glass) -> Glass:
+

Since module namespacing only causes more confusion, we will discard this idea.

No methods on the enum itself

Python also disallows methods from being defined on Union types. +In the case of our concrete example, we can’t add methods to the Glass type.

The following code uses a hypothetical is_empty() method on the Glass union +type which is not allowed. Hence the code won’t run.

def refill(glass: Glass) -> Glass:
   if glass.is_empty(): # can't implement on type `Glass` directly
     return Full('water')
   return glass
-

Even if we use module level namespacing, it’s simply not possible to define any method on a Union type in Python.

To define a method like is_empty(), it must be implemented on both the classes Full and Empty. This can get -tedious if there are 3 or more variants.

Python is a sneaky language

Last week I discovered that Python allows creating nested classes to keep things organized.

from dataclasses import dataclass
+

To define a method like is_empty(), it must be implemented on both the classes +Full and Empty. This gets tedious for 3 or more variants.

Python is a sneaky language

Last week I discovered that Python allows creating nested classes to keep things organized.

from dataclasses import dataclass
 
 class Glass:
   @dataclass
@@ -46,7 +118,7 @@ tedious if there are 3 or more variants.

P class Full: drink: str

Python will happily run the above code and we can access the “variants” under the Glass namespace.

lemonade = Glass.Full('lemonade')
-

If only we could register the variants as the Glass type itself and inherit all its methods.

Redecorate

We can define a decorator that takes all of the nested dataclasses and makes them inherit the outer class.

import inspect
+

If only we could register the variants as the Glass type itself and inherit all its methods.

Redecorate

We can define a decorator that takes all of the nested dataclasses and makes them inherit the outer class.

import inspect
 
 def AlgebraicEnum(cls):
     for subclass_name, subclass in inspect.getmembers(cls, predicate=inspect.isclass):
@@ -54,7 +126,8 @@ tedious if there are 3 or more variants.

P setattr(cls, subclass_name, type(subclass_name, (cls, subclass), {})) return cls -

That’s all there is to the magic! Now we can simply add this decorator above the previous class declaration +

The inheritance means all methods of the outer class are available on the nested +classes and any object of a nested class isinstance of the outer class.

That’s all there is to the magic! Now we can simply add this decorator above the previous class declaration and the variants like Glass.Empty and Glass.Full would be of the type Glass.

from dataclasses import dataclass
 
 @AlgebraicEnum
@@ -67,22 +140,71 @@ and the variants like Glass.Empty and Glass.Full would
   class Full:
     drink: str
 
-  def report_drink(self) -> str:
+  def report_drink(self: 'Glass') -> str:
     match self:
       case Glass.Empty():
         return "Whoops, looks like you've finished your drink!"
       case Glass.Full(drink):
         return f"Ah a {drink}, what a fine taste!"
 
-  def is_empty(self) -> str:
+  def is_empty(self: 'Glass') -> bool:
     match self:
       case Glass.Empty():
         return True
     return False
 

As a bonus, the variants will also inherit any methods defined on the Glass type.

Note how the report_drink method accepts a self of type Glass and the match arms -compare it with Glass.Empty and Glass.Full.

These methods get automatically called via the method resolution order chain due to the inheritance.

Closing thoughts

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 goto-definitions will also lead you to the correct class defining a variant or the enum itself.

I have packaged this decorator with a couple more typing restrictions into a library at github:lavafroth/ape.

I hope you enjoyed this foray into contorting Python.

Python +compare it with Glass.Empty and Glass.Full.

These methods get automatically called via the method resolution order chain due to the inheritance.

The following code runs just fine.

diet_coke = Glass.Full('diet coke')
+empty = Glass.Empty()
+
+print(diet_coke.report_drink())
+print(empty.is_empty())
+
import inspect
+from dataclasses import dataclass
+
+
+def AlgebraicEnum(cls):
+    for subclass_name, subclass in inspect.getmembers(cls, predicate=inspect.isclass):
+        if subclass_name != "__class__":
+            setattr(cls, subclass_name, type(subclass_name, (cls, subclass), {}))
+
+    return cls
+
+
+@AlgebraicEnum
+class Glass:
+  @dataclass
+  class Empty:
+    pass
+
+  @dataclass
+  class Full:
+    drink: str
+
+  def report_drink(self: 'Glass') -> str:
+    match self:
+      case Glass.Empty():
+        return "Whoops, looks like you've finished your drink!"
+      case Glass.Full(drink):
+        return f"Ah a {drink}, what a fine taste!"
+
+  def is_empty(self: 'Glass') -> bool:
+    match self:
+      case Glass.Empty():
+        return True
+    return False
+
+
+diet_coke = Glass.Full('diet coke')
+empty = Glass.Empty()
+
+print(diet_coke.report_drink())
+print(empty.is_empty())
+
Ah a diet coke, what a fine taste!
+True
+

Closing thoughts

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, goto-definitions will +lead you to the correct class definition.

I have packaged this decorator with a couple more typing restrictions into a library at github:lavafroth/ape.

I hope you enjoyed this foray into contorting Python.

\ No newline at end of file diff --git a/post/index.html b/post/index.html index 4418468a..44b7a64b 100644 --- a/post/index.html +++ b/post/index.html @@ -1,4 +1,4 @@ -Posts - lavafroth

Algebraic Python Enums


Python +Posts - lavafroth

Algebraic Python Enums


Python Decorators Rust Algebraic Data Types diff --git a/post/index.xml b/post/index.xml index f9d1c768..80982987 100644 --- a/post/index.xml +++ b/post/index.xml @@ -1,6 +1,13 @@ -Posts on lavafrothhttps://lavafroth.is-a.dev/post/Recent content in Posts on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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>NixOS Notes to Selfhttps://lavafroth.is-a.dev/post/nixos-notes-to-self/Sun, 14 Sep 2025 18:31:52 +0530https://lavafroth.is-a.dev/post/nixos-notes-to-self/<p>A dedicated post collecting solutions to minor NixOS headaches.</p> +Posts on lavafrothhttps://lavafroth.is-a.dev/post/Recent content in Posts on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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>NixOS Notes to Selfhttps://lavafroth.is-a.dev/post/nixos-notes-to-self/Sun, 14 Sep 2025 18:31:52 +0530https://lavafroth.is-a.dev/post/nixos-notes-to-self/<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> diff --git a/tags/algebraic-data-types/index.html b/tags/algebraic-data-types/index.html index 5c620dbe..3e642716 100644 --- a/tags/algebraic-data-types/index.html +++ b/tags/algebraic-data-types/index.html @@ -1,4 +1,4 @@ -Algebraic Data Types - lavafroth

Algebraic Python Enums


Python +Algebraic Data Types - lavafroth

Algebraic Python Enums


Python Decorators Rust Algebraic Data Types diff --git a/tags/algebraic-data-types/index.xml b/tags/algebraic-data-types/index.xml index aee5d614..dd50589c 100644 --- a/tags/algebraic-data-types/index.xml +++ b/tags/algebraic-data-types/index.xml @@ -1,3 +1,10 @@ -Algebraic Data Types on lavafrothhttps://lavafroth.is-a.dev/tags/algebraic-data-types/Recent content in Algebraic Data Types on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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> \ No newline at end of file +Algebraic Data Types on lavafrothhttps://lavafroth.is-a.dev/tags/algebraic-data-types/Recent content in Algebraic Data Types on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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> \ No newline at end of file diff --git a/tags/decorators/index.html b/tags/decorators/index.html index c676fe2e..076f297d 100644 --- a/tags/decorators/index.html +++ b/tags/decorators/index.html @@ -1,4 +1,4 @@ -Decorators - lavafroth

Algebraic Python Enums


Python +Decorators - lavafroth

Algebraic Python Enums


Python Decorators Rust Algebraic Data Types diff --git a/tags/decorators/index.xml b/tags/decorators/index.xml index 823fdad4..274ac849 100644 --- a/tags/decorators/index.xml +++ b/tags/decorators/index.xml @@ -1,3 +1,10 @@ -Decorators on lavafrothhttps://lavafroth.is-a.dev/tags/decorators/Recent content in Decorators on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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> \ No newline at end of file +Decorators on lavafrothhttps://lavafroth.is-a.dev/tags/decorators/Recent content in Decorators on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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> \ No newline at end of file diff --git a/tags/python/index.html b/tags/python/index.html index fed1e5db..0d55b150 100644 --- a/tags/python/index.html +++ b/tags/python/index.html @@ -1,4 +1,4 @@ -Python - lavafroth

Algebraic Python Enums


Python +Python - lavafroth

Algebraic Python Enums


Python Decorators Rust Algebraic Data Types diff --git a/tags/python/index.xml b/tags/python/index.xml index a27138d1..fd75b2e9 100644 --- a/tags/python/index.xml +++ b/tags/python/index.xml @@ -1,6 +1,13 @@ -Python on lavafrothhttps://lavafroth.is-a.dev/tags/python/Recent content in Python on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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>PicoCTF SansAlpha Writeuphttps://lavafroth.is-a.dev/post/picoctf-sansalpha-writeup/Sun, 05 Jan 2025 11:55:52 +0530https://lavafroth.is-a.dev/post/picoctf-sansalpha-writeup/<p>Hey everyone, since 2024 hasn&rsquo;t seen a lot of posts on this blog, I plan to +Python on lavafrothhttps://lavafroth.is-a.dev/tags/python/Recent content in Python on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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>PicoCTF SansAlpha Writeuphttps://lavafroth.is-a.dev/post/picoctf-sansalpha-writeup/Sun, 05 Jan 2025 11:55:52 +0530https://lavafroth.is-a.dev/post/picoctf-sansalpha-writeup/<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> diff --git a/tags/rust/index.html b/tags/rust/index.html index d8bbb120..c4ee2cd6 100644 --- a/tags/rust/index.html +++ b/tags/rust/index.html @@ -1,4 +1,4 @@ -Rust - lavafroth

Algebraic Python Enums


Python +Rust - lavafroth

Algebraic Python Enums


Python Decorators Rust Algebraic Data Types diff --git a/tags/rust/index.xml b/tags/rust/index.xml index dad1a4c1..b27dc0a4 100644 --- a/tags/rust/index.xml +++ b/tags/rust/index.xml @@ -1,6 +1,13 @@ -Rust on lavafrothhttps://lavafroth.is-a.dev/tags/rust/Recent content in Rust on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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>Wrapping up GSoC 2024https://lavafroth.is-a.dev/post/the-gsoc-grand-finale/Sat, 24 Aug 2024 10:28:50 +0530https://lavafroth.is-a.dev/post/the-gsoc-grand-finale/<h1 id="overview">Overview</h1> +Rust on lavafrothhttps://lavafroth.is-a.dev/tags/rust/Recent content in Rust on lavafrothHugoen-usSun, 02 Nov 2025 19:08:46 +0530Algebraic Python Enumshttps://lavafroth.is-a.dev/post/algebraic-python-enums/Sun, 02 Nov 2025 19:08:46 +0530https://lavafroth.is-a.dev/post/algebraic-python-enums/<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>Wrapping up GSoC 2024https://lavafroth.is-a.dev/post/the-gsoc-grand-finale/Sat, 24 Aug 2024 10:28:50 +0530https://lavafroth.is-a.dev/post/the-gsoc-grand-finale/<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>