<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://theleafslug.com/" xml:lang="en"><title xml:base="https://theleafslug.com" xml:lang="en">The Leafslug</title><id>https://prma.dev/</id><updated>2026-05-08T10:42:33+00:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><icon>https://theleafslug.com/assets/logo/favicon.svg</icon><link href="https://theleafslug.com/" rel="alternate" hreflang="en" type="text/html" title="The Leafslug"/><logo>https://theleafslug.com/assets/logo/logo.svg</logo><rights xml:base="https://theleafslug.com" xml:lang="en">© 2022-2026 Amirhossein Alesheikh. All rights reserved.</rights><subtitle xml:base="https://theleafslug.com" xml:lang="en">The Feed of The Leafslug, containing all the categories and tags</subtitle><entry><title xml:base="https://theleafslug.com" xml:lang="en">Democracy</title><id>urn:uuid:e76d7926-26e9-4cff-b798-2d18b7c1066e</id><updated>2026-04-18T10:05:05+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="politics" label="politics"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/democracy" rel="alternate" hreflang="en" type="text/html"/><published>2026-04-18T10:05:05+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Democracy is not treated the same by everyone</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;There is a left and a right in politics.&lt;/p&gt;
&lt;p&gt;And there are people that agree mostly with the left.&lt;/p&gt;
&lt;p&gt;And people that agree mostly with the right.&lt;/p&gt;
&lt;p&gt;And people that find it easier to be on the left.&lt;/p&gt;
&lt;p&gt;And people that find it easier to be on the right.
And people who find left beneficial to them.&lt;/p&gt;
&lt;p&gt;And people who find right beneficial to them.&lt;/p&gt;
&lt;p&gt;And people who love the ecstasy of being fans of the left.&lt;/p&gt;
&lt;p&gt;And people who love the ecstasy of being fans of the right.&lt;/p&gt;
&lt;p&gt;And people that just enjoy watching the game.&lt;/p&gt;
&lt;p&gt;And players. They win or lose. It’s only a game to them.&lt;/p&gt;
&lt;p&gt;And people who organize the game, not caring which side wins, as long as the tickets are sold.&lt;/p&gt;
&lt;p&gt;But at the end, it’s just a game, &lt;em&gt;when&lt;/em&gt; the left and the right are only fans and players.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Fucking Black-Hats</title><id>urn:uuid:c84a4c0b-0c16-4ce3-b507-06d15f37e585</id><updated>2026-04-07T15:09:05+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="meta" label="meta"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/fucking-blackhats" rel="alternate" hreflang="en" type="text/html"/><published>2026-04-07T15:09:05+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">My server got infected. So I&apos;m making my own life simpler.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Last time I wrote here was a while ago.
At the time I was starting a very thorough redesign of this website.
Nothing that you would notice. Mostly updating the backend to handle concurrency using the actor model, handling invariance using type-driven patterns, moving from SQLite to PostgreSQL, etc.&lt;/p&gt;
&lt;p&gt;I did this because I was mostly trying things out. My blog’s backend was a way for me to try out things that I do not have the opportunity to try on my day job.&lt;/p&gt;
&lt;p&gt;However, one fucking black-hat hacker ruined it for me. A few days ago, I received an E-Mail from &lt;em&gt;Servinga&lt;/em&gt;, that the IP of the VPS I was using to host my blog was reported for violations. It was reported by multiple sources to have been port scanning, and looking for servers that exposed &lt;code&gt;2134&lt;/code&gt; port. Kind of a traditional port that Trojans and other viruses used to communicate to each other.&lt;/p&gt;
&lt;p&gt;Servinga was gracious enough not to end their contract with me. But to me, it was the last draw. I was already paying so much for the server and I already had exhausted a lot of the ideas I wanted to try. I set up the server with strict version control, and firewall. And I still could not figure out how it was infected.&lt;/p&gt;
&lt;p&gt;But in the space of problems I would like to tackle these days, playing &lt;em&gt;cat and mouse&lt;/em&gt; with black-hats is not on top of my list.
So I spend a few hours, creating a static site generator from the source code of my previous website. Uploading them to &lt;a href=&quot;https://statichost.eu&quot;&gt;statichost.eu&lt;/a&gt;.
You are now reading that website.&lt;/p&gt;
&lt;p&gt;I mourn the lost of my playground, ever so slightly. But this is for better. Maybe I write more in here. Maybe I take up projects that are less private. But for now, fuck the black-hat that ruined my playground.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Sorry</title><id>urn:uuid:d3e0892e-0c5b-4132-9f6e-8c5165b5bec8</id><updated>2025-09-01T19:47:43+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="meta" label="meta"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/i-broke-your-feed-reader" rel="alternate" hreflang="en" type="text/html"/><published>2025-09-01T19:47:43+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I spammed your feed reader, and I&apos;m sorry!</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;If you are subscribed to my feed, you might have been bombarded by old items being marked as new in your feed reader.
This is entirely my fault, and I want to apologize. I know this is extremely inconvenient. I hope you stay subscribed. But I understand if you feel otherwise.&lt;/p&gt;
&lt;section id=&quot;The-Reason&quot;&gt;
&lt;h2&gt;The Reason&lt;/h2&gt;
&lt;p&gt;So, there is a reason why this happens. Mind you, this is not an excuse, just the technical reason.&lt;/p&gt;
&lt;p&gt;When I started writing the software behind this blog, I was completely ignorant of the specifics of the &lt;abbr title=&quot;The Atom Syndication Format Standard&quot; tabindex=&quot;0&quot;&gt;ATOM&lt;/abbr&gt; format. And being frustrated and naive, I didn’t read the spec for it.&lt;/p&gt;
&lt;p&gt;&lt;abbr title=&quot;The Atom Syndication Format Standard&quot; tabindex=&quot;0&quot;&gt;ATOM&lt;/abbr&gt; is a particular beast. And in the field for the &lt;code&gt;&amp;lt;id&amp;gt;&lt;/code&gt; of the items, I should have put a &lt;abbr title=&quot;Uniform Resource Identifier&quot; tabindex=&quot;0&quot;&gt;URI&lt;/abbr&gt;. In my stupidity, I thought it was supposed to be the relative &lt;abbr title=&quot;Uniform Resource Locator&quot; tabindex=&quot;0&quot;&gt;URL&lt;/abbr&gt; of each item. I know I was stupid.&lt;/p&gt;
&lt;p&gt;And over the past year, with a lot of the rewrites, I put plenty of effort into not breaking the feed. However, for each post I had to set the feed ID manually, and keeping track of it became a rather tedious act. More unpleasantly, unless I removed those items or I broke it, my feeds never validated.&lt;/p&gt;
&lt;p&gt;For this reason, I decided not to live in the shadow of my past mistake and let you bear the annoyance. I know. I’m a selfish ass. From now on, however, the &lt;code&gt;&amp;lt;id&amp;gt;&lt;/code&gt; of each post is a &lt;code&gt;UUID&lt;/code&gt; that is automatically created and kept in the database.&lt;/p&gt;
&lt;p&gt;Hopefully, this is the last time I break your feeds.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">My Dog Bites Me</title><id>urn:uuid:01d2ff6c-36ee-4e11-b46d-4b33ac4b108d</id><updated>2025-07-28T17:47:05+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="personal" label="personal"/><category term="dog" label="dog"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/my-dog-bites-me" rel="alternate" hreflang="en" type="text/html"/><published>2025-07-28T17:47:05+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Every night my dog bites me.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;He is there, right before me and my destination. He knows where I want to go. And I know what he will do if I do it too quickly, too slowly, or in a manner that he deems not appropriate. He stares at my feet. Jumping on his four paws, he warns me of the oncoming pain. We have danced through the same routine night after night. But it doesn’t change anything: he is of the wolf lineage, and he cannot betray his ancestors through inaction.&lt;/p&gt;
&lt;p&gt;I jump on the bed, jumping over him while doing so. His reaction is just as immediate, jumping twice his height, reaching the bed. Ready to bite me, with eyes as wild as his teeth. Slowly I sit and get into position. Now it’s the hard part: putting the blanket on my body.&lt;/p&gt;
&lt;p&gt;Pinching the blanket, I pull it slowly towards myself self, My dog jumps on it, letting out a growl. He is not having it. “I should distract him somehow”, I think to myself. Looking around, there is nothing. Trying to move my wife’s blanket doesn’t result in anything.&lt;/p&gt;
&lt;p&gt;Suddenly, I see it, his chew-treat that he carefully hid on the centre most layer of the blanket, truly invisible to every blind aggressor out there.&lt;/p&gt;
&lt;p&gt;I put the treat in my hand, and move it in front of him, trying to make it seductive to him. I definitely have his attention. I throw it on the ground. He leaps towards it, and I jump at the now-free blanket, putting it on my body.&lt;/p&gt;
&lt;p&gt;He notices this, turns around, he is not making this mistake again, at least not for the rest of the night!&lt;/p&gt;
&lt;p&gt;Feeling over-confident, I try to adjust the blanket with my right foot’s toe. And that was the final straw. He jumps and bites my foot and then my ass, barking behind each push of his teeth into my skin.
I scratch a little, a pinch of blood.&lt;/p&gt;
&lt;p&gt;I start petting him to calm him down. He starts to cool down. I pet him more. Finally, content that I will not move any more, he jumps down the bed, on his own bed, by the foot of our bed.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;It is unclear to me why my dog plays this same game every night, and mostly only with me. He doesn’t bite my wife as much. But every night at 11 o’clock, he has to bite while I’m getting in the bed. If we are staying awake longer, he will come and growl at us, communicating in his own way that “I’m tired, let’s get it over with”.&lt;/p&gt;
&lt;p&gt;You might think this is an undesirable behaviour. Something that we should train him out of.
But I find it funny. I would never ever opt out of it. He, for some reason, takes this to be his duty. I’m not sure why, but he is really dedicated to this. He has been for over 7 years now. And every night it is a bonding ritual we have, just like morning cuddles, or sitting by the porch after his walks. That painful moment does not come with suffering. It comes with exhilaration. And I miss it every night I’m away from him. Or he is unwell and too tired for it.&lt;/p&gt;
&lt;p&gt;I don’t know. It might sound masochistic. But his cute face while growling, it is too precious to forgo.&lt;/p&gt;
&lt;p&gt;Wait…&lt;/p&gt;
&lt;p&gt;Oh, goddamn it! I forgot to take my pills! Fuuuuuuuck!&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Scientists Don&apos;t Invent</title><id>urn:uuid:353caf76-ed34-4f1f-a467-cbfe53ae6791</id><updated>2025-06-15T22:37:48+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="engineering" label="engineering"/><category term="science" label="science"/><category term="media" label="media"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/scientists-invented" rel="alternate" hreflang="en" type="text/html"/><published>2025-06-15T22:34:41+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">&quot;Scientists invented...&quot; is a red-flag.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;blockquote&gt;
&lt;p&gt;The world is going to end in just 12 years by mega volcanos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I read in &lt;em&gt;Information Weekly&lt;/em&gt; magazine when I was 9. I read it at the home of my grandparents; they had a subscription to this magazine. A pretty yellow magazine with stories, reader’s letters, kids sections, puzzles, and of course, a two-page “Science and Technology” right in the middle of the magazine. I was addicted to that section. I read that part right before I go to the puzzles and kids parts.&lt;/p&gt;
&lt;p&gt;And I remember this exact news there that said that the world is going to end in 12 years by a series of massive volcanoes that will end civilization, kill the environment, and end life on earth.&lt;/p&gt;
&lt;p&gt;You may be surprised to know that more than 20 years have passed, and we are not all dead!&lt;/p&gt;
&lt;p&gt;Now this story has nothing to do with the rest and the main point of this post, but giving a narrative to a piece is going to engage readers to the article. So, are you engaged?&lt;/p&gt;
&lt;p&gt;Anyhow, I have noticed that every article, podcast, video, or even book that has something like “scientists made…” or “scientists invented…” is usually written by an uneducated person who under-researched the material for his work.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Scientists are in charge of finding out stuff. They are amazing at this. They might create it on the side of science or as a consequence of it, but often the more interesting stuff is done by people whose main focus is not science.
&lt;/li&gt;
&lt;li&gt;
The creating stuff is typically done by designers and engineers, who consult or use the work of scientists.
&lt;/li&gt;
&lt;li&gt;
These articles may confuse academicians with scientists. But academicians that &lt;em&gt;make stuff&lt;/em&gt; are not typically the same academicians that &lt;em&gt;do science&lt;/em&gt;; their process is not the same, their papers don’t look the same, their journals are not the same, and they are hardly in the same circles &lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. A better-researched article mentions that these are biologists, or medical engineers. Or something like that.
&lt;/li&gt;
&lt;li&gt;
Also, inventions done solely by academicians are notoriously dead on publication. So I would not count on them to change your world unless they were contracted by a private company.
&lt;/li&gt;
&lt;li&gt;
These articles may refer to private companies. In these cases, a well-researched article usually mentions the company. A big company gives credibility to the world-changing product. A small company is an opportunity for a journalist to gain credibility by saying, “I was one of the first to report on X” when the company became ubiquity. Not mentioning it might say 3 things.
&lt;ol&gt;
&lt;li&gt;
At best, the journalist is young and does not know how this might be affecting their career. In that case, I also do not trust their assessment of what can actually be a great deal.
&lt;/li&gt;
&lt;li&gt;
They may have been lazy and not done good enough research on that work. This is rare, but if the journalist is doing this repeatedly, just lose them. They are not worth your time.
&lt;/li&gt;
&lt;li&gt;
They may believe that the company, the startup, or the figures behind them are sketchy. And intentionally hide that fact from you. This is not a sign of a good journalist. But a clickbait creator.
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;And when you find them working in the same circles, there is usually a big banner on top of the most prominent wall of the room with “Interdisciplinary” written in bright yellow letters.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Search My Blog</title><id>urn:uuid:8febb440-daae-4dec-9093-334330d7c599</id><updated>2026-04-08T16:33:01+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="sqlite" label="sqlite"/><category term="search" label="search"/><category term="fts5" label="fts5"/><category term="meta" label="meta"/><category term="blog" label="blog"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/search" rel="alternate" hreflang="en" type="text/html"/><published>2025-06-14T11:45:39+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I added a search functionality to the blog.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I just added a search functionality to my blog.&lt;/p&gt;
&lt;p&gt;It uses SQLite’s &lt;a href=&quot;https://www.sqlite.org/fts5.html&quot;&gt;fts5 extension&lt;/a&gt; on a virtual table.&lt;/p&gt;
&lt;section id=&quot;FAQ&quot;&gt;
&lt;h2&gt;FAQ&lt;/h2&gt;
&lt;section id=&quot;Why-not-Meilisearch&quot;&gt;
&lt;h3&gt;Why not Meilisearch?&lt;/h3&gt;
&lt;p&gt;Because I was already using SQLite and fts5 is pretty good.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Why-not-use-Google&quot;&gt;
&lt;h3&gt;Why not use Google?&lt;/h3&gt;
&lt;p&gt;Because I like you a lot and I don’t think Google should know about our secrets.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;But-isnt-Google-the-best-search-engine&quot;&gt;
&lt;h3&gt;But isn’t Google the best search engine?&lt;/h3&gt;
&lt;p&gt;Yeah, I was using internet during the 2000s, too.
But right now, my shitty excuse for a search engine offers a higher quality, with no tracking, no &lt;abbr title=&quot;Large Language Model&quot; tabindex=&quot;0&quot;&gt;LLM&lt;/abbr&gt; bullshit, no ads, no pay-me-to-show-you-on-top&lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Who-asks-these-question-frequently-that-you-are-always-answering&quot;&gt;
&lt;h3&gt;Who asks these question frequently that you are always answering?&lt;/h3&gt;
&lt;p&gt;If I ask them frequently while I’m making it, they are technically Frequently Asked Questions.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id=&quot;Update-on-08042026&quot;&gt;
&lt;h2&gt;Update on 08.04.2026&lt;/h2&gt;
&lt;p&gt;Sadly I have had to remove search from my blog because &lt;a href=&quot;/entries/fucking-blackhats&quot;&gt;it is a simple static site now&lt;/a&gt;.
But thanks for all the fish!&lt;/p&gt;
&lt;/section&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;Although, I guess it would be funny if somebody paid me to show the results for their website on my own’s.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">I love git. I replaced it with jj.</title><id>urn:uuid:fae8e247-6500-4327-8936-3bf946f04ce9</id><updated>2025-06-13T22:53:41+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="version-control" label="version-control"/><category term="git" label="git"/><category term="jj" label="jj"/><category term="dvcs" label="dvcs"/><category term="vcs" label="vcs"/><category term="recommendations" label="recommendations"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/jj" rel="alternate" hreflang="en" type="text/html"/><published>2025-06-06T16:17:46+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I&apos;m recommending Jujutsu Version Control System.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Git is awesome. I love git. I recommended resources for it on this blog.&lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; I have played with libgit2, and created custom cli tools for myself.&lt;/p&gt;
&lt;p&gt;However, for the past two months, I have been using &lt;a href=&quot;https://jj-vcs.github.io/jj/latest/&quot;&gt;jj&lt;/a&gt; at work and on my personal projects. It is simply awesome. It is rebasing, on steroid. For most people, if you like git and you also like rebasing, you will definitely love this.&lt;/p&gt;
&lt;p&gt;There have already been a lot of blog posts about it. &lt;a id=&quot;fnref2&quot; href=&quot;#fn2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; And every day one more is added.&lt;/p&gt;
&lt;p&gt;So just consider this my recommendation of jujutsu.&lt;/p&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;&lt;a href=&quot;/entries/git-send-mail&quot;&gt;git-send-mail.io&lt;/a&gt; and &lt;a href=&quot;/entries/git-rebase-io&quot;&gt;git-rebase.io&lt;/a&gt;&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&quot;https://v5.chriskrycho.com/essays/jj-init/&quot;&gt;jj init&lt;/a&gt; by Chris Krycho
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://zerowidth.com/2025/what-ive-learned-from-jj&quot;&gt;What I’ve learned from jj&lt;/a&gt; by Nathan Witmer
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://arne.me/blog/jj-in-practice&quot;&gt;Jujutsu in practice&lt;/a&gt; by Arne Bahlo
&lt;/li&gt;
&lt;li&gt;
And if you are sold, this is the best starting point out there, by the guy that wrote the defacto book on Rust: &lt;a href=&quot;https://steveklabnik.github.io/jujutsu-tutorial/&quot;&gt;Steve’s Jujutsu Tutorial&lt;/a&gt; by Steve Klabnik
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;#fnref2&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">And Back to Rust, Again!</title><id>urn:uuid:20499228-ad43-44a6-ad50-f4298b5a1b38</id><updated>2025-06-02T22:49:52+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="event-sourcing" label="event-sourcing"/><category term="elixir" label="elixir"/><category term="blog" label="blog"/><category term="meta" label="meta"/><category term="rust" label="rust"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/and-back-to-rust" rel="alternate" hreflang="en" type="text/html"/><published>2025-06-02T22:49:52+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I rewrote my blog. Explaining why and a lot of leafslugs.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;So, I re-re-wrote my blog using Rust. And bought &lt;a href=&quot;https://theleafslug.com&quot;&gt;a new domain&lt;/a&gt;. And commissioned a Leafslug illustration.&lt;/p&gt;
&lt;section id=&quot;Why&quot;&gt;
&lt;h2&gt;Why&lt;/h2&gt;
&lt;p&gt;I really loved Elixir. It was a great experience learning it. I really like the model of LiveView.
However, Elixir’s more prominent figures and companies jumped into the latest hype. After the last one. After the one before that. All during half a year that I experienced it.&lt;/p&gt;
&lt;p&gt;It doesn’t spark joy in me anymore.&lt;/p&gt;
&lt;p&gt;Day-by-day, it feels less and less like a language that I like to use, a community I want to be a part of, and more and more like a proprietary language with a closed enterprise ecosystem. That’s not the vibe I like to code with. &lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Don’t get me wrong. I think BEAM is bee’s knees.
And I think the syntax of Elixir is amazing. I just don’t enjoy being in that community, working with libraries made for it, or consuming the podcasts that are so fascinated by the latest &lt;abbr title=&quot;Large Language Model&quot; tabindex=&quot;0&quot;&gt;LLM&lt;/abbr&gt; crap.&lt;/p&gt;
&lt;p&gt;So, since I was thinking about expanding the backend I wrote for my blog, I decided just to take the pill and re-rewrite&lt;a id=&quot;fnref2&quot; href=&quot;#fn2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; it again in Rust.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;The-Rewrite&quot;&gt;
&lt;h2&gt;The Rewrite&lt;/h2&gt;
&lt;p&gt;So, it is not just a rewrite. The new rewrite has some particularly interesting characteristics.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
(Almost) Everything is event-sourced. &lt;a id=&quot;fnref3&quot; href=&quot;#fn3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
The persistence relies on a single-table SQLite database file.
&lt;/li&gt;
&lt;li&gt;
I wrote a client for it that makes sending posts and editing them much easier.
&lt;/li&gt;
&lt;li&gt;
The markup is the lovely Djot, instead of Markdown.
&lt;/li&gt;
&lt;li&gt;
A new, lovely domain! &lt;a href=&quot;https://theleafslug.com&quot;&gt;TheLeafslug.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Simple &lt;abbr title=&quot;Cascading Style Sheets&quot; tabindex=&quot;0&quot;&gt;CSS&lt;/abbr&gt;, No Tailwind. A more semantic &lt;abbr title=&quot;HyperText Markup Language&quot; tabindex=&quot;0&quot;&gt;HTML&lt;/abbr&gt;.
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id=&quot;FAQ&quot;&gt;
&lt;h2&gt;FAQ&lt;/h2&gt;
&lt;section id=&quot;Isnt-Rust-an-over-kill&quot;&gt;
&lt;h3&gt;Isn’t Rust an over-kill?&lt;/h3&gt;
&lt;p&gt;I’m not learning Python just to answer your question.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Isnt-event-sourcing-an-over-kill&quot;&gt;
&lt;h3&gt;Isn’t event-sourcing an over-kill?&lt;/h3&gt;
&lt;p&gt;Not unless you want snapshotting, multi-tenancy, and state resolution.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Arent-there-better-databases-for-storing-events&quot;&gt;
&lt;h3&gt;Aren’t there better databases for storing events?&lt;/h3&gt;
&lt;p&gt;Yes, but they are actually over-kill.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Why-changing-the-domain&quot;&gt;
&lt;h3&gt;Why changing the domain?&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
First, no one complimented the clever name of my last domain.
&lt;/li&gt;
&lt;li&gt;
That domain is being held hostage by another registrar; that doesn’t let me move it elsewhere.
&lt;/li&gt;
&lt;li&gt;
Leafslugs spark joy in me.
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id=&quot;Why-not&quot;&gt;
&lt;h3&gt;Why not…?&lt;/h3&gt;
&lt;p&gt;Ok, I’m done with your endless questions now.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;A big red-letters on a yellow background sign that screams: &lt;em&gt;&lt;strong&gt;&lt;strong&gt;SARCASM&lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;
&lt;p&gt;The first version of this blog was actually written in Rust.&lt;a href=&quot;#fnref2&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot;&gt;
&lt;p&gt;Are you interested in a post with an architectural breakdown? If you are, please send me a quick email at &lt;a href=&quot;mailto:me@prma.dev&quot;&gt;me@prma.dev&lt;/a&gt;.&lt;a href=&quot;#fnref3&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">How to change the title of a page in Gleam</title><id>urn:uuid:2e94e40a-f7e5-4ed6-bda0-95b6c8dd1aab</id><updated>2025-02-18T09:40:24+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="frontend" label="frontend"/><category term="lustre" label="lustre"/><category term="gleam" label="gleam"/><category term="tils" label="tils"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/how-to-change-the-title-of-a-page-in-gleam" rel="alternate" hreflang="en" type="text/html"/><published>2025-02-18T09:40:24+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Lustre only changes the part of the DOM that you assign it. Using FFI we can change the title of the page.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;So, yeah. I’m posting front-end stuff as well now.&lt;/p&gt;
&lt;section id=&quot;The-Problem&quot;&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;So we have a framework called &lt;a href=&quot;https://hexdocs.pm/lustre/index.html&quot;&gt;Lustre&lt;/a&gt; in Gleam that allows you to have multiple forms of client-side and server-side front-ends.
And it is great. But it only manages a single part of the DOM with your specified id.&lt;/p&gt;
&lt;p&gt;So if you have this &lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;constant&quot;&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;!&lt;/span&gt;doctype html&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;attribute&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;en&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;🚧 Some weird website&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&amp;#x2f;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&amp;#x2f;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;attribute&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&amp;#x2f;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;&amp;lt;!-- here is the interesting part--&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&amp;#x2f;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&amp;#x2f;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And if you start your application in you main function like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;constructor&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation delimiter&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;lustre&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;variable other member&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;#app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor&quot;&gt;Nil&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will only change the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; with the &lt;code&gt;id=&quot;app&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So, how would you change the title of the page?&lt;/p&gt;
&lt;p&gt;If you move the id from the div to the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; tag, you would not be able to return a list of elements, as far as I understand &lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;The-solution&quot;&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;p&gt;Create a file at &lt;code&gt;src/set_window_title.js&lt;/code&gt; with this content:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export function set_windowTitle(title) {
  document.title = title;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And add these to one of your Gleam files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;set_window_title&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation delimiter&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;&lt;span class=&quot;variable&quot;&gt;effect&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;Effect&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;punctuation delimiter&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;effect&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;variable other member&quot;&gt;from&lt;/span&gt;
  &lt;span class=&quot;variable&quot;&gt;do_set_window_title&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;attribute&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;variable&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable&quot;&gt;javascript&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;.&amp;#x2f;set_window_title.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;set_windowTitle&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;do_set_window_title&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation delimiter&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now if you call the &lt;code&gt;set_window_title&lt;/code&gt; function as an &lt;em&gt;effect&lt;/em&gt;, and pass it a &lt;em&gt;string&lt;/em&gt;, it will change the title of the page, like a charm.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;https://github.com/hayleigh-dot-dev&quot;&gt;Hayleigh Thompson&lt;/a&gt;, for the solution!&lt;/p&gt;
&lt;/section&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;I am probably wrong on that. But I could not find any way to do so.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Are we there yet?</title><id>urn:uuid:4ab6c1d7-e6a1-44c7-a3cd-092c3eab8239</id><updated>2025-02-08T21:26:29+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="personal" label="personal"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/are-we-there-yet" rel="alternate" hreflang="en" type="text/html"/><published>2025-02-08T21:26:29+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">There is this fucking question that is blocking my blogging.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;blockquote&gt;
&lt;p&gt;Are we there yet?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Every. Single. Fucking. Time. I’m thinking of blogging this fucking question is the first sentence that comes up in my mind. I have no idea why.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Are we there yet?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It doesn’t even make a fucking sense. Most of what we try to achieve is not defined by specific, well-defined borders.&lt;/p&gt;
&lt;p&gt;“Hey Rust developers, Are we there, yet?”, “Where?”. Other than a bored toddler nagging endlessly about the length of the road, in what other context does that even make any sense?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Are we there yet?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you do not know how to define the &lt;em&gt;there&lt;/em&gt;, why would you give a rat’s ass if you get &lt;em&gt;there&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;There you go, brain. Are you satisfied?&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Moving to Germany</title><id>urn:uuid:02e4a788-cece-4933-9a1b-2288a1d5af7f</id><updated>2025-01-18T14:02:49+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="germany" label="germany"/><category term="personal" label="personal"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/moving-to-germany" rel="alternate" hreflang="en" type="text/html"/><published>2025-01-18T14:02:49+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">In couple of weeks I&apos;m moving to Germany!</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I’m happy to inform you, dear reader, that after around three years of constant struggle and effort, I have finally received my German Visa.&lt;/p&gt;
&lt;p&gt;And, I will be reunited with my wife, in about two weeks from now.&lt;/p&gt;
&lt;p&gt;Also -since each time I have mentioned moving to Germany someone asks this - yes, I will be bringing Kitkat, my dog as well. Of course, I will. He is going to be &lt;em&gt;Der Hund&lt;/em&gt;! And &lt;em&gt;bellen&lt;/em&gt;, constantly,&lt;/p&gt;
&lt;p&gt;P.S. I’m also looking for a job right now. If you know of any positions that could use my skills in Elixir, Go and Rust, &lt;a href=&quot;mailto:me@prma.dev&quot;&gt;please point me to it&lt;/a&gt;!&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Inquiry Into Being</title><id>urn:uuid:c136be03-7c75-4289-aff0-8893e58c3f58</id><updated>2024-12-14T10:07:12+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="meditation" label="meditation"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/inquiry-into-being" rel="alternate" hreflang="en" type="text/html"/><published>2024-12-14T10:07:12+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I am doing meditation, again.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Some years ago I started meditating. I began, motivated by the health effects of meditation. Mostly, I had trouble controlling my impulses.&lt;/p&gt;
&lt;p&gt;It did wonders.&lt;/p&gt;
&lt;p&gt;However, My efforts and motivations began to change into an introspective approach to understand consciousness and the state of being. I did not have anything in the way of anyone that personally could help me. Just a bunch of apps.&lt;/p&gt;
&lt;p&gt;But alas, my efforts were abandoned because of some massive changes in my life.&lt;/p&gt;
&lt;p&gt;I still don’t have anyone that personally guides me, but I began again.
I mostly want to take it as far as “Waking Up” app by Sam Harris can take me, and then find my own path afterward.&lt;/p&gt;
&lt;p&gt;Just a couple of weeks of practice and I feel being calmer and having some realizations about the nature of &lt;em&gt;being&lt;/em&gt;.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">How to start and stop Elixir application</title><id>urn:uuid:dd70df97-c067-4334-aaec-707ab7fa6434</id><updated>2025-05-30T15:44:12+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="phoenix" label="phoenix"/><category term="programming" label="programming"/><category term="freebsd" label="freebsd"/><category term="elixir" label="elixir"/><category term="tils" label="tils"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/how-to-start-and-stop-elixir-application" rel="alternate" hreflang="en" type="text/html"/><published>2024-11-28T07:07:30+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">When you release Elixir applications, it comes with an start and stop command.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;So one of the challenges I faced moving to the FreeBSD was that for the services I wanted have, I had to come up with a kill script for shutting down or restarting them.&lt;/p&gt;
&lt;p&gt;The challenge is especially hard, since the &lt;abbr title=&quot;Process ID&quot; tabindex=&quot;0&quot;&gt;PID&lt;/abbr&gt; of the Elixir applications multiplies. And you have to kill them by hand. And because of fault-tolerant nature of Elixir, it kind of feels like killing a hydra:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cut off one head, two more shall take its place.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So what can one do? 
Just create a release, and the executable contains &lt;code&gt;start&lt;/code&gt; &lt;code&gt;stop&lt;/code&gt; &lt;code&gt;restart&lt;/code&gt; and a bunch of more useful commands&lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So build it like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;function&quot;&gt;mix&lt;/span&gt; release
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And for example if the application name is &lt;code&gt;blog&lt;/code&gt; and it is made using phoenix, you can do this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PHX_SERVER=&lt;span class=&quot;string&quot;&gt;&amp;#x27;1&amp;#x27;&lt;/span&gt; MIX_ENV=&lt;span class=&quot;string&quot;&gt;&amp;#x27;prod&amp;#x27;&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;_build&amp;#x2f;prod&amp;#x2f;rel&amp;#x2f;blog&amp;#x2f;bin&amp;#x2f;blog&lt;/span&gt; start  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a service on FreeBSD I settled on this script for my blog:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;comment&quot;&gt;#!&amp;#x2f;bin&amp;#x2f;sh&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;# PROVIDE: blog&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;# REQUIRE: daemon&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;# BEFORE:&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;# KEYWORD: shutdown&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;.&lt;/span&gt; &amp;#x2f;etc&amp;#x2f;rc.subr

name=&lt;span class=&quot;string&quot;&gt;&amp;quot;blog&amp;quot;&lt;/span&gt;
desc=&lt;span class=&quot;string&quot;&gt;&amp;quot;blog - imadethissite.com&amp;quot;&lt;/span&gt;
rcvar=&lt;span class=&quot;string&quot;&gt;&amp;quot;blog_enable&amp;quot;&lt;/span&gt;

project_dir=&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;#x2f;home&amp;#x2f;prma&amp;#x2f;blog&amp;quot;&lt;/span&gt;

mix_exec=&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;#x2f;usr&amp;#x2f;local&amp;#x2f;bin&amp;#x2f;mix&amp;quot;&lt;/span&gt;
daemon_exec=&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;#x2f;usr&amp;#x2f;sbin&amp;#x2f;daemon&amp;quot;&lt;/span&gt;

mix_opts=&lt;span class=&quot;string&quot;&gt;&amp;quot;phx.server&amp;quot;&lt;/span&gt;
secret_key_base=&lt;span class=&quot;string&quot;&gt;&amp;quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;quot;&lt;/span&gt;

pid_file=&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;#x2f;var&amp;#x2f;run&amp;#x2f;${name}.pid&amp;quot;&lt;/span&gt;
daemon_user=&lt;span class=&quot;string&quot;&gt;&amp;quot;[your_user_name]&amp;quot;&lt;/span&gt;

server_port=4001
log_file=&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;#x2f;var&amp;#x2f;log&amp;#x2f;${name}.log&amp;quot;&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;load_rc_config&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;span class=&quot;operator&quot;&gt;$&lt;/span&gt;name&amp;quot;&lt;/span&gt; :&lt;span class=&quot;string&quot;&gt;&amp;quot;${blog_enable=&lt;span class=&quot;string&quot;&gt;&amp;quot;NO&amp;quot;&lt;/span&gt;}&amp;quot;&lt;/span&gt;

start_cmd=&lt;span class=&quot;string&quot;&gt;&amp;quot;blog_start&amp;quot;&lt;/span&gt;
stop_cmd=&lt;span class=&quot;string&quot;&gt;&amp;quot;blog_stop&amp;quot;&lt;/span&gt;
compiled_path=&lt;span class=&quot;string&quot;&gt;&amp;quot;_build&amp;#x2f;prod&amp;#x2f;rel&amp;#x2f;blog&amp;#x2f;bin&amp;#x2f;blog&amp;quot;&lt;/span&gt;

PATH=&lt;span class=&quot;operator&quot;&gt;$&lt;/span&gt;PATH:&amp;#x2f;usr&amp;#x2f;local&amp;#x2f;lib&amp;#x2f;erlang27&amp;#x2f;bin&amp;#x2f;erl

&lt;span class=&quot;function&quot;&gt;blog_start&lt;/span&gt;() {

  &lt;span class=&quot;function&quot;&gt;cd&lt;/span&gt; ${project_dir} || &lt;span class=&quot;function&quot;&gt;exit&lt;/span&gt;
  &lt;span class=&quot;function&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;[BLOG] Starting BLOG at: http:&amp;#x2f;&amp;#x2f;localhost:${server_port}&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;function&quot;&gt;su&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;-&lt;/span&gt; ${daemon_user}  &lt;span class=&quot;constant&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;cd ${project_dir}  &amp;amp;&amp;amp; PORT=${server_port} PHX_SERVER=&amp;#x27;1&amp;#x27; MIX_ENV=&amp;#x27;prod&amp;#x27; SECRET_KEY_BASE=${secret_key_base}&lt;span class=&quot;operator&quot;&gt; $&lt;/span&gt;compiled_path start&amp;quot;&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;${log_file}&amp;quot;&lt;/span&gt; 2&amp;gt;&amp;amp;1 &amp;amp;
  &lt;span class=&quot;function&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;[BLOG] started!&amp;quot;&lt;/span&gt;
}

&lt;span class=&quot;function&quot;&gt;blog_stop&lt;/span&gt;() {
  &lt;span class=&quot;function&quot;&gt;cd&lt;/span&gt; ${project_dir} || &lt;span class=&quot;function&quot;&gt;exit&lt;/span&gt;

  &lt;span class=&quot;function&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;[BLOG] Stopping BLOG&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;operator&quot;&gt;$&lt;/span&gt;compiled_path&lt;/span&gt; stop
  &lt;span class=&quot;function&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;[BLOG] Stopped&amp;quot;&lt;/span&gt;
}

&lt;span class=&quot;function&quot;&gt;run_rc_command&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;span class=&quot;operator&quot;&gt;$&lt;/span&gt;1&amp;quot;&lt;/span&gt;
  
&lt;/code&gt;&lt;/pre&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;&lt;code&gt;shell&lt;/code&gt;, &lt;code&gt;eval&lt;/code&gt; are arguably more amazing. But the &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;stop&lt;/code&gt; was the remedies that I could hardly find in the internet.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Making Many Many-To-Many Relations in Relational Databases</title><id>urn:uuid:362e106d-d414-4507-9607-30631da7f71c</id><updated>2025-05-30T15:22:28+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="rdbms" label="rdbms"/><category term="sql" label="sql"/><category term="tils" label="tils"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/making-many-many-to-many-relations-in-relational-databases" rel="alternate" hreflang="en" type="text/html"/><published>2024-11-14T08:51:25+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I describe how to make many-to-many relations on the same row with different meanings.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Imagine you have a &lt;code&gt;books&lt;/code&gt; table. And you have &lt;code&gt;people&lt;/code&gt; table.
You want to create a relation between the two table, giving credit to the people.&lt;/p&gt;
&lt;p&gt;So a traditional many-to-many does this:
1. You create a table called &lt;code&gt;books_people&lt;/code&gt;.
2. Each row of &lt;code&gt;books_people&lt;/code&gt; have 2 references. &lt;code&gt;book_id&lt;/code&gt; and &lt;code&gt;person_id&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[book] 
       \
[book_id, person_id]
         &amp;#x2f;
[person]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you only count authors this would work, perfectly.&lt;/p&gt;
&lt;p&gt;But in making of a book, there are many more people involved: Translators, illustrators, etc. 
And sometimes a person could be also a translator as well. Or even an illustrator, on the same book!
So, doing a simple traditional &lt;em&gt;many-to-many&lt;/em&gt; does not capture their role. 
And creating a table for each role (&lt;code&gt;translators&lt;/code&gt;, &lt;code&gt;authors&lt;/code&gt;, &lt;code&gt;illustrators&lt;/code&gt;) is not really feasible, and wasteful.&lt;/p&gt;
&lt;p&gt;What do you do, then?
We add a &lt;code&gt;role&lt;/code&gt; column to the &lt;code&gt;books_people&lt;/code&gt; table.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[book] 
       \
[book_id, person_id, role]
         &amp;#x2f;
[person]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And rename the table to &lt;code&gt;involvements&lt;/code&gt; for good measure!&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Today I Learned is not trademarked</title><id>urn:uuid:45b63030-ba43-48e2-a623-0d83901e8d29</id><updated>2024-11-11T09:46:41+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="meta" label="meta"/><category term="tils" label="tils"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/today-i-learned-is-not-trademarked" rel="alternate" hreflang="en" type="text/html"/><published>2024-11-11T09:46:41+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I just found out that &quot;Today I learned&quot; is a common trend!</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;For the longest time, I believed that “Today I Learned” was an idea coming out of &lt;a href=&quot;http://til.hashrocket.com/&quot;&gt;HashRocket&lt;/a&gt;. Which was a shame, since I really loved the idea, but I did not want to steal someone else’s idea.
But, Today, I saw &lt;a href=&quot;https://jvns.ca/til/&quot;&gt;Julia Evans&lt;/a&gt; had a blog with the same name. Which caused me to reconsider my previous presumptions. So I searched for it, and lo and behold: It even has a subreddit!&lt;/p&gt;
&lt;p&gt;So I got quickly to work, and here we have it!&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Elixir on FreeBSD</title><id>urn:uuid:3b4e275b-f847-405c-8b7b-53280211dee3</id><updated>2025-05-30T15:56:42+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="liveview" label="liveview"/><category term="phoenix" label="phoenix"/><category term="elixir" label="elixir"/><category term="freebsd" label="freebsd"/><category term="meta" label="meta"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/elixir-on-freebsd" rel="alternate" hreflang="en" type="text/html"/><published>2024-10-06T12:55:49+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I have rewritten my blog with Elixir and deployed it on a FreeBSD VPS.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;So, I deleted my blog. I deleted my sister-in-law’s work-in-progress website. I also deleted my Miniflux instance with the PostgreSQL Database it was using. With no back-ups.&lt;/p&gt;
&lt;p&gt;Accidentally.&lt;/p&gt;
&lt;p&gt;It was all using a single Debian 12 VPS, which I accidentally deleted when I was trying to delete another VPS instead. Dumb me.&lt;/p&gt;
&lt;p&gt;I tried my best to deploy everything again, but even though nothing was changed, once again, the Debian’s old-is-good-because philosophy took another victim, and this time, it was me. The same problem also happened with Ubuntu. No surprises there. I am also wise enough to know nothing would be different with any of the RPM-based Linux distributions (CentOS, openSUSE, etc.).&lt;/p&gt;
&lt;section id=&quot;A-better-OS&quot;&gt;
&lt;h2&gt;A better OS&lt;/h2&gt;
&lt;p&gt;There was another option, one that boasted stability, and I was pleasantly surprised it wasn’t because of the same stupid shit that Linux server OSes so direly suffer from. You guessed correctly, FreeBSD. I started using it. Since the first &lt;code&gt;ssh&lt;/code&gt; login, everything was much smoother.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Elixir&quot;&gt;
&lt;h2&gt;Elixir&lt;/h2&gt;
&lt;p&gt;I also took the opportunity to rewrite my blog in my new favorite language, Elixir. Yes. I rewrote my Rust blog in Elixir. To continue with the craziness, it is actually much more performant than the Rust version ever was &lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now I can absolutely go speak a day and night about how magnificent and wonderful Elixir is. And how, after experiencing Go and Rust, two statically-typed languages, I was surprised that a dynamically-typed language &lt;a id=&quot;fnref2&quot; href=&quot;#fn2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; could actually be more reliable than a static one &lt;a id=&quot;fnref3&quot; href=&quot;#fn3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;. But, suffice it to say that there is hardly any use case on the server-side that I cannot imagine Elixir being the best solution by a huge margin.&lt;/p&gt;
&lt;p&gt;Right now, if you inspect this site, you will see two web-sockets being opened, and afterward, while you are browsing through the site, no additional &lt;abbr title=&quot;HyperText Transfer Protocol&quot; tabindex=&quot;0&quot;&gt;HTTP&lt;/abbr&gt; requests being made. This is thanks to the power of the &lt;a href=&quot;https://www.phoenixframework.org/&quot;&gt;Phoenix framework&lt;/a&gt;’s &lt;a href=&quot;https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html&quot;&gt;LiveView&lt;/a&gt; library. Did I need that? Probably not. Is it more environmentally-friendly to not establish yet another TCP connection for each interaction, and instead have a 100KB (uncompressed) JavaScript? I am not sure! Was it for practice purposes? Absolutely!&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;IMadeThisSitecom&quot;&gt;
&lt;h2&gt;IMadeThisSite.com&lt;/h2&gt;
&lt;p&gt;I’m also sporting a new domain. IMadeThisSite.com. Why? Well …:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The ownership of &lt;code&gt;.dev&lt;/code&gt; does not put me at ease. Squarespace, as well as &lt;code&gt;.dev&lt;/code&gt;‘s previous owner, Google, are not the most reliable and least predatory providers of any service. So my prma.dev domain always feels at a cliff’s edge.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I think I would enjoy putting this &lt;abbr title=&quot;Uniform Resource Locator&quot; tabindex=&quot;0&quot;&gt;URL&lt;/abbr&gt; at the top of my resume, without any further explanations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I mean, it is true! Ain’t it?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id=&quot;Some-regressions&quot;&gt;
&lt;h2&gt;Some regressions&lt;/h2&gt;
&lt;p&gt;Along the way, there were a few compromises that I had to make:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;I no longer use Djot. Why? Elixir does not have a good Djot parser, as of the time of this blog post, and I do not intend to write one for now.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I do not use &lt;a href=&quot;/entries/files-as-metadata-format&quot;&gt;&lt;abbr title=&quot;Files As Metadata Format&quot; tabindex=&quot;0&quot;&gt;FAMF&lt;/abbr&gt;&lt;/a&gt; for the post metadata. It is not because I lost faith in &lt;abbr title=&quot;Files As Metadata Format&quot; tabindex=&quot;0&quot;&gt;FAMF&lt;/abbr&gt;, I just wanted to see what fancy things I could do with it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;There are some speculations that it was because I was using MUSL instead of Glibc. Which I never found out. But it kinds of goes in the face of Rust’s motto of “A language empowering everyone to build reliable and efficient software”. Which seems only true, if everyone used a Glibc based Linux distribution, otherwise you might get a 10-second, CPU-at-100% load time for a fucking &lt;abbr title=&quot;HyperText Markup Language&quot; tabindex=&quot;0&quot;&gt;HTML&lt;/abbr&gt; at some unknown point in the code.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;
&lt;p&gt;Only for now. José Valim (the creator of Elixir), Guillaume Duboc (A PhD student), and Giuseppe Castagna (programming language researcher) are working on bringing about &lt;em&gt;Set-Theoric Types&lt;/em&gt; to Elixir. And judging by the other design decisions that José made, it is going to be fantastic.&lt;a href=&quot;#fnref2&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot;&gt;
&lt;p&gt;It is absolutely not the case for any other dynamically typed language. The reliability comes, not because of the dynamic-ness, but despite it.&lt;a href=&quot;#fnref3&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Services I No Longer Use</title><id>urn:uuid:d63a1cd0-5214-49bc-9d1a-df030c2153cf</id><updated>2025-05-30T16:03:05+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="saas" label="saas"/><category term="uberspace" label="uberspace"/><category term="llm" label="llm"/><category term="feedbin" label="feedbin"/><category term="kagi" label="kagi"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/services-i-no-longer-use" rel="alternate" hreflang="en" type="text/html"/><published>2024-09-09T12:33:26+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Explaining my decision to stop using Kagi, Uberspace and Feedbin</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I have lost interest in the Kagi search engine. I was very positive about it earlier, and I expressed my enthusiasm for it in my post called &lt;a href=&quot;/entries/web-experience-makeover&quot;&gt;Giving My Experience of the Web a Makeover&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, I have become disillusioned with their ongoing development. If you take a look at &lt;a href=&quot;https://kagi.com/changelog&quot;&gt;Kagi’s changelog blog&lt;/a&gt;, you’ll notice a strong focus on their &lt;abbr title=&quot;Large Language Model&quot; tabindex=&quot;0&quot;&gt;LLM&lt;/abbr&gt;s. The blog post by Lori, titled &lt;a href=&quot;https://d-shoot.net/kagi.html&quot;&gt;Why I Lost Faith in Kagi&lt;/a&gt;, explains this matter further.&lt;/p&gt;
&lt;p&gt;As an alternative, I am currently using DuckDuckGo, which I can’t say I enjoy all that much. But it is the lesser of several evils.&lt;/p&gt;
&lt;p&gt;I have also moved my blog from &lt;a href=&quot;https://uberspace.de&quot;&gt;uberspace&lt;/a&gt;. The reason was that I could not work without root privileges&lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; or an up-to-date version of glibc&lt;a id=&quot;fnref2&quot; href=&quot;#fn2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Another service I said goodbye to was &lt;a href=&quot;https://feedbin.com&quot;&gt;feedbin.com&lt;/a&gt;. Feedbin is a good service with a solid track record. However, if you’re not in the Apple ecosystem, you’ll have a second-rate experience. I am not part of that ecosystem, so after enjoying a year of using Feedbin, I replaced it with a self-hosted Miniflux and various third-party clients. I still recommend Feedbin to anyone who cannot (or would prefer not to) host their own Miniflux or who is in the Apple ecosystem. Feedbin is a really solid choice.&lt;/p&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;To install Docker or Nix.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;
&lt;p&gt;Almost everything requires a more recent (&amp;gt;5.28) version of CentOS.&lt;a href=&quot;#fnref2&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">The XZ advantage over CrowdStrike</title><id>urn:uuid:36df6706-d35f-4c6e-aa30-28a832603d1a</id><updated>2025-05-30T15:29:42+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="floss" label="floss"/><category term="foss" label="foss"/><category term="software-development" label="software-development"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/the-xz-advantage-over-crowdstrike" rel="alternate" hreflang="en" type="text/html"/><published>2024-07-19T20:46:13+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">What XZ incident had going for itself that CrowdStrike never had.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;May I remind you that the XZ incident &lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; was discovered because it was open-source (&lt;abbr title=&quot;Free and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FOSS&lt;/abbr&gt;) by an open-source contributor employed at Microsoft, while the CrowdStrike &lt;a id=&quot;fnref2&quot; href=&quot;#fn2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;, a Microsoft Windows’ bug, was discovered when millions of people woke up to a fucking &lt;abbr title=&quot;Blue Screen Of Death&quot; tabindex=&quot;0&quot;&gt;BSOD&lt;/abbr&gt;?  It is as if there is something about &lt;abbr title=&quot;Free/Libre and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FLOSS&lt;/abbr&gt; that prevents this kind of fuckup.&lt;/p&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;You know the XZ incident? A malicious actor called Jia Tang had inserted a backdoor into the XZ program. Likely targeting Linux servers?&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;
&lt;p&gt;A company called CrowdStrike distributed a patch to many enterprise Windows OSes through Microsoft’s update channel, bricking a massive amount of Windows installation — which, at the time of this writing, could only can be fixed manually.&lt;a href=&quot;#fnref2&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">&quot;You are responsible for the consequences of your speech&quot;</title><id>urn:uuid:870c31e3-6757-486e-a93a-b7467644742f</id><updated>2024-07-14T20:17:49+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="linguistics" label="linguistics"/><category term="speech" label="speech"/><category term="ethics" label="ethics"/><category term="recommendations" label="recommendations"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/you-are-responsible-for-the-consequences-of-your-speech" rel="alternate" hreflang="en" type="text/html"/><published>2024-07-14T20:17:49+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">&quot;You are responsible for your actions!&quot;, argues a linguist.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;blockquote&gt;
&lt;p&gt;I’m just joking! Why are you getting mad? – A comedian&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s not a sexist joke, it is a joke about sexism. Why are you taking these jokes seriously?
– Another comedian&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well, Here is a beautifully explained response from a linguist:
&lt;a href=&quot;https://llwyn.srht.site/posts/responsibility-for-unintended-interpretations/&quot;&gt;You are responsible for the consequences of your speech (Yes, really).&lt;/a&gt;&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Stupid Superhero Movies</title><id>urn:uuid:ab7a0f16-374d-40e5-859d-f7baf55decf1</id><updated>2024-07-14T14:02:52+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="ethics" label="ethics"/><category term="superhero" label="superhero"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/stupid-superhero-movies" rel="alternate" hreflang="en" type="text/html"/><published>2024-07-14T14:02:52+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Super hero movie writers are always escaping reality! (no shit!)</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I hate this stupid &lt;strong&gt;doing the right thing&lt;/strong&gt; ideological bullshit that superhero movies are pushing.&lt;/p&gt;
&lt;p&gt;Oh, you have a &lt;a href=&quot;https://en.wikipedia.org/wiki/Trolley_problem&quot;&gt;trolley problem&lt;/a&gt;? The trolley will just suddenly fly, or a third track will just appear out of fucking thin air!&lt;/p&gt;
&lt;p&gt;Just fucking grow up and take responsibility for the consequences of your actions. Will you?&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">gRPC was a mistake</title><id>urn:uuid:d0cf6882-65ef-4659-a2f1-983d9085aeef</id><updated>2025-05-30T15:58:54+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="rest" label="rest"/><category term="api" label="api"/><category term="back-end" label="back-end"/><category term="grpc" label="grpc"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/grpc-was-a-mistake" rel="alternate" hreflang="en" type="text/html"/><published>2024-07-13T10:21:41+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I&apos;m not proud of choosing gRPC and I&apos;m paying for it.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Ever since this morning, I have been bothered by the thought: &lt;abbr title=&quot;Google Remote Procedure Calls&quot; tabindex=&quot;0&quot;&gt;gRPC&lt;/abbr&gt; added nothing but endless overhead to our product. Using it was an absolute mistake.&lt;/p&gt;
&lt;p&gt;The greatest pitfall comes from the fact that the generated libraries are almost always useless directly, so you would need to define two different mappers, one &lt;strong&gt;from&lt;/strong&gt; the Protocol Buffer-generated struct and one &lt;strong&gt;to&lt;/strong&gt; Protocol Buffer-generated struct, manually. That mapping also takes away any performance, or ergonomic benefits &lt;abbr title=&quot;Google Remote Procedure Calls&quot; tabindex=&quot;0&quot;&gt;gRPC&lt;/abbr&gt; may have had.&lt;/p&gt;
&lt;p&gt;If you need streaming, &lt;abbr title=&quot;Google Remote Procedure Calls&quot; tabindex=&quot;0&quot;&gt;gRPC&lt;/abbr&gt; is very good. But I would only use it in those specific circumstances, and every other endpoint would be &lt;abbr title=&quot;Java Script Object Notation&quot; tabindex=&quot;0&quot;&gt;JSON&lt;/abbr&gt; and &lt;abbr title=&quot;HyperText Transfer Protocol&quot; tabindex=&quot;0&quot;&gt;HTTP&lt;/abbr&gt; &lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, and message brokers &lt;a id=&quot;fnref2&quot; href=&quot;#fn2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And the compiler is also weird, the tooling is unsatisfactory.&lt;/p&gt;
&lt;p&gt;The promised language agnosticism doesn’t pay off in small teams, since the generated library is usually so massive that reading it would take more time than just messaging your colleagues and asking for the fields in the &lt;abbr title=&quot;Java Script Object Notation&quot; tabindex=&quot;0&quot;&gt;JSON&lt;/abbr&gt; request body. In retrospect, we had much less trouble with end-points that did not incorporate &lt;abbr title=&quot;Google Remote Procedure Calls&quot; tabindex=&quot;0&quot;&gt;gRPC&lt;/abbr&gt;.&lt;/p&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;For synchronous &lt;abbr title=&quot;Application Programming Interface&quot; tabindex=&quot;0&quot;&gt;API&lt;/abbr&gt;s.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;
&lt;p&gt;For asynchronous &lt;abbr title=&quot;Application Programming Interface&quot; tabindex=&quot;0&quot;&gt;API&lt;/abbr&gt;s.&lt;a href=&quot;#fnref2&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Files As Metadata Format</title><id>urn:uuid:b6c43cb5-1acc-45bb-b094-995b603e8ae7</id><updated>2026-02-27T16:53:53+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="files" label="files"/><category term="unix" label="unix"/><category term="blogging" label="blogging"/><category term="metadata" label="metadata"/><category term="famf" label="famf"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/files-as-metadata-format" rel="alternate" hreflang="en" type="text/html"/><published>2024-07-06T15:19:06+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">File structures with simple contents can be used instead of YAML, TOML or JSON. More effectively!</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;&lt;abbr title=&quot;YAML Ain&apos;t Markup Language&quot; tabindex=&quot;0&quot;&gt;YAML&lt;/abbr&gt; and &lt;abbr title=&quot;Tom&apos;s Obvious, Minimal Language&quot; tabindex=&quot;0&quot;&gt;TOML&lt;/abbr&gt; suck. Long live the &lt;abbr title=&quot;Files As Metadata Format&quot; tabindex=&quot;0&quot;&gt;FAMF&lt;/abbr&gt;!&lt;/p&gt;
&lt;section id=&quot;What-is&quot;&gt;
&lt;h2&gt;What is &lt;abbr title=&quot;Files As Metadata Format&quot; tabindex=&quot;0&quot;&gt;FAMF&lt;/abbr&gt;?&lt;/h2&gt;
&lt;p&gt;File As Metadata Format (&lt;abbr title=&quot;Files As Metadata Format&quot; tabindex=&quot;0&quot;&gt;FAMF&lt;/abbr&gt;) is not anything horribly new. It is an extension of the Unix way of dealing with information.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Everything is a file.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Basically, each field of data is its own file; the key is the file name, and the content of the file is the field content. The exception is when the field is another set of information or a list of this information.&lt;/p&gt;
&lt;p&gt;As an example, the metadata for this blog post could be structured like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;variable other member&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Files As Metadata format&amp;quot;&lt;/span&gt;
&lt;span class=&quot;variable other member&quot;&gt;slug&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;files-as-metadata-format&amp;quot;&lt;/span&gt;
&lt;span class=&quot;variable other member&quot;&gt;published_at&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;2024-07-05T21:17:36+03:30&amp;quot;&lt;/span&gt;
&lt;span class=&quot;variable other member&quot;&gt;created_at&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;2024-07-05T21:17:36+03:30&amp;quot;&lt;/span&gt;
&lt;span class=&quot;variable other member&quot;&gt;updated_at&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;2024-07-05T21:17:36+03:30&amp;quot;&lt;/span&gt;
&lt;span class=&quot;variable other member&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;posts&amp;quot;&lt;/span&gt;
&lt;span class=&quot;variable other member&quot;&gt;tags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;famf&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;information&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;metadata&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the &lt;abbr title=&quot;Tom&apos;s Obvious, Minimal Language&quot; tabindex=&quot;0&quot;&gt;TOML&lt;/abbr&gt; would be added as some sort of header to the top of a Markdown or Djot document.&lt;/p&gt;
&lt;p&gt;Now, if you are on Linux and you want to see the title of every post, you are kind of out of luck. You either have to create a pretty fragile script that uses awk and &lt;code&gt;sed&lt;/code&gt;, and regex and won’t work tomorrow, or you will have to create/modify your own markup parser that gives you those titles. Never mind editing them.&lt;/p&gt;
&lt;p&gt;Instead, imagine this file structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;#x2f;posts
└──&amp;#x2f;files_as_metadata_format
   ├── content.dj 
   ├── upd_at
   ├── cre_at
   ├── title
   ├── slug
   └── tags 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each file contains only the information asked for.
What is the content of upd_at?  &lt;code&gt;2024-07-05T21:17:36+03:30&lt;/code&gt;
What is the content of the title? &lt;code&gt;Files As Metadata format&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If I want to publish it, I just do this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;function&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;--iso-8601=seconds&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; pub_at &lt;span class=&quot;comment&quot;&gt;# 2024-07-05T23:02:34+03:30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The folder would look like this. The application I built checks for the existence of the file and the validity of the date. And we are good to go.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;#x2f;posts
└──&amp;#x2f;files_as_metadata_format
   ├── content.dj 
   ├── upd_at
   ├── pub_at &amp;lt;-- Here
   ├── cre_at
   ├── title
   ├── slug
   └── tags 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A more advanced structure may look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uses
├── cre_at
├── description
├── pub_at
├── tags
├── title
├── upd_at  
└──&amp;#x2f;things
   ├──&amp;#x2f;editor
   │  ├── main
   │  └── substitute
   ├──&amp;#x2f;languages
   │  ├── main
   │  └── substitute
   └──&amp;#x2f;os
      ├── main
      └── substitute
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Imagine a page like my &lt;a href=&quot;/uses&quot;&gt;uses&lt;/a&gt; page. 
you have a list of stuff, and you have the information and content of the page itself.&lt;/p&gt;
&lt;p&gt;Here you can see a key-value structure under things, where each value is its own object.&lt;/p&gt;
&lt;p&gt;Now, you might have noticed the tags file.  Isn’t that a list?
Well, yes, it is, but it is just a list of single values. That is separated by a line break.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;famf
information
metadata
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can easily parse this using &lt;code&gt;awk&lt;/code&gt;, &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;fzf&lt;/code&gt;, your language’s split or  lines function and on and on.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Why&quot;&gt;
&lt;h2&gt;Why?&lt;/h2&gt;
&lt;p&gt;It is extremely simple; you don’t need to adhere to any kind of syntax, and you won’t need formatters. You won’t need special editors. You have the best tooling: &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, &lt;code&gt;cp&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;cat&lt;/code&gt;, &lt;code&gt;sed&lt;/code&gt;, etc.
If that’s not enough for you, you won’t need weird templates; they are easier to read, program, and track. 
You don’t need any parsers. You are free to use any language you want. 
You can put photos, zip files, binaries, texts, etc. 
You can also only read titles, publication dates, or any other fields without needing to parse all the files.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Wouldn’t-that-just-reduce-performance-because-of-all-the-IOs&quot;&gt;
&lt;h2&gt;Wouldn’t that just reduce performance because of all the IOs?&lt;/h2&gt;
&lt;p&gt;Yeah, sure. I made a simple benchmark, actually. Here is the result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bench    fastest       │ slowest       │ median        │ mean          │ samples │ iters
├─ famf  9.591 µs      │ 1.182 ms      │ 10.18 µs      │ 11.12 µs      │ 1000000 │ 1000000
╰─ toml  7.852 µs      │ 726.9 µs      │ 8.132 µs      │ 8.673 µs      │ 1000000 │ 1000000  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, there is not &lt;strong&gt;that&lt;/strong&gt; much of a difference.
And this benchmark favors &lt;abbr title=&quot;Tom&apos;s Obvious, Minimal Language&quot; tabindex=&quot;0&quot;&gt;TOML&lt;/abbr&gt;, since the &lt;abbr title=&quot;Tom&apos;s Obvious, Minimal Language&quot; tabindex=&quot;0&quot;&gt;TOML&lt;/abbr&gt; is not inside another markup file, in which case you must first extract the &lt;abbr title=&quot;Tom&apos;s Obvious, Minimal Language&quot; tabindex=&quot;0&quot;&gt;TOML&lt;/abbr&gt; from that file, before you can parse it. While the &lt;abbr title=&quot;Files As Metadata Format&quot; tabindex=&quot;0&quot;&gt;FAMF&lt;/abbr&gt; structure does not work any differently, . 
Added to that, we are not counting the cases where you just want to get a list of titles. In those cases &lt;abbr title=&quot;Files As Metadata Format&quot; tabindex=&quot;0&quot;&gt;FAMF&lt;/abbr&gt; only opens the title files, while &lt;abbr title=&quot;Tom&apos;s Obvious, Minimal Language&quot; tabindex=&quot;0&quot;&gt;TOML&lt;/abbr&gt;, in the best-case scenario, has to use a specialized parser to read the stream of content, parse it until it reaches the end of &lt;abbr title=&quot;Tom&apos;s Obvious, Minimal Language&quot; tabindex=&quot;0&quot;&gt;TOML&lt;/abbr&gt;, and then it will give you the value. Which is not even what happens in the most actual real-world cases.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;How-about-all-the-tooling&quot;&gt;
&lt;h2&gt;How about all the tooling?&lt;/h2&gt;
&lt;p&gt;Yes &lt;abbr title=&quot;Tom&apos;s Obvious, Minimal Language&quot; tabindex=&quot;0&quot;&gt;TOML&lt;/abbr&gt;, &lt;abbr title=&quot;YAML Ain&apos;t Markup Language&quot; tabindex=&quot;0&quot;&gt;YAML&lt;/abbr&gt;, &lt;abbr title=&quot;Java Script Object Notation&quot; tabindex=&quot;0&quot;&gt;JSON&lt;/abbr&gt; and others have great tooling. 
You know what else has great tooling? Files!
Every file manager, file manipulation tool, and file search tool is helping you navigate those bad boys.&lt;/p&gt;
&lt;p&gt;The only thing lacking are schema validation tools.&lt;/p&gt;
&lt;p&gt;And that should not be that hard to implement as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Is-this-actually-new&quot;&gt;
&lt;h2&gt;Is this actually new?&lt;/h2&gt;
&lt;p&gt;I am not sure. It should not be. But it is not a common practice outside of Unix file systems. And even then, &lt;code&gt;.conf&lt;/code&gt; and &lt;code&gt;.ini&lt;/code&gt; files, as well as other weird formats, are not uncommon.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;If-it-is-a-better-idea-than-why-won’t-everyone-use-it&quot;&gt;
&lt;h2&gt;If it is a better idea than &lt;abbr title=&quot;Java Script Object Notation&quot; tabindex=&quot;0&quot;&gt;JSON&lt;/abbr&gt; why won’t everyone use it?&lt;/h2&gt;
&lt;p&gt;I don’t know. Who cares! Shut up!&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Update-on-2024-07-08&quot;&gt;
&lt;h2&gt;Update on 2024-07-08&lt;/h2&gt;
&lt;p&gt;Some people on &lt;a href=&quot;https://lobste.rs/s/uboac6/files_as_metadata_format#c_son8va&quot;&gt;lobste.rs&lt;/a&gt; started a very interesting discussion.
One that is worth considering.
And that is the limitations of how the file is being stored and accessed, and in general, file-system limitations;
And lack of atomicity in changes.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The impact of a high number of inodes and the limitations of the number of inodes in Unix-like systems. A very valid point. For which I created 4 million directories, under each 40 text files, with different text content. I replaced a random file’s content using good ol’ &lt;code&gt;sed&lt;/code&gt;. And, of course, I timed it. I did the same thing after deleting every directory but one. And timed it again. And did that manually a few times. The fluctuations in the performance of the system made more difference to performance than the existence of 3,999,999 other directories.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Atomicity in changing the information is also another interesting point. For example, if I want to update the &lt;code&gt;content.dj&lt;/code&gt; file, I also need to change the &lt;code&gt;upd_at&lt;/code&gt; file as well. In such cases, if I suddenly get interrupted, I might have changed the &lt;code&gt;content.dj&lt;/code&gt; without changing the &lt;code&gt;upd_at&lt;/code&gt;. Also, another program might have had the same idea of changing it. That is not desirable. However, &lt;abbr title=&quot;Tom&apos;s Obvious, Minimal Language&quot; tabindex=&quot;0&quot;&gt;TOML&lt;/abbr&gt;, &lt;abbr title=&quot;YAML Ain&apos;t Markup Language&quot; tabindex=&quot;0&quot;&gt;YAML&lt;/abbr&gt; and friends only offer those nifty features if you are putting everything in one giant file. And that is because you have to load all the information at once, lock on the file, and then rewrite the whole thing. You may also think that you might change them line by line. But that is assuming that you know which lines, you have the proper serializer, and you don’t mind at least loading all the information on the memory or streaming the file, which only helps you with data-races.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In all of these cases, the answer is not &lt;abbr title=&quot;Tom&apos;s Obvious, Minimal Language&quot; tabindex=&quot;0&quot;&gt;TOML&lt;/abbr&gt;, &lt;abbr title=&quot;YAML Ain&apos;t Markup Language&quot; tabindex=&quot;0&quot;&gt;YAML&lt;/abbr&gt; or &lt;abbr title=&quot;Java Script Object Notation&quot; tabindex=&quot;0&quot;&gt;JSON&lt;/abbr&gt; — or &lt;abbr title=&quot;Files As Metadata Format&quot; tabindex=&quot;0&quot;&gt;FAMF&lt;/abbr&gt; for what it’s worth. It is goddamn &lt;strong&gt;&lt;strong&gt;database&lt;/strong&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Old Is Not Lazy</title><id>urn:uuid:0fc0070b-bde5-41e8-8eff-d5e220ba7fcb</id><updated>2024-06-27T08:37:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="technology" label="technology"/><category term="software" label="software"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/old-is-not-lazy" rel="alternate" hreflang="en" type="text/html"/><published>2024-06-27T08:37:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Old stuff sometimes are more reasonable then the new ones.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;When I was growing up, I viewed adults aversion to the new thing as a result of laziness.&lt;/p&gt;
&lt;p&gt;Then I grew up. And I am noticing that many of the problems we are facing on a daily-basis, have shitty new solutions. When I look into before my time, I often find out there is a well tested, mature, and efficient solution, with its only fault being &lt;strong&gt;“not as shiny”&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I become less and less contempt with what I get with &lt;strong&gt;“new”&lt;/strong&gt; stuff. The old stuff is also &lt;strong&gt;new to me&lt;/strong&gt;. But they are not &lt;strong&gt;new to the world&lt;/strong&gt;.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Simplicity Of Maintaining</title><id>urn:uuid:8a454fc6-98bd-4e42-8f97-c2d9f346b7f4</id><updated>2024-06-25T13:47:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="programming" label="programming"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/simplicity-of-maintaining" rel="alternate" hreflang="en" type="text/html"/><published>2024-06-25T13:47:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Differing thoughts in simplicity show&apos;s when it comes to people evaluating programming languages.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I think there is conflict with people that confuse &lt;strong&gt;simplicity of a programming language&lt;/strong&gt; with &lt;strong&gt;simplicity of writing, reading and maintaining a program written in a language&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Iterators increase the complexity of the language, but at least for me, decrease the complexity and extensibility of my codes significantly.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Blog From Scratch</title><id>urn:uuid:07f8fd0b-21d5-4c8a-9594-a7f9df998ec6</id><updated>2025-05-30T15:42:27+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="blog" label="blog"/><category term="meta" label="meta"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/blog-from-scratch" rel="alternate" hreflang="en" type="text/html"/><published>2024-06-09T15:14:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I rewrote my blog.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;First off, to all those who have subscribed to my feed: &lt;strong&gt;&lt;strong&gt;I am genuinely sorry for the massive amount of spam in the feed!&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have rewritten my blog from scratch. What was once a statically generated blog &lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, is now a fully functioning web server written in Rust.&lt;/p&gt;
&lt;section id=&quot;Why&quot;&gt;
&lt;h2&gt;Why&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/strong&gt;: Learning and flexibility.&lt;/p&gt;
&lt;p&gt;&lt;abbr title=&quot;Static Site Generator&quot; tabindex=&quot;0&quot;&gt;SSG&lt;/abbr&gt;s are great. They make the web a better place to be.
They make it faster, lighter, more accessible, and more stable.  
You have a couple of pages, you create those pages, and… &lt;strong&gt;&lt;strong&gt;&lt;strong&gt;bam&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;!
You have a pretty and stable site for yourself.
They have many, many varieties. Most, take a few templates and some Markdown files, and create a bunch of &lt;abbr title=&quot;HyperText Markup Language&quot; tabindex=&quot;0&quot;&gt;HTML&lt;/abbr&gt; pages. My favorite of this bunch is &lt;a href=&quot;https://gohugo.io&quot;&gt;Hugo&lt;/a&gt; which pretty fast, feature-full, and well-structured.
Others are more interesting; they basically create the same pipeline: &lt;code&gt;content + template = HTML&lt;/code&gt;. Yet they have different presumptions. Of these bunch, I absolutely adore &lt;a href=&quot;https://soupault.app/&quot;&gt;Soupault&lt;/a&gt;. This one uses &lt;abbr title=&quot;HyperText Markup Language&quot; tabindex=&quot;0&quot;&gt;HTML&lt;/abbr&gt; and &lt;abbr title=&quot;Cascading Style Sheets&quot; tabindex=&quot;0&quot;&gt;CSS&lt;/abbr&gt; as their templating engine and does not presume any particular content type. You bring your own converter. You may use anyone or a few different Markup languages. It is fantastic.&lt;/p&gt;
&lt;p&gt;However, each has its own flaws. And you can only go so far with static pages.&lt;/p&gt;
&lt;p&gt;Some of the things that have constrained me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
I like to be able to choose which Markup language I use at each moment.
I might like to write some on Markdown, others in Djot, Others still in Org-Mode.
And then I do my own modifications, macros, and extensions.
Some &lt;abbr title=&quot;Static Site Generator&quot; tabindex=&quot;0&quot;&gt;SSG&lt;/abbr&gt;s give you some choice in the matter. But other than &lt;a href=&quot;https://soupault.app/&quot;&gt;Soupault&lt;/a&gt;, you are usually at the mercy of the choices of the &lt;abbr title=&quot;Static Site Generator&quot; tabindex=&quot;0&quot;&gt;SSG&lt;/abbr&gt; maintainer.
&lt;/li&gt;
&lt;li&gt;
I would like to have dedicated feeds for each category. Most &lt;abbr title=&quot;Static Site Generator&quot; tabindex=&quot;0&quot;&gt;SSG&lt;/abbr&gt;s avoid letting you do that or give you limited choice on the format of the feed.
&lt;/li&gt;
&lt;li&gt;
You can do wonders with templating languages. But the tooling is usually horrible; the disasters only manifest themselves when you visit and validate each page, and doing things like showing specific posts only on the feeds requires the &lt;abbr title=&quot;Static Site Generator&quot; tabindex=&quot;0&quot;&gt;SSG&lt;/abbr&gt; to make the metadata available to you and for you to do pretty clunky conditionals using the templating language.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And then, there are things that you can only do, when you have access to the Runtime of the server.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
You cannot receive drafts and posts without having access to the coding environment — I don’t do it right now here, but I Intend to add one in the future.
&lt;/li&gt;
&lt;li&gt;
Some things, like Web Mentions, require the access to server.
&lt;/li&gt;
&lt;li&gt;
Having more interactivity, using things like &lt;a href=&quot;https://htmx.org/&quot;&gt;HTMX&lt;/a&gt;, is simply not possible using &lt;abbr title=&quot;Static Site Generator&quot; tabindex=&quot;0&quot;&gt;SSG&lt;/abbr&gt;s.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Add to all of these the fact that I am a Back-end developer. Sometimes I may want to experiment with different ideas. Some of these ideas may not be a good fit for the projects I work on, during my day job. Or my teammates may not agree with me about their suitability. Having a web server as a home lab has been a great desire of mine!&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;What-did-I-choose&quot;&gt;
&lt;h2&gt;What did I choose?&lt;/h2&gt;
&lt;p&gt;Over time, during the creation of the web application, I have experimented with different things. And I have made choices about others. Let me explain each.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://rust-lang.org&quot;&gt;Rust&lt;/a&gt; is a pretty great language. But One thing it is not is &lt;strong&gt;simple&lt;/strong&gt;.
I am very confident with &lt;a href=&quot;https://go.dev&quot;&gt;Go&lt;/a&gt;. And I am also learning &lt;a href=&quot;https://gleam.run&quot;&gt;Gleam&lt;/a&gt;.
Both of them later offer a much simpler workflow. 
However, wanting to have maximum flexibility, &lt;a href=&quot;&quot;&gt;Rust&lt;/a&gt; is a better language for me. Added to that, things like dealing with nil-pointers in &lt;a href=&quot;https://go.dev&quot;&gt;Go&lt;/a&gt; have been a source of constant pain in my ass. &lt;a href=&quot;https://rust-lang.org&quot;&gt;Rust&lt;/a&gt; offers less chance of Runtime error.&lt;/p&gt;
&lt;p&gt;You may not have heard of &lt;a href=&quot;https://djot.net/&quot;&gt;Djot&lt;/a&gt;. &lt;a href=&quot;https://djot.net/&quot;&gt;Djot&lt;/a&gt; is created by the creator of Pandoc, the command-line utility that converts different document formats. It is pretty similar to Markdown, but with the significant advantage of being created by someone who has spent a significant amount of time working with markup languages instead of &lt;a href=&quot;https://daringfireball.net/2004/03/introducing_markdown&quot;&gt;some random blogger suggesting something at some point in their blog post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I am using a library called InkJet which uses tree-sitter to add syntax highlighting to my code blocks. I have injected it into the Djot parser I use, called Jotdown.&lt;/p&gt;
&lt;p&gt;Also, I have decided to hard-code the contents for now. So at compilation time, every &lt;a href=&quot;https://djot.net/&quot;&gt;Djot&lt;/a&gt; file is read and embedded inside the web server. This just simplifies things for now for me. But I have implemented the whole thing so that I can inject dynamic contents later on.&lt;/p&gt;
&lt;p&gt;During my &lt;abbr title=&quot;Application Programming Interface&quot; tabindex=&quot;0&quot;&gt;API&lt;/abbr&gt; testing, I have noticed that the performance of the new version could not match the statically generated one, using the built-in server of Hugo. Upon further inspection, the culprit was the rendering process. Which took the time of serving up each page on the local storage from 5ms to 15ms. Though not a lot, It could be easily fixed using a lazily created on-memory cache layer for each page and feed. 
So each page gets rendered only once, right after I update the site.
Easy.&lt;/p&gt;
&lt;section id=&quot;Uberspace&quot;&gt;
&lt;h3&gt;&lt;code&gt;Uberspace&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Thanks to the suggestion of &lt;a href=&quot;https://benjaminhollon.com/&quot;&gt;Benjamin Hollon&lt;/a&gt;, I have found a really small-web-friendly hosting service called &lt;a href=&quot;https://uberspace.de/&quot;&gt;uberspace.de&lt;/a&gt; with a generously priced €5/month service. The OS is a bit out of date right now &lt;a id=&quot;fnref2&quot; href=&quot;#fn2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;, and that is causing a bit of a pain during the build process, but honestly, their service is so lovely and Linux-friendly that I could not consider any other service!&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id=&quot;What-have-I-lost&quot;&gt;
&lt;h2&gt;What have I lost?&lt;/h2&gt;
&lt;p&gt;Everything has its trade-offs. And there are some really great reasons for not doing what I have done.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Previously, adding a blog post was as simple as creating a file, and running a &lt;code&gt;Justfile&lt;/code&gt; &lt;a id=&quot;fnref3&quot; href=&quot;#fn3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;. 
Right now, I have to create a couple of files, add the post to the dedicated array, and then build it using Nix Flake &lt;a id=&quot;fnref4&quot; href=&quot;#fn4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt;, and then rsync the resulting binary to the server and restarting the service using ssh.
&lt;/li&gt;
&lt;li&gt;
Added to that, the compilation time is significant. And CPU-intensive. For some reason, some of the C dependencies of Tree-sitter that I depend on are not friendly to incremental builds. I am seriously considering dropping syntax-highlighting as a result!
&lt;/li&gt;
&lt;li&gt;
Another con of this method is obviously having to pay for it! I cannot mooch off of &lt;a href=&quot;https://srht.site/&quot;&gt;sourcehut pages&lt;/a&gt; anymore!
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;It was generated using &lt;a href=&quot;https://gohugo.io&quot;&gt;Hugo&lt;/a&gt;&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;
&lt;p&gt;I have contacted their support team. They told me that they are working on an update.&lt;a href=&quot;#fnref2&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot;&gt;
&lt;p&gt;Or &lt;strong&gt;Hipster’s &lt;code&gt;Makefile&lt;/code&gt;&lt;/strong&gt; if you will!&lt;a href=&quot;#fnref3&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot;&gt;
&lt;p&gt;The build pain that I mentioned earlier!&lt;a href=&quot;#fnref4&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Evils Of Effective Altruism</title><id>urn:uuid:5db089a1-4277-4d09-9b2c-4313f83196c0</id><updated>2024-05-13T11:24:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="ethics" label="ethics"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/evils-of-effective-altruism" rel="alternate" hreflang="en" type="text/html"/><published>2024-05-13T11:24:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I discuss my dilemma with regards to the Effective Altruism fans.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I have been a Utilitarianist my entire life. While I didn’t have a name for it, I evaluated every action based on its eventual effect on the suffering and happiness of conscious beings.&lt;/p&gt;
&lt;p&gt;Being born in an Islamic country, I was aware that my views were not shared by many. However, I always wondered why&lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I instinctively became a feminist in an all-boys school, even in one of the most patriarchal countries in the world. Additionally, I ended up becoming a Vegan without any social proximity to anyone with that identity.&lt;/p&gt;
&lt;p&gt;I became familiar with live and dead proponents of this branch of Prescriptive Ethics while exploring Ethics during my early 20s. Among them, I found agreement with some, such as Peter Singer, who advocated for Animal Rights and provided valuable insights into maintaining a consistent utilitarianistic view.&lt;/p&gt;
&lt;p&gt;Peter Singer introduced the concept of &lt;strong&gt;Effective Altruism&lt;/strong&gt; in recent times. In essence, it asserts that when being altruistic, your intentions are irrelevant. What truly matters is the improvement in the world following your actions. For example, a donation to charity that builds a church in your neighborhood is less ethically valuable than a donation that funds vaccinating children, even if the latter was done as a PR stunt.&lt;/p&gt;
&lt;p&gt;However, as Molly White have so well demonstrated it &lt;a id=&quot;fnref2&quot; href=&quot;#fn2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;, Billionaires and Millionaires in Silicon Valley have bastardized this idea, to the point that they only do the PR stunt, if we are lucky.&lt;/p&gt;
&lt;p&gt;In his book, &lt;strong&gt;The Most Good You Can Do&lt;/strong&gt;, Peter Singer provides an example of one of his students who joined Wall Street to earn a significant amount of money, which they could then use for effectively altruistic purposes.&lt;/p&gt;
&lt;p&gt;The example provided was meant to demonstrate the seemingly counterintuitive reasoning behind being effective in altruistic endeavors.&lt;/p&gt;
&lt;p&gt;Those with significant interests in maintaining the status quo found parts of this example to be extremely convenient. In particular, the notion that “hoarding money &lt;strong&gt;can&lt;/strong&gt; be ethical!” appeared to be their primary focus, while other aspects of the idea were largely overlooked.&lt;/p&gt;
&lt;p&gt;This kind of bastardization of Utilitarian Ethics has been done before, most prominently by Joseph Stalin, to justify purges and famine. Specifically he used the term “Greater Good”. Which I believe at least has the tone of Utilitarianism.&lt;/p&gt;
&lt;p&gt;In this case, we can argue that Joseph Stalin did not actually adhere to any utilitarianistic ethic principles, as his actions did not bring about much utility as a consequence of his actions. However, consequences are hard to predict, and judgments can only be made in hindsight. Due to the practical vagueness, anyone can find rationalization for any action. So, if this prescriptive ethics is so permissible that does not help anyone, is it really an acceptable theory?&lt;/p&gt;
&lt;p&gt;In this case, Deontology fares much better, as it advocates specific actions. For instance, “lying is bad.” This is really helpful, as it allows you to simply avoid lying and be considered good. There is a quote used by Immanuel Kant &lt;a id=&quot;fnref3&quot; href=&quot;#fn3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; in his book &lt;strong&gt;Project for a Perpetual Peace: A Philosophical Essay&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fiat justitia, pereat mundus&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This quote, “Fiat justitia, pereat mundus”, literally means “Let justice be done, let the world perish”. In a deontological absolute world, people would not lie, even if one little lie could save the world from burning.&lt;/p&gt;
&lt;p&gt;This example highlights an extreme case of adhering to deontology, but it also showcases the simplicity and straightforwardness of the concept.&lt;/p&gt;
&lt;p&gt;However, even though rules of deontology are simple to know and hard to adhere to, there is a rich history of religious figures justifying their endless lies and actions in the name of deontological rules.&lt;/p&gt;
&lt;p&gt;In the city where I reside, the Morality Police imprison individuals, administer corporal punishments, and even sanction death sentences, all justified by the Deontological rules of Islam. Additionally, there is the concept of Expedient Lies, where one lies for a specific purpose, if it helps the religion.&lt;/p&gt;
&lt;p&gt;Oh we landed on the same place after all!&lt;/p&gt;
&lt;p&gt;In our Effective Altruism case, I see a parallel. Justifying the accumulation of wealth without using it to significantly improve the world, under the guise of Effective Altruism, is akin to actively contributing to the preishment of world while not engaging in any acts of moral value, in the name of Deontology.&lt;/p&gt;
&lt;p&gt;The intentional misuse of philosophies to justify horrendous actions is not a new phenomenon, nor is it exclusive to utilitarianism. Any moral perspective can be manipulated to rationalize any behavior.&lt;/p&gt;
&lt;p&gt;But there’s another problem in this situation. A prescriptive theory should provide guidance. It should assist us in making decisions in our everyday lives. If it’s permissive, allowing anything to happen, is it still a good normative theory?&lt;/p&gt;
&lt;p&gt;Here, I remain undecided. One argument for utilitarianism is that uncertainty does not usually hinder us. There is evidence suggesting that food X may cause cancer, and some evidence refuting it. We might not have a definitive answer at present. The current uncertainty in biology does not compel us to abandon the field entirely and gravitate towards the more straightforward and certain Jewish food regimen.
But predicting the future is far from simple. As uncertainty grows, so does the challenge of adhering to utilitarianism.&lt;/p&gt;
&lt;p&gt;This is often evident in more intricate situations. Where there is a likelihood of the interests of future beings conflicting with the social interests of presently living individuals.&lt;/p&gt;
&lt;p&gt;In certain more evident instances, like slavery, animal cruelty, and sexism, utilitarianists have typically been ahead of their deontologist contemporaries.&lt;/p&gt;
&lt;p&gt;For me, I think I will stick with utilitarianism. I believe that, in general, utilitarianism has been more clear than some other theories. And I don’t think individuals who abuse this theory are any more prevalent than those who have misused deontology.&lt;/p&gt;
&lt;p&gt;You may have observed that I have not discussed another significant branch of prescriptive ethical theories, Virtue Ethics. Although I can appreciate the importance of incorporating virtues into one’s actions, I don’t see it providing any guidance on what is good and what is bad.&lt;/p&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;I have recently familiarized myself with the idea that there could be distinct &lt;strong&gt;Moral Instincts&lt;/strong&gt; or &lt;strong&gt;Moral Senses&lt;/strong&gt; influencing people’s diverse choices in Prescriptive Ethics. I might be situated at the far end of the spectrum in this context.
If you want to know more about this, look into “Moral foundations’ theory”.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;
&lt;p&gt;A very interesting and thoughtful post on her blog &lt;strong&gt;Citation Needed&lt;/strong&gt; titled: &lt;a href=&quot;https://www.citationneeded.news/effective-obfuscation/&quot;&gt;Effective Obfuscation&lt;/a&gt;&lt;a href=&quot;#fnref2&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot;&gt;
&lt;p&gt;He used it as a demonstrative example, but he did not originate it.&lt;a href=&quot;#fnref3&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">u8 vs. u128</title><id>urn:uuid:d946b8e7-d629-44fb-9513-e98cde2ef0dc</id><updated>2025-05-30T15:52:11+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="programming" label="programming"/><category term="rust" label="rust"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/u8-vs-u128" rel="alternate" hreflang="en" type="text/html"/><published>2024-05-01T13:20:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I compared the performance of u8 with u32 and u64 and u128 in Rust.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;A few days ago, I read a discussion on a YouTube video.
The essence of the discussion was that memory layout and memory size matter.&lt;/p&gt;
&lt;p&gt;So, an unsigned &lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; 8-bit integer (or &lt;code&gt;u8&lt;/code&gt; in Rust) takes up less memory and thus is faster than a &lt;code&gt;u128&lt;/code&gt;. However, someone else added a caveat: the memory layout can differ based on the architecture. Another point made was that 32 and 64-bit integers are probably faster, as modern CPUs optimize these values thoroughly. Therefore, a &lt;code&gt;u8&lt;/code&gt; is probably slower than a &lt;code&gt;u32&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On the face of it, the argument made sense. However, two things made me wonder:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Is it true?
&lt;/li&gt;
&lt;li&gt;
Are the differences so vast that I should consider using &lt;code&gt;u8&lt;/code&gt;, &lt;code&gt;u32&lt;/code&gt;, or &lt;code&gt;u64&lt;/code&gt; for IDs of my structs instead of &lt;code&gt;u128&lt;/code&gt;?
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Like a good Bayesian thinker, I opted to look into some evidence.&lt;/p&gt;
&lt;p&gt;So, I’ve written a program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;attribute&quot;&gt;#&lt;span class=&quot;punctuation bracket&quot;&gt;[&lt;/span&gt;derive&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;Debug&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor&quot;&gt;Clone&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; serde&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;Serialize&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; serde&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;Deserialize&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SomeThing&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    item&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type builtin&quot;&gt;u128&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;*and this one*&amp;#x2f;&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;make255&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SomeThing&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant builtin&quot;&gt;0&lt;/span&gt;..&lt;span class=&quot;constant builtin&quot;&gt;255u128&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;* &amp;lt;- changing this number*&amp;#x2f;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;|n| &lt;span class=&quot;type&quot;&gt;SomeThing&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt; item&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; n &lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; 65_535 * 255 =  16_711_425 &amp;#x2f;&amp;#x2f; numbers&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; 33_422_850 * 2 = 33_422_850  &amp;#x2f;&amp;#x2f; Since we are reformatting those numbers once again when converting them back from strings&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; 33_422_850 * 100 = 3_342_285_000 &amp;#x2f;&amp;#x2f; For 100 times&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; material&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt; = &lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant builtin&quot;&gt;0&lt;/span&gt;..u16&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;MAX&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;*65535*&amp;#x2f;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;flat_map&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;|_| &lt;span class=&quot;function&quot;&gt;make255&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; stringed = serde_json&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;to_string&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;material&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;fucked&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; _unstringed =
        serde_json&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from_str&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SomeThing&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;stringed&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;could not deserialize&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I created four editions of the above code, with &lt;code&gt;u8&lt;/code&gt;, &lt;code&gt;u32&lt;/code&gt;, &lt;code&gt;u64&lt;/code&gt;, and &lt;code&gt;u128&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I built them using &lt;code&gt;cargo build --release&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Each run of the program would create around 33 million structs.&lt;/p&gt;
&lt;p&gt;Each containing a number between 0 to 255 &lt;a id=&quot;fnref2&quot; href=&quot;#fn2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;, and then turn each into a &lt;abbr title=&quot;Java Script Object Notation&quot; tabindex=&quot;0&quot;&gt;JSON&lt;/abbr&gt; string and then turn them back into &lt;code&gt;SomeThing&lt;/code&gt; structs.&lt;/p&gt;
&lt;p&gt;As a backend developer, this covers one of the more important concerns of mine, which is serializing and deserializing &lt;a id=&quot;fnref3&quot; href=&quot;#fn3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I used &lt;code&gt;hyperfine&lt;/code&gt; to run each binary 100 times. This means that for each type, we created 3 billion units.&lt;/p&gt;
&lt;p&gt;Here are the results for the &lt;code&gt;u8&lt;/code&gt; version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;function&quot;&gt;❯&lt;/span&gt; hyperfine  &lt;span class=&quot;constant&quot;&gt;--runs&lt;/span&gt; 100 .&amp;#x2f;u8version  &lt;span class=&quot;constant&quot;&gt;--export-json&lt;/span&gt; 8.json
&lt;span class=&quot;function&quot;&gt;Benchmark&lt;/span&gt; 1: .&amp;#x2f;u8version
  &lt;span class=&quot;function&quot;&gt;Time&lt;/span&gt; (&lt;span class=&quot;function&quot;&gt;mean&lt;/span&gt; ± σ):     &lt;span class=&quot;function&quot;&gt;921.9&lt;/span&gt; ms ±  72.6 ms    [User: 854.1 ms, System: 65.4 ms]
  &lt;span class=&quot;function&quot;&gt;Range&lt;/span&gt; (&lt;span class=&quot;function&quot;&gt;min&lt;/span&gt; … max):   &lt;span class=&quot;function&quot;&gt;801.2&lt;/span&gt; ms … 1082.6 ms    100 runs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here are the results for the &lt;code&gt;u32&lt;/code&gt; version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;function&quot;&gt;✦&lt;/span&gt; ❯ hyperfine  &lt;span class=&quot;constant&quot;&gt;--runs&lt;/span&gt; 100 .&amp;#x2f;u32version  &lt;span class=&quot;constant&quot;&gt;--export-json&lt;/span&gt; 32.json
&lt;span class=&quot;function&quot;&gt;Benchmark&lt;/span&gt; 1: .&amp;#x2f;u32version
  &lt;span class=&quot;function&quot;&gt;Time&lt;/span&gt; (&lt;span class=&quot;function&quot;&gt;mean&lt;/span&gt; ± σ):     &lt;span class=&quot;function&quot;&gt;957.6&lt;/span&gt; ms ±  70.0 ms    [User: 860.1 ms, System: 95.1 ms]
  &lt;span class=&quot;function&quot;&gt;Range&lt;/span&gt; (&lt;span class=&quot;function&quot;&gt;min&lt;/span&gt; … max):   &lt;span class=&quot;function&quot;&gt;876.6&lt;/span&gt; ms … 1134.1 ms    100 runs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here are the results for the &lt;code&gt;u64&lt;/code&gt; version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;function&quot;&gt;✦&lt;/span&gt; ❯ hyperfine  &lt;span class=&quot;constant&quot;&gt;--runs&lt;/span&gt; 100 .&amp;#x2f;u64version  &lt;span class=&quot;constant&quot;&gt;--export-json&lt;/span&gt; 64.json
&lt;span class=&quot;function&quot;&gt;Benchmark&lt;/span&gt; 1: .&amp;#x2f;u64version
  &lt;span class=&quot;function&quot;&gt;Time&lt;/span&gt; (&lt;span class=&quot;function&quot;&gt;mean&lt;/span&gt; ± σ):     &lt;span class=&quot;function&quot;&gt;969.8&lt;/span&gt; ms ±  21.9 ms    [User: 836.9 ms, System: 130.3 ms]
  &lt;span class=&quot;function&quot;&gt;Range&lt;/span&gt; (&lt;span class=&quot;function&quot;&gt;min&lt;/span&gt; … max):   &lt;span class=&quot;function&quot;&gt;890.5&lt;/span&gt; ms … 1038.4 ms    100 runs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And finally, here are the results for the &lt;code&gt;u128&lt;/code&gt; version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;function&quot;&gt;✦&lt;/span&gt; ❯ hyperfine  &lt;span class=&quot;constant&quot;&gt;--runs&lt;/span&gt; 100 .&amp;#x2f;u128version  &lt;span class=&quot;constant&quot;&gt;--export-json&lt;/span&gt; 128.json
&lt;span class=&quot;function&quot;&gt;Benchmark&lt;/span&gt; 1: .&amp;#x2f;u128version
  &lt;span class=&quot;function&quot;&gt;Time&lt;/span&gt; (&lt;span class=&quot;function&quot;&gt;mean&lt;/span&gt; ± σ):      &lt;span class=&quot;function&quot;&gt;1.421&lt;/span&gt; s ±  0.022 s    [User: 1.210 s, System: 0.206 s]
  &lt;span class=&quot;function&quot;&gt;Range&lt;/span&gt; (&lt;span class=&quot;function&quot;&gt;min&lt;/span&gt; … max):    &lt;span class=&quot;function&quot;&gt;1.371&lt;/span&gt; s …  1.473 s    100 runs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, compared to the &lt;code&gt;u8&lt;/code&gt; version, the &lt;code&gt;u32&lt;/code&gt; version took only &lt;strong&gt;&lt;strong&gt;3%&lt;/strong&gt;&lt;/strong&gt; more time, the &lt;code&gt;u64&lt;/code&gt; version only &lt;strong&gt;&lt;strong&gt;5%&lt;/strong&gt;&lt;/strong&gt; more, and the &lt;code&gt;u128&lt;/code&gt; version around &lt;strong&gt;&lt;strong&gt;54%&lt;/strong&gt;&lt;/strong&gt; more time.&lt;/p&gt;
&lt;p&gt;The difference between &lt;code&gt;u8&lt;/code&gt;, &lt;code&gt;u32&lt;/code&gt;, and &lt;code&gt;u64&lt;/code&gt; is so minuscule that I cannot help but agree that they are extremely optimized. It’s probably not faster than &lt;code&gt;u8&lt;/code&gt;, but it is fair to say that when you are concerned with performance, &lt;code&gt;u64&lt;/code&gt; is still as solid as &lt;code&gt;u8&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;u128&lt;/code&gt; is not as performant as the other types. But at this point, we should consider the amount of difference in time. Between &lt;code&gt;u8&lt;/code&gt; and &lt;code&gt;u128&lt;/code&gt;, there was only a 15 nanosecond difference. To put it into perspective, you would need 4 billion &lt;code&gt;u8&lt;/code&gt; instances instead of &lt;code&gt;u128&lt;/code&gt; to save one minute of computation time on my computer.&lt;/p&gt;
&lt;p&gt;In a back-end environment, such a small difference seems extremely negligible, making &lt;code&gt;u128&lt;/code&gt; with its extreme tolerance for integer overflow seem like a good deal.&lt;/p&gt;
&lt;section id=&quot;Update-3-hours-later-same-day&quot;&gt;
&lt;h1&gt;Update 3 hours later, same day &lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://fosstodon.org/@jsbarretto@social.coop/112366172970412624&quot;&gt;Joshua Barretto&lt;/a&gt; suggested that I should use black_box to fence against possible compiler optimization.
I took the benchmarkds again, and the results took significantly longer, around 50-60% more time. But they kept the same proportions. Specifically &lt;code&gt;u8&lt;/code&gt; took &lt;strong&gt;&lt;strong&gt;1.498&lt;/strong&gt;&lt;/strong&gt; seconds, &lt;code&gt;u32&lt;/code&gt; took &lt;strong&gt;&lt;strong&gt;1.565&lt;/strong&gt;&lt;/strong&gt; seconds, &lt;code&gt;u64&lt;/code&gt; took &lt;strong&gt;&lt;strong&gt;1.615&lt;/strong&gt;&lt;/strong&gt; seconds and &lt;code&gt;u128&lt;/code&gt; took &lt;strong&gt;&lt;strong&gt;2.289&lt;/strong&gt;&lt;/strong&gt; seconds.&lt;/p&gt;
&lt;p&gt;Here is the modified code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; std&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;hint&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;black_box&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;attribute&quot;&gt;#&lt;span class=&quot;punctuation bracket&quot;&gt;[&lt;/span&gt;derive&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;Debug&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor&quot;&gt;Clone&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; serde&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;Serialize&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; serde&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;Deserialize&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SomeThing&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    item&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type builtin&quot;&gt;u128&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; 
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;make255&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SomeThing&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;black_box&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant builtin&quot;&gt;0&lt;/span&gt;..&lt;span class=&quot;constant builtin&quot;&gt;255u128&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;|n| &lt;span class=&quot;type&quot;&gt;SomeThing&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt; item&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; n &lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;function&quot;&gt;black_box&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;|| &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; material&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt; = &lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant builtin&quot;&gt;0&lt;/span&gt;..u16&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;MAX&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;flat_map&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;|_| &lt;span class=&quot;function&quot;&gt;black_box&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;make255&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; stringed = &lt;span class=&quot;function&quot;&gt;black_box&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;serde_json&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;to_string&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;material&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;fucked&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; _unstringed = &lt;span class=&quot;function&quot;&gt;black_box&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;serde_json&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from_str&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SomeThing&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;stringed&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;punctuation delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;function method&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;could not deserialize&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/section&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;Unsigned means that it cannot contain anything less than 0.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;
&lt;p&gt;That’s because &lt;code&gt;u8&lt;/code&gt; is limited to 255.&lt;a href=&quot;#fnref2&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot;&gt;
&lt;p&gt;However, this may mean that another confounding factor is tinting our data: the libraries involved in serializing and deserializing may be the source of the difference. However, since I am looking for applicable scenarios, this works well in my favor.&lt;a href=&quot;#fnref3&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Go Vs. Rust Readability</title><id>urn:uuid:efc1299a-d7e4-486e-8bf4-5862aea1475f</id><updated>2024-04-14T22:19:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="opinion" label="opinion"/><category term="go" label="go"/><category term="programming" label="programming"/><category term="rust" label="rust"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/go-vs-rust-readability" rel="alternate" hreflang="en" type="text/html"/><published>2024-04-14T22:19:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I compare the readability of Rust and Go.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Traditionally speaking, Go and Rust are not direct competitors on many fronts. Each take different trade-offs. But more often than not, you might need to choose one over the other. It is compared in the niche the other fails. Like low-level system development, which Rust easily rules. Or maybe dev-ops tooling which Go is easily good at it.&lt;/p&gt;
&lt;p&gt;However, there are many overlaps in their use case. Think high-performance web-servers. In those spaces, we should compare other things. Like readability and maintainability of language. In this post, I want to share my thoughts on readability.&lt;/p&gt;
&lt;section id=&quot;TlDR&quot;&gt;
&lt;h2&gt;Tl;DR&lt;/h2&gt;
&lt;p&gt;Rust is not less maintainable than Go because Rust is less readable.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;What-I-do-not-disagree-with&quot;&gt;
&lt;h2&gt;What I do not disagree with&lt;/h2&gt;
&lt;p&gt;Just to be clear, although I’m making a case for Rust and arguing that readability should not be as much concern, I would like to make clear that I’m not arguing against these common-sense statements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Go is more readable.
&lt;/li&gt;
&lt;li&gt;
Go has less overhead for people with no previous experience with language.
&lt;/li&gt;
&lt;li&gt;
Readability is generally what you want.
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id=&quot;Why-readability-is-good&quot;&gt;
&lt;h2&gt;Why readability is good&lt;/h2&gt;
&lt;p&gt;English is more readable than any programming language. However, readability is not the only measure that we are using for choosing a language.&lt;/p&gt;
&lt;p&gt;Readability and clarity are not inherently good, rather it is a proxy for something else we value: A readable code helps us understand the flow of information in order to &lt;em&gt;&lt;strong&gt;&lt;strong&gt;understand its logic&lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;, &lt;em&gt;&lt;strong&gt;&lt;strong&gt;capture its bugs&lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;&lt;strong&gt;extend it&lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;, easier. A line of code is read in many situations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
I want to find out how a piece of code can give rise to a specific runtime bug.
&lt;/li&gt;
&lt;li&gt;
I want to audit it to see if it exposes any specific vulnerability, data-race, etc.
&lt;/li&gt;
&lt;li&gt;
I want to add features to it, and I want to know where and how I should plug the new functionality to.
&lt;/li&gt;
&lt;li&gt;
I want to make a code more robust, document it and make it more available for other people by refactoring it.
&lt;/li&gt;
&lt;li&gt;
I want to review the code of my colleague to see if a set of fresh eyes could capture a new bug, or an inconsistent styling with the rest of the codebase.
&lt;/li&gt;
&lt;li&gt;
I want to understand what a code base does. Maybe I’m trying to see if a software is spying on me, or maybe I’m trying to understand the way it calculated my taxes.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These are all noble pursuits. And in all these cases, readability is vital in preventing disasters and better experience in onboarding others.&lt;/p&gt;
&lt;p&gt;Go’s readability is probably one of its best features. At my current and previous jobs, I have had to jump into different code bases with different levels of legacy and problematic codebases where junior developers with no-idea of idiomatic ways of coding Go left their projects without any context for the next developer.&lt;/p&gt;
&lt;p&gt;Such low quality codes should take forever for one to decode. However, because of the beautifully simple syntax of Go, I could start to be productive and sending PRs in less than a day. Have you seen a codebase where all the back-end code was coded by a narcissistic lone-wolf meth-addict? Well, I have, and it’s an absolute shit-show. Yet, I committed my first edits in 3 hours. Go is excellent at that. And I can understand how a huge tech company with very quick employee turn-over can give rise to such language. Kudos to the Go team.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Surrendering Users&apos; Data at Gun-Point</title><id>urn:uuid:ed69f45e-d39c-461a-94f8-fe27c0b8cf06</id><updated>2025-05-30T15:32:12+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="backend" label="backend"/><category term="ethics" label="ethics"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/surrendering-users-data-at-gun-point" rel="alternate" hreflang="en" type="text/html"/><published>2024-04-13T22:29:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Should you surrender data at gunpoint? What data?</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Approximately a year ago, large companies in Iran began sharing their users’ information with the government.&lt;/p&gt;
&lt;p&gt;As a result, people began boycotting these companies. Engineers working at these companies faced criticism for handing over the data and continuing to work for these organizations. In response, they posted on their social media platforms, seeking sympathy and asking: “What would you have done if the army intelligence simply walked in and demanded all your data?”. That is a fair question. I cannot but agree that, given the same situation, I would have likely done the same.&lt;/p&gt;
&lt;p&gt;However, I was not in that situation. And that is the point.&lt;/p&gt;
&lt;p&gt;The engineers in these companies have built an impressive body of knowledge about their users. So much so that some of them have managed to assemble a team of AI- and Machine-Learning- experts, supplying their marketing teams with predictive information and trained models to increase their market share by playing with prices and outperforming their competitors. So the amount of information they have gathered is indeed impressive, and it far exceeds the amount needed for the app to function effectively.&lt;/p&gt;
&lt;p&gt;So, why do these engineers continue to store data they don’t actually need? I have three possible reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
They lack creativity in finding solutions that only gather information that is justified by the need.
&lt;/li&gt;
&lt;li&gt;
They are unwilling to risk their jobs.
&lt;/li&gt;
&lt;li&gt;
They lack understanding of the risks associated with storing these data.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let me offer an example of how things can be better:&lt;/p&gt;
&lt;p&gt;Imagine that Tim is tasked with cleaning up inactive users from the database and moving their data into an archiving database.&lt;/p&gt;
&lt;p&gt;How can Tim recognize the inactive users?&lt;/p&gt;
&lt;p&gt;Tim comes up with the solution of keeping track of user login dates. A giant append-only list for each user, where the time and date of each login is appended. From this data, Tim can identify users who have not logged in for over six months.&lt;/p&gt;
&lt;p&gt;This solution does more than just the job. It also provides a body of knowledge about user habits, their access to the internet, and the ratio of actions per login. This information, combined with data from other sources, become rich data sources that allow tracking every single step any user takes.&lt;/p&gt;
&lt;p&gt;Instead of the append-only list approach, Tim could have implemented a simpler solution using a boolean value for each user. Initially, this value would be set to &lt;code&gt;false&lt;/code&gt;, and once a user logs in, the database would update it to &lt;code&gt;true&lt;/code&gt;. After six months, Tim could easily generate a list of users who have not logged in.
This approach is more cost-effective, less susceptible to abuse, and still achieves the same result as the more complex solution.&lt;/p&gt;
&lt;p&gt;Storing plaintext passwords is undeniably a mistake, as it provides more information than necessary for anyone with good intentions. To address this issue, passwords are hashed instead. The purpose is not to know the actual password but to confirm, with reasonable certainty, if a user has provided the same password before.&lt;/p&gt;
&lt;p&gt;A salted hash can achieve this goal, ensuring that the stored information is sufficient for verifying user authentication.&lt;/p&gt;
&lt;p&gt;Similarly to how storing plaintext passwords is a mistake, any other information on our databases can also be misused to harm users.&lt;/p&gt;
&lt;p&gt;So if you’re more than just digital mercenaries, solely focused on the next paycheck without giving a shit about the consequences for others, I implore you to adhere to some professional principles. Don’t blindly agree to every request from the marketing team. Instead, ask yourself if you would be comfortable with your own data, in these databases, being breached or falling into the hands of an authoritarian regime or even your marketing team.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">&quot;Why We Can&apos;t Have Nice Software&quot;</title><id>urn:uuid:5d3ca059-848a-47ad-86ae-588b87f3b929</id><updated>2024-02-06T09:23:00+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="technology" label="technology"/><category term="software" label="software"/><category term="recommendations" label="recommendations"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/why-we-cant-have-nice-software-by-andrew-kelley" rel="alternate" hreflang="en" type="text/html"/><published>2024-02-06T09:23:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I recommend a post that goes into the bullshit that big-corps pull on people.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;As a young pup in my early twenties, I once held a naively hopeful perspective on those massive entities we call corporations.
I foolishly believed that &lt;strong&gt;Big-Tech&lt;/strong&gt; companies actually possessed good intentions. Why would anyone with a choice between a morally satisfying choice and mere pittance of extra profit, go for the latter? Why bear such a guilt for slightly higher profit? So what if Google and Microsoft produced buggy or sub-par products? They probably have bad engineers, and slightly unsavory intentions.&lt;/p&gt;
&lt;p&gt;Many years later, and after observing countless fuck-ups by corporations, I no longer feel as optimistic about the amount of fault that lies in their intentions as I see perfectly competent software engineers who work in these companies. The hierarchy of these companies incentivize middle and top-level management to pressure for more and more of these slightly-higher profits. Although the profit may seem proportionally small, it has significant implications for every managerial employee’s career.&lt;/p&gt;
&lt;p&gt;Emphasizing the adverse effects of such forces on consumers, Andrew Kelley published an affectionate essay on his blog, called &lt;a href=&quot;https://andrewkelley.me/post/why-we-cant-have-nice-software.html&quot;&gt;Why We Can’t Have Nice Software&lt;/a&gt;, which I highly recommend reading.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">git-rebase.io</title><id>urn:uuid:a52f8f51-d2ab-44ab-8035-88b173232ac4</id><updated>2024-01-31T13:32:00+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="git" label="git"/><category term="recommendations" label="recommendations"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/git-rebase-io" rel="alternate" hreflang="en" type="text/html"/><published>2024-01-31T13:32:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I recommend a website that teaches you how to use git rebase.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Ever since a while back, I started giving a &lt;strong&gt;damn&lt;/strong&gt; about my Git commits and workflow. Before that, I used &lt;code&gt;git&lt;/code&gt; mostly as a tool to push my code to GitHub.&lt;/p&gt;
&lt;p&gt;However, as soon as I began working with &lt;a href=&quot;https://sr.ht&quot;&gt;Sourcehut&lt;/a&gt; and contributing to the &lt;a href=&quot;https://pimalaya.org&quot;&gt;Pimalaya project&lt;/a&gt;, I found myself caring more and more about each commit and the information contained in them.&lt;/p&gt;
&lt;p&gt;Doing so, however, can be impractical without using &lt;code&gt;git rebase&lt;/code&gt;. &lt;code&gt;git rebase&lt;/code&gt; is an amazing tool for organizing and cleaning up commits, as well as organizing a &lt;strong&gt;patchset&lt;/strong&gt;. However, due to its many functionalities, it can be overwhelming to learn from Stack Overflow or random Google searches or using the &lt;code&gt;--help&lt;/code&gt; flag.&lt;/p&gt;
&lt;p&gt;Drew DeVault created &lt;a href=&quot;https://git-rebase.io&quot;&gt;git-rebase.io&lt;/a&gt;, which is a great tutorial for learning how to use &lt;code&gt;git rebase -i&lt;/code&gt; properly. I strongly suggest trying to run each command and following along with the tutorial, as they can be more concretely learned when you do.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">git-send-mail.io</title><id>urn:uuid:4dbe5c56-fdf8-4058-a77f-cc4456ebb7bc</id><updated>2023-12-29T16:10:00+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="git" label="git"/><category term="recommendations" label="recommendations"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/git-send-mail" rel="alternate" hreflang="en" type="text/html"/><published>2023-12-29T16:10:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Recommending a website to learn how to use emails for collaborating using Git.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Git is an amazing tool, and a massive one at that. Most of us know and agree about that fact. Sure, there are things that use more interesting approaches to the underlying data structure &lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, but for the most part, Git offers a world of wonder that no other system has.&lt;/p&gt;
&lt;p&gt;As it happens, many developers only use a handful of features of Git, which is a shame, since those features fit much better in a workflow that includes more of Git’s features &lt;a id=&quot;fnref2&quot; href=&quot;#fn2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One such feature is &lt;code&gt;git send-email&lt;/code&gt;, which I have been using recently to contribute to the &lt;a href=&quot;https://pimalaya.org&quot;&gt;Pimalaya project&lt;/a&gt; &lt;a id=&quot;fnref3&quot; href=&quot;#fn3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This command lets you send a patch-set &lt;a id=&quot;fnref4&quot; href=&quot;#fn4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt; via email to someone or a mailing list. This is how &lt;a href=&quot;https://lkml.org&quot;&gt;Linux Kernel development&lt;/a&gt; is done and how &lt;a href=&quot;https://sr.ht&quot;&gt;SourceHut&lt;/a&gt; &lt;a id=&quot;fnref5&quot; href=&quot;#fn5&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/a&gt; works.&lt;/p&gt;
&lt;p&gt;However, this workflow is foreign to most developers. &lt;a href=&quot;https://drewdevault.com&quot;&gt;Drew DeVault&lt;/a&gt; &lt;a id=&quot;fnref6&quot; href=&quot;#fn6&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;6&lt;/sup&gt;&lt;/a&gt; created a very nice webpage on &lt;a href=&quot;https://git-send-email.io&quot;&gt;git-send-email&lt;/a&gt;, which guides you through using this rather amazing command.&lt;/p&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;I’m referring to Pijul and Darcs.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;
&lt;p&gt;This, of course, is thanks to the mass adoption of GitHub, which, to be frank, offers a workflow that is probably mostly advantageous to absolute beginners in programming and subpar to full-time developers. Although I can see myself being wrong on this point as well.&lt;a href=&quot;#fnref2&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot;&gt;
&lt;p&gt;Probably one of my upcoming recommendations.&lt;a href=&quot;#fnref3&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot;&gt;
&lt;p&gt;Or &lt;strong&gt;a set of commits&lt;/strong&gt;, if you will.&lt;a href=&quot;#fnref4&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot;&gt;
&lt;p&gt;Another one of my upcoming recommendations.&lt;a href=&quot;#fnref5&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn6&quot;&gt;
&lt;p&gt;Drew co-created SourceHut, which should also connect some dots for you as well.&lt;a href=&quot;#fnref6&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Guilty Pleasures</title><id>urn:uuid:61cbb251-021c-4156-b734-8df30708eb18</id><updated>2023-12-26T20:57:00+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="personal" label="personal"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/guilty-pleasures" rel="alternate" hreflang="en" type="text/html"/><published>2023-12-26T20:57:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Thoughts about my own guilty pleasures.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;For a long time, I have been wondering about my guilty pleasures, trying to figure out which pleasure, in particular, I feel guilty about. I think about other people’s answers, looking for things one does not need much practice to enjoy—‘satisfactions of pigs’, as John Stuart Mill would have put it. He famously wrote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is better to be a human being dissatisfied than a pig satisfied;
better to be Socrates dissatisfied than a fool satisfied.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He argued that the quality of pleasures is much more important than their quantity.
Listening to Bach, even if it brings little joy to someone, would always trump the manic joy of attending a Britney Spears concert.&lt;/p&gt;
&lt;p&gt;However, as it happens, I am not a Millian. I find that argument bogus. I don’t feel any shame about listening to the cheesiest ’80s music and then complimenting that with Mozart’s Requiem.&lt;/p&gt;
&lt;p&gt;Don’t get me wrong. I have a strong sense of guilt. I am a vegan. I help others when I can. And I regularly make life-changing decisions that may not favor my well-being but end up benefiting others. I just have not found many places in my life where guilt and pleasure co-exist.&lt;/p&gt;
&lt;p&gt;I figured that my sense of guilt probably sucks every ounce of pleasure from different activities. That theory seemed shaky, at best.&lt;/p&gt;
&lt;p&gt;Then, just an hour ago, it hit me. I have been looking in the wrong place. My two guilty pleasures? Fine coffee and fine audio equipment. It might sound quite strange to feel guilty about these. But consider this: My ethical stance in life is firmly rooted in &lt;a href=&quot;https://www.utilitarianism.com/hedutil.htm&quot;&gt;Hedonistic Utilitarianism&lt;/a&gt;, which basically means to do whatever it takes to bring the most amount of pleasure and the least amount of suffering to the world. For example, the pleasure I take in eating meat does not surpass the suffering it brings to the animals from which the meat came.&lt;/p&gt;
&lt;p&gt;If I have some amount of money, I should spend it in such a way that it creates the most joy in the world. That surely includes myself, but probably a hungry kid on the street could derive much more pleasure from the same amount of money I am spending on headphones and coffee. For sure, these lavish purchases mostly fall under the mid-range products of a European household. But I live in a third-world country, and even with the salary of a developer, they are still more than most people are willing to pay, here. I am ashamed to admit that I enjoy fine coffees and fine headphones.&lt;/p&gt;
&lt;p&gt;It turns out, I am a proud pig and an ashamed Socrates.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;em&gt;Honk! Honk!&lt;/em&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Fake Nuance</title><id>urn:uuid:5d4dc3aa-b281-4921-b81b-f0f4843c781c</id><updated>2023-12-17T19:10:00+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="opinion" label="opinion"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/fake-nuance" rel="alternate" hreflang="en" type="text/html"/><published>2023-12-17T19:10:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Claiming that you have a nuance that you don&apos;t know about, will never lead to a humbler person.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;On a daily basis, I express an outrageous opinion about technology.&lt;em&gt;“Apple should abandon Swift altogether and use Rust instead of just dancing around this move”&lt;/em&gt; I once declared. To the best of my knowledge, that is a fair opinion. If I am a fool for thinking this way, then I am a fool. If, instead, I state that all languages have a good reason for being there and express that Swift is something amazing just to avoid sounding foolish, I will be a silent fool, but a fool nonetheless.&lt;/p&gt;
&lt;p&gt;At least when my foolishness is expressed, some good Samaritan or an offended opposer might add nuance to my opinions and make me a wiser person than I currently am. In five years, I will be wiser, while the person who chooses to sound wise when they are not will still be a fool.&lt;/p&gt;
&lt;p&gt;Taking the fool-forever-road is so ingrained in our polite and technical manner that we don’t think about it much. A rather obvious example of this is when we respond with “It depends” to any technical question. My friend, if you don’t know how to answer the question of “what it depends on” clearly, you are not being nuanced; you are just a fool like the inquirer of the question, hoping that your intuition comes to your rescue when you are held at gunpoint for a decision.&lt;/p&gt;
&lt;p&gt;Be a fool once in a while; it is much better than being one all the time.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">SOLID is a premature optimization</title><id>urn:uuid:abdfa20c-6f1b-4173-aaf5-5a42d29a05d0</id><updated>2025-05-30T15:23:48+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="programming" label="programming"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/solid-premature-optimization" rel="alternate" hreflang="en" type="text/html"/><published>2023-12-04T11:34:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">The SOLID principles are the actual premature optimizations.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Honestly, the primary challenge I encountered with complex codebases originated from adhering to &lt;abbr title=&quot;Single-responsibility, Open–closed, Liskov substitution, Interface segregation, Dependency inversion&quot; tabindex=&quot;0&quot;&gt;SOLID&lt;/abbr&gt; principles. Surprisingly, they appeared to turn the straightforward task of making any changes into a Herculean feat. Introducing numerous cumbersome abstractions also took a toll on performance.&lt;/p&gt;
&lt;p&gt;Talk about actual premature optimizations!&lt;/p&gt;
&lt;p&gt;I much prefer something like &lt;abbr title=&quot;Composable, Unix Philosophy, Predictable, Idiomatic, Domain-based&quot; tabindex=&quot;0&quot;&gt;CUPID&lt;/abbr&gt; principles. &lt;a href=&quot;https://cupid.dev/&quot;&gt;More information on &lt;abbr title=&quot;Composable, Unix Philosophy, Predictable, Idiomatic, Domain-based&quot; tabindex=&quot;0&quot;&gt;CUPID&lt;/abbr&gt;&lt;/a&gt;&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Git For Persistence Layer</title><id>urn:uuid:7abffb39-4bc5-4326-b690-a8dbe05c5490</id><updated>2025-05-30T16:00:01+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="git" label="git"/><category term="backend" label="backend"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/git-for-persistence-layer" rel="alternate" hreflang="en" type="text/html"/><published>2023-12-04T09:18:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">git as a persistence layer, what could go wrong?</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I’m entertaining with the idea of making a personal web-server that uses git instead of a database. Yet I don’t have any idea how well such a thing would work. More importantly, I’m not sure about the &lt;abbr title=&quot;Application Programming Interface&quot; tabindex=&quot;0&quot;&gt;API&lt;/abbr&gt;. Perhaps instead of using the standard &lt;abbr title=&quot;Representational State Transfer&quot; tabindex=&quot;0&quot;&gt;REST&lt;/abbr&gt;, I could use Telegram or Matrix instead of creating a whole frontend.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Holidays For Rustaceans</title><id>urn:uuid:ea8da43d-a5d5-4cf5-8e02-6111ac5a235d</id><updated>2023-12-04T09:11:00+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="programming" label="programming"/><category term="rust" label="rust"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/holidays-for-rustaceans" rel="alternate" hreflang="en" type="text/html"/><published>2023-12-04T09:11:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">For Rust developers, the passion stems from a combination of 10% performance, safety, and tooling. The remaining 90% is the bliss of holidays free from on-call disruptions.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;For Rust developers, the passion stems from a combination of 10% performance, safety, and tooling. The remaining 90% is the bliss of holidays free from on-call disruptions.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Popularization of The Wrong Thing</title><id>urn:uuid:f5a917cf-6f67-4d2d-b78d-9e8a7cfce2e3</id><updated>2025-05-30T15:53:41+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="popularization" label="popularization"/><category term="music" label="music"/><category term="lo-fi" label="lo-fi"/><category term="art" label="art"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/popularization-of-the-wrong-thing" rel="alternate" hreflang="en" type="text/html"/><published>2023-11-05T15:41:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I whine about things becoming popular that shouldn&apos;t have.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;There are people who proudly declare:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I used to like X, but then it became popular, so I don’t like it anymore.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I fucking hate these people. What a bunch of douche-bags. Do you consider yourself superior to others?&lt;/p&gt;
&lt;p&gt;However, there are circumstances where I believe that this perspective is valid and can be seen as a positive stance to take.&lt;/p&gt;
&lt;section id=&quot;The-Adventurer&quot;&gt;
&lt;h2&gt;The Adventurer&lt;/h2&gt;
&lt;p&gt;There is a group of people who enjoy uncovering unknown valleys, experiencing them, and staying committed until they reach a more popular stage. They relish the thrill of discovery and take pleasure in popularizing things.&lt;/p&gt;
&lt;p&gt;One such group is composed of individuals who embrace emerging programming languages, with Zig and Nim serving as good examples. Some of them thrive in the startup scene, where they are comfortable taking risks and making decisions that have a tangible impact. However, in a more stable environment, when things become mainstream, their services are no longer required. Their advocacy and contributions are graciously acknowledged, and they happily move on to the next cutting-edge endeavor—a clean break.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;The-Adventurer’s-Friend&quot;&gt;
&lt;h2&gt;The Adventurer’s Friend&lt;/h2&gt;
&lt;p&gt;Similar to the first group, there are individuals who relish spending time in less mainstream communities. It’s true that you can always find individuals with egotistical tendencies in these non-mainstream groups, as they seek to exert authority over others. However, there are also truly brilliant people who are dedicated to their craft, and they are both driven by their passion and drive the development of their crafts. You might encounter them later on as they become giants in their fields, but at that point they may become too preoccupied to engage with people they don’t already know.&lt;/p&gt;
&lt;p&gt;These communities are incredibly dynamic and enjoyable. Your actions can influence the trajectory of the entire community’s existence.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;The-Misunderstood&quot;&gt;
&lt;h2&gt;The Misunderstood&lt;/h2&gt;
&lt;p&gt;The reason for this post is that I’ve recently found myself in this group.&lt;/p&gt;
&lt;p&gt;If you delve into any modern art history book, you’ll encounter fascinating descriptions of abstract art. Its intended message is simple, in contrast to figurative art, which aims to depict tangible subjects. Abstract art seeks to convey emotions without adhering to reality, much like instrumental music. The history of abstract art is marked by experimentation and truly impressive works, both technically and emotionally.&lt;/p&gt;
&lt;p&gt;However, if you search for abstract art on most art trading websites or social media, what you’ll discover is a type of decorative art. It experiments with various elements but often lacks novelty. Nevertheless, it can add exceptional charm to your hallway’s wall. This is a valid art form that enriches the world. However, for those seeking experimental abstract art that conveys emotions like hatred or sorrow, it’s increasingly challenging to find it because the more popular usage of the term ‘abstract art’ leans toward the decorative.&lt;/p&gt;
&lt;p&gt;However, what recently placed me in this group was not the above. Instead, it was a few years ago when I fell in love with a genre of music called &lt;abbr title=&quot;Low-Fidelity&quot; tabindex=&quot;0&quot;&gt;Lo-Fi&lt;/abbr&gt;. &lt;abbr title=&quot;Low-Fidelity&quot; tabindex=&quot;0&quot;&gt;Lo-Fi&lt;/abbr&gt; music is a genre with a nostalgic approach to music, incorporating background noises from phonographs, sound clips from old movies, and yet embracing contemporary techniques. Apps like Loffee perfectly capture this kind of music for me.&lt;/p&gt;
&lt;p&gt;Unfortunately, over the past couple of years, &lt;abbr title=&quot;Low-Fidelity&quot; tabindex=&quot;0&quot;&gt;Lo-Fi&lt;/abbr&gt; has been used interchangeably with chill-hop ambient music. Most people use it as background music during their focus sessions, and you might hear it in coffee shops and YouTube videos. The famous Lofi Girl YouTube channel also features music that I can only describe as ambient chill-hop. If you search for &lt;abbr title=&quot;Low-Fidelity&quot; tabindex=&quot;0&quot;&gt;Lo-Fi&lt;/abbr&gt; music, you’ll predominantly find that genre, which saddens me because I spend hours searching for music in my favorite genre, only to encounter ambient music.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Readers&quot;&gt;
&lt;h2&gt;Dear Readers&lt;/h2&gt;
&lt;p&gt;The reason for my post is to ask if you are aware of any good sources for the &lt;abbr title=&quot;Low-Fidelity&quot; tabindex=&quot;0&quot;&gt;Lo-Fi&lt;/abbr&gt; music I’m searching for. If you do, please reach out to me.&lt;/p&gt;
&lt;p&gt;If, by chance, I discover a reliable source, I will update this post below this line.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Diversity Quotas</title><id>urn:uuid:66b63edd-31d9-4753-a8e1-16ab7ab9e67f</id><updated>2023-11-04T12:31:33+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="diversity" label="diversity"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/diversity-quotas" rel="alternate" hreflang="en" type="text/html"/><published>2023-11-04T12:31:33+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Diversity Quotas are not radical!</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Honestly, I cannot say that diversity quotas are &lt;strong&gt;radical&lt;/strong&gt; feminism; or in any terms extreme. Especially since they are implemented in societies that have endured thousands of years of cultural, institutional, and governmental oppression of women and minorities, which, we have yet to witness significant progress in achieving true equality for these oppressed groups.&lt;/p&gt;
&lt;p&gt;Equal opportunity does not entail placing the food on top of the trees and then asserting that the whale just didn’t take it while the chimp did.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Python And NixOS</title><id>urn:uuid:64acaa05-4296-454f-8290-151099a2e015</id><updated>2023-11-02T08:33:00+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="python" label="python"/><category term="nix" label="nix"/><category term="programming" label="programming"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/python-and-nixos" rel="alternate" hreflang="en" type="text/html"/><published>2023-11-02T08:33:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Python sucks and it&apos;s showing in NixOS ecosystem.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;The problems surrounding Python programs on NixOS seem never-ending. I often have to refrain from installing most Python programs. On each update, another one of them breaks during installation – either their tests don’t pass, or their dependencies fail in some way.&lt;/p&gt;
&lt;p&gt;And to be honest, I give the benefit of the doubt to NixOS, seeing its result with other languages, and knowing what I know about pip.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Test of 10x Developer</title><id>urn:uuid:4bc9ba85-8ed4-490d-b959-7e5e08e34234</id><updated>2023-10-16T21:40:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="development" label="development"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/test-of-10x-developers" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T21:40:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">nagging about 10x developers.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;The true test of 10x developer is that you put two of them together, each debugging each-others code, then you if they kept their 10x status, they are the true 10x developer. My guess would be that their population will reduce to less than that of unicorns’.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Usage Restriction of Software Licenses</title><id>urn:uuid:65f3f218-d225-45c6-b6e0-c081e871b69f</id><updated>2023-10-16T21:35:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="open-source" label="open-source"/><category term="licenses" label="licenses"/><category term="software" label="software"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/usage-restriction-software-licences" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T21:35:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Nagging about usage restriction in the software licenses</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Please think twice before saying, “usage restriction is good because you might want to prevent someone from using your tool for war, crime, etc.”&lt;/p&gt;
&lt;p&gt;Like, you know that a poorly enforced license won’t deter a person in that situation from using your software, right?&lt;/p&gt;
&lt;p&gt;There are probably better arguments for including usage restrictions in a software license; this one is a terrible one.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Rust Skills Transferability</title><id>urn:uuid:e8dbf1ef-aca5-4720-b56c-8500cc82e31e</id><updated>2023-10-16T21:34:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="languages" label="languages"/><category term="rust" label="rust"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/rust-skills-transferability" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T21:34:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I talk about transferability of the skills one learn from Rust.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;While the skills learned in Rust, like working with the &lt;strong&gt;borrow checker&lt;/strong&gt;, may seem limited to Rust itself, the claim of their intransferability is somewhat overstated.&lt;/p&gt;
&lt;p&gt;Understanding the borrow checker is specific to languages using it, but the approaches it encourages are typically advanced and valued by experienced engineers. And often, it is evidenced by the patterns that are simplest to implement.&lt;/p&gt;
&lt;p&gt;The obvious exception to that is &lt;code&gt;unwrap()&lt;/code&gt; and &lt;code&gt;expect()&lt;/code&gt;. Even though the &lt;code&gt;?&lt;/code&gt; operator is a step towards simplifying that process, it is undeniable that the hassle of creating and managing errors is not simpler than the extra 8 characters introduced by the &lt;code&gt;.unwrap()&lt;/code&gt;.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Rust&apos;s Productivity</title><id>urn:uuid:73b2255b-5ab8-4624-9e6c-58b6d72d1afa</id><updated>2023-10-16T21:34:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="programming" label="programming"/><category term="rust" label="rust"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/rust-productivity" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T21:34:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">talking about rust productivity.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I think the best way to characterize Rust’s productivity, is to put it on a quality axis.&lt;/p&gt;
&lt;p&gt;If you want low quality code (prototyping, etc.) Rust is much less productive than the alternative.&lt;/p&gt;
&lt;p&gt;For medium level of quality, Rust is similar to others.&lt;/p&gt;
&lt;p&gt;For high quality code, Rust is much more productive than any alternatives.&lt;/p&gt;
&lt;p&gt;Quality is intentionally vague, to encapsulate performance, leanness, documentation, and security.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Prototyping in Software development</title><id>urn:uuid:be24baee-2e52-48fb-9e6f-21639ee18a52</id><updated>2023-10-16T21:34:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="software-development" label="software-development"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/prototyping-software-development" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T21:34:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">What should a prototype software have?</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I think when you are proposing a fast prototyping phase in programming, you should be able to answer these questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
What don’t we know that we hope to find out with this prototype?
&lt;/li&gt;
&lt;li&gt;
Why is this the best approach for finding the answer to that question.
&lt;/li&gt;
&lt;li&gt;
When is the prototype going to be deleted?
If you cannot answer to these questions, what you are proposing is not a prototype, it is prototype quality end product. A knock off, if you will. A bad practice distilled.
&lt;/li&gt;
&lt;/ol&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">O&apos;Reilly Book Covers</title><id>urn:uuid:60f7a728-1e05-4797-bd8e-9a5393219917</id><updated>2023-10-16T21:34:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="books" label="books"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/oreilly-book-covers" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T21:34:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Just babbeling around about O&apos;Reilly Book Covers.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;There is a retired burned out offended wild life photographer out there responsible for the O’Reilly’s book covers, after they were told “You’re a photographer, that’s the same thing as graphic designer, give us 500 book covers, here is $1.”&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Older, Better Technologies</title><id>urn:uuid:70ad36ff-91ce-4676-bc35-042986ab438c</id><updated>2023-10-16T21:34:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="enshittification" label="enshittification"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/older-better-technologies" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T21:34:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Some older stuff were replaced by newer inferior ones.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;It is very illuminating to see that using older style technologies, may lead to better experience. This just goes to show that many of the features and complexity and progress are not &lt;strong&gt;for people&lt;/strong&gt;, but for profit of a few. That, of course, is a wild speculation of the highest order.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Centralization Around GitHub</title><id>urn:uuid:716e0c29-952c-41d1-9408-c169c90a7060</id><updated>2023-10-16T21:34:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="enshitification" label="enshitification"/><category term="codeberg" label="codeberg"/><category term="github" label="github"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/github-centralization" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T21:34:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I&apos;m just worried about GitHub being so centeralized.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I find the situation around GitHub centralization distressing. And this extreme reliance on GitHub is worrying.
Maybe in time things change. But the moment I find a job and thus don’t need to keep my repos on GitHub anymore, I would like to move to a more federated forge.&lt;/p&gt;
&lt;p&gt;Codeberg seems like the closest option. I will just simply mirror my commits to GitHub for the time being, slowly retiring them when I’m sure that Codeberg remotes have the necessary configurations and flows that are needed. I don’t think I can retire my account though.&lt;/p&gt;
&lt;p&gt;Every place I worked or want to work, are using GitHub. I cannot but worry about the same amount of enshitification that twitter and Reddit has taken, to also come for GitHub.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Dynamic Linking is the Wrong solution</title><id>urn:uuid:f9a26605-61e7-4384-8e38-cddc5ad3554c</id><updated>2023-10-16T21:33:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="dynamic-linking" label="dynamic-linking"/><category term="software" label="software"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/dynamic-linking-the-wrong-solution" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T21:33:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I argue against dynamic linking!</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Dynamic linking for the reason of security is the wrong solution, only propagating the problem of language and application developers to the downstream package distributors.&lt;/p&gt;
&lt;p&gt;It is basically saying, yeah, I wrote this package with this language and dependencies, but you will be the one paying for my choice of technology.&lt;/p&gt;
&lt;p&gt;Of course, down stream people also shouldn’t have accommodated these software.
Except they did and now, there are multitudes of ecosystems operating this way.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">I Hate Jira</title><id>urn:uuid:45921e8c-6cbe-4337-9e03-a09fc0b6558b</id><updated>2025-05-30T15:25:14+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="jira" label="jira"/><category term="software-development" label="software-development"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/i-hate-jira" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T21:30:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I deeply hate Jira.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I absolutely hate &lt;strong&gt;&lt;strong&gt;Jira&lt;/strong&gt;&lt;/strong&gt;. It is when you spend hours of valuable time, prioritizing tasks that take less time doing than setting them on Jira.&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">ADHD not Being Real</title><id>urn:uuid:7936c40f-4f06-4a85-9a43-6c37d22698b6</id><updated>2025-05-30T15:38:30+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="adhd" label="adhd"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/adhd-not-real" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T18:09:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Idiotic things that people say about ADHD.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;abbr title=&quot;Attention-Deficit / Hyperactivity Disorder&quot; tabindex=&quot;0&quot;&gt;ADHD&lt;/abbr&gt; is not real. It is just unmotivated kids needing more structure.&lt;/p&gt;
&lt;p&gt;– Some lady today&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Therefore:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cancer is not real.
It is just overly horny cells needing to chill the fuck down.&lt;/p&gt;
&lt;p&gt;– Probably the same lady, assuming no double standards&lt;/p&gt;
&lt;/blockquote&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Missing Rust Blogpost</title><id>urn:uuid:4fe9aa18-00e9-4e1b-ae4c-1cae88a49925</id><updated>2023-10-16T17:27:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="rust" label="rust"/><category term="dailies" label="dailies"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/missing-rust-post" rel="alternate" hreflang="en" type="text/html"/><published>2023-10-16T17:27:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I&apos;m being critical of performance obsession in Rust ecosystem.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;There is a blog post missing in the Rust sphere: &lt;strong&gt;How to not obsess over performance gain and improve changeability of Rust applications.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In other words, imagine that you want to move a function used in one file to another. How would you do that in under ten minutes?&lt;/p&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">The Tragedy of The Tech-Stacks</title><id>urn:uuid:de915eb1-1e02-48c3-917d-75489a21c9bd</id><updated>2025-05-30T15:34:42+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="programming" label="programming"/><category term="software" label="software"/><category term="opinion" label="opinion"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/tragedy-of-the-tech-stacks" rel="alternate" hreflang="en" type="text/html"/><published>2023-08-11T11:08:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">There is a broken chain, keeping people on a broken tech-stack.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Back in 1958, there was this thinker named Garrett Hardin who kicked off his well-known piece titled “The Tragedy of the Commons” in the following way:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;At the end of a thoughtful article on the future of nuclear war, Weisner and York concluded that “Both sides of the arms race are… confronted by the dilemma of steadily increasing military power and steadily decreasing national security. It is our considered our professional judgment that this dilemma has not professional technical solution. If the great powers continue to look for solutions in the area of science and technology only, the result will be to worsen the situation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then, Hardin goes on to rattle the foundations by delving into a colossal issue — the challenge of population expansion. He breaks it down by saying that when you have a shared resource, and each individual aims to squeeze out the most benefit for themselves, the result is a harm inflicted upon everyone, even the very ones taking those actions.&lt;/p&gt;
&lt;p&gt;Now, picture this famous analogy. Imagine a stretch of grassland, claimed by three farmers. Each of them brings their cow out to graze on it daily. Sounds reasonable, right? But then, one fortunate farmer’s cow becomes pregnant. This stroke of luck leaves him with two cows, effectively doubling his profits. Observing this triumph, the other farmers follow suit, diving into a spree of buying and breeding cows, aiming to maximize their individual gains. However, this frenzy leads to a rampant grazing that leaves the grassland bare and barren. Ultimately, the once lush grass disappears, and the insatiable appetite of the voracious cows brings about their own starvation. In the end, all the farmers are left with no cows, their initial wealth transformed into a state even worse than before.&lt;/p&gt;
&lt;p&gt;He coins it as the “Tragedy Of The Commons.” I prefer to see it as a powerful representation of what often dampens the enjoyment across the software terrain for every key player involved: the user, the developer, the &lt;abbr title=&quot;Chief Executive Officer&quot; tabindex=&quot;0&quot;&gt;CEO&lt;/abbr&gt;, and the investor.&lt;/p&gt;
&lt;p&gt;How meta!&lt;/p&gt;
&lt;section id=&quot;The-Clever-One-The-Frustrated-One-and-The-Scared-One&quot;&gt;
&lt;h2&gt;The Clever One, The Frustrated One and The Scared One&lt;/h2&gt;
&lt;p&gt;Now, let’s meet a familiar figure, the one we often encounter, the embodiment of many developers out there. We’ll give her a name: Sarah. Sarah’s eager to dive into a fresh technology - one that could potentially elevate her current position. So, how does she tackle this? She begins by exploring a domain, and within that, she sets her sights on a specific technology. Let’s designate this domain as something imaginary, to prevent any inadvertent offense. How about we refer to it as “Front-End Development”?&lt;/p&gt;
&lt;p&gt;For Front-End Sarah finds out a few different contenders in the field. She asks herself what could the industry be thirsty for? The naive answer she arrives at, is “the most reliable one, the one that is the pleasure to develop and the one that has the most advantages”. Oh, Sarah, you impractical idealistic perfectionist, you!&lt;/p&gt;
&lt;p&gt;Now, delving into the realm of Front-End, Sarah stumbles upon a handful of potential contenders. She ponders, what might the industry truly crave? Her initial, somewhat naive response is, “The most dependable option, the one that brings joy to the development process, and the one that boasts numerous advantages.” Oh Sarah, you, impractical, idealistic, perfectionist you!&lt;/p&gt;
&lt;p&gt;Armed with these benchmarks, she opts for the Elm language (yet another mythical being). She proceeds to dive into Elm, driven by her enthusiasm. However, curiosity gets the better of her, and she sneakily glances at the job listings on LinkedIn. To her astonishment, she discovers a mere trio of job opportunities for Elm. This baffles her, leading her to question the accuracy of her initial language assessment.&lt;/p&gt;
&lt;p&gt;Seeking insight, she turns to Tom, an exceptional &lt;abbr title=&quot;Chief Technology Officer&quot; tabindex=&quot;0&quot;&gt;CTO&lt;/abbr&gt; she’s acquainted with, to discuss whether Elm lives up to its hype. Much to Sarah’s astonishment, Tom echoes her initial convictions regarding Elm. He affirms that, indeed, Elm proves to be an exceptional language, boasting enduring dependability, a well-established ecosystem, and a delightful development journey.&lt;/p&gt;
&lt;p&gt;Sarah, now even more puzzled than before, directs her confusion towards Tom, questioning whether he’s in the process of recruiting Elm developers. Once again, Tom’s response is resolute: “Absolutely not! Where could I possibly locate a pool of Elm-savvy developers? However, we’re actively seeking out JavaScript experts!” (once more, a language name sufficiently distanced from any existing real-world instances).&lt;/p&gt;
&lt;p&gt;After a brief moment of contemplation, Sarah bursts out, “What about me?”.&lt;/p&gt;
&lt;p&gt;Tom responds with a shake of his head, stating, “Oh, that wouldn’t work. You see, for any given application, we require a team of 20 individuals to consistently handle maintenance and bug fixes. Where on earth would we come across 20 Elm developers?”&lt;/p&gt;
&lt;p&gt;“Well, shouldn’t Elm apps theoretically require significantly less maintenance, given the multitude of bugs that are caught during the initial development stages?” Sarah counters silently within her mind. An idea begins to form, one she opts to keep to herself, “Ah, so maintaining a delicate codebase might indicate a higher demand for fresh JavaScript developers - implying enhanced job security!”&lt;/p&gt;
&lt;p&gt;Feeling rather clever, she decides to validate her hunch by perusing the (imaginary) yellow pages, named Glassdoor. And lo and behold, an endless scroll unveils a plethora of distinct job listings, all centered around JavaScript.&lt;/p&gt;
&lt;p&gt;Well, Sarah learns JavaScript and all her beliefs gets validated, she becomes a very wealthy engineer, with a great job security, with each company she enters trying to keep her, year-after-yer, while other companies trying to persuade her by higher and higher offers. Or at least that was the boring version of this post that did not start with the word “tragedy”.&lt;/p&gt;
&lt;p&gt;Instead, she uncovers that her counterparts, much like herself, had also been quite &lt;strong&gt;clever&lt;/strong&gt;. A multitude of newcomers gravitated towards the language flaunting the highest job listings. Each job opening faced a surplus of around a hundred contenders. The “victor,” so to speak, emerges as the individual boasting the most qualifications and the most modest salary expectation. Or should we even label them as victors, considering that the instant they dare to dream a little bigger, a fresh job listing crops up, promptly displacing them with the next eager contender.&lt;/p&gt;
&lt;p&gt;Tom, our trusty &lt;abbr title=&quot;Chief Technology Officer&quot; tabindex=&quot;0&quot;&gt;CTO&lt;/abbr&gt;, worn out from the cycle of on-boarding one low-budget, novice developer after another, vents his frustrations to the &lt;abbr title=&quot;Chief Executive Officer&quot; tabindex=&quot;0&quot;&gt;CEO&lt;/abbr&gt;. The &lt;abbr title=&quot;Chief Executive Officer&quot; tabindex=&quot;0&quot;&gt;CEO&lt;/abbr&gt; engages in discussions with the investors, who share the same dissatisfaction due to their profits being eroded by an inefficient workforce. They call upon the &lt;abbr title=&quot;Chief Executive Officer&quot; tabindex=&quot;0&quot;&gt;CEO&lt;/abbr&gt; to devise a remedy for this predicament.&lt;/p&gt;
&lt;p&gt;The &lt;abbr title=&quot;Chief Executive Officer&quot; tabindex=&quot;0&quot;&gt;CEO&lt;/abbr&gt; returns with a strategy to shift from JavsScript to Elm technology. The investors, content with the proposal, take a brief pause to deliberate. A few days later, they rejoin the conversation, expressing a notable apprehension. “Elm is practically unheard of! None of our rivals employ this language. That’s a substantial gamble we’re not prepared to take!”&lt;/p&gt;
&lt;p&gt;Arash, the &lt;abbr title=&quot;Chief Executive Officer&quot; tabindex=&quot;0&quot;&gt;CEO&lt;/abbr&gt;, &lt;abbr title=&quot;Chief Technology Officer&quot; tabindex=&quot;0&quot;&gt;CTO&lt;/abbr&gt;, &lt;abbr title=&quot;Chief Financial Officer&quot; tabindex=&quot;0&quot;&gt;CFO&lt;/abbr&gt;, Product Manager, and the visionary founder of a fledgling startup, confronts the very same imaginative quandary of selecting a technology stack. Given the inherent high-stakes nature of startups, Arash adopts a prudent approach by examining the practices of more established corporations, such as those overseen by individuals like Tom in his role as &lt;abbr title=&quot;Chief Technology Officer&quot; tabindex=&quot;0&quot;&gt;CTO&lt;/abbr&gt;, in order to identify a tried-and-true trajectory.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;The-Lose-Lose-Lose-situation&quot;&gt;
&lt;h2&gt;The Lose-Lose-Lose situation&lt;/h2&gt;
&lt;p&gt;At every juncture, every individual optimized their decisions for personal gain. At each instance, a superior option was presented, and they acknowledged the benefits it offered. Nevertheless, they settled for the inferior alternative (for the sake of avoiding any unnecessary debate, let’s refrain from mentioning that the hypothetical lesser choice was JavaScript, naturally). As a result, each person finds themselves in a less advantageous position than if they had collectively embraced the superior alternative. This impact ripples beyond individuals, extending to the entire ecosystem, hindered by the precarious edifice of abstractions left behind by the swiftly growing number of predecessors.&lt;/p&gt;
&lt;p&gt;So, why did they all fall short of enhancing their own lives and the lives of others? Was it the technology’s flaw? Or did the ecosystem falter? You’re astute enough to deduce the answer; after all, you had the wit to discern the languages I implicitly referred to in my hypothetical scenarios.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;The-Solution&quot;&gt;
&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;I must admit, I’m uncertain. The nuclear arsenal continues to expand, even though the era of the Cold War has long passed. Thankfully, our world hasn’t been ravaged by nuclear conflict. Rather, it’s the interplay of mutually assured destruction and the realization by the leaders of those two nations that not embracing an alternative risk could lead to dire consequences. This, at least, has placed us in a relatively improved state.&lt;/p&gt;
&lt;p&gt;Simultaneously, we find ourselves grappling with Garrett Hardin’s preoccupation — the persistent challenges of overpopulation and looming environmental catastrophes. Evidently, the far-reaching peril of not embracing an alternative is of such extended duration that it transcends the immediate concerns of the very generation opting against alternatives. The burden of their choices is instead borne by their descendants:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fuck those brats.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the world of software, the tempo is notably faster, the stakes less dire compared to earlier circumstances, and the individuals engaged are often more honest than politicians and notably smarter than the average voter.&lt;/p&gt;
&lt;p&gt;However, the remedy doesn’t entail adhering to an oddly precise series
of ritualistic maneuvers. It’s a more daunting challenge. Just as
Garrett Hardin titled his article, the solution remains much the same:&lt;/p&gt;
&lt;blockquote source=&quot;Garrett Hardin&quot;&gt;
&lt;p&gt;The population problem has no technical solution; it requires a fundamental extension of in morality. 
— Garrett Hardin&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Reader&quot;&gt;
&lt;h2&gt;Dear Reader&lt;/h2&gt;
&lt;p&gt;I know! The ghastly claim of “to improve developer experience we first should grow an ethical sense”, seems absurd. Yet I see no specifically little amount of gradual change, where at least someone on the whole chain did not bite the bullet and risk it.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Call Me Perma</title><id>urn:uuid:9aaf223c-d6a7-418a-8745-22b26850be31</id><updated>2025-05-30T15:37:03+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="names" label="names"/><category term="perma" label="perma"/><category term="update" label="update"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/call-me-perma" rel="alternate" hreflang="en" type="text/html"/><published>2023-08-09T11:01:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I have changed my name.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;I find myself seated in the passenger’s seat of my mother’s car, as we make our way to an appointment with an educational psychologist. A sense of confusion and concern lingers within me, stemming from my mother’s sudden and puzzling reaction to my C-graded report card. The journey passes quietly, and we arrive at the specialist’s office without exchanging a word, leaving me still uncertain about the purpose of our visit.&lt;/p&gt;
&lt;p&gt;The psychologist initiates our session by administering a series of aptitude and intelligence tests appropriate for my age. Throughout the process, my mother’s keen gaze remains fixed on me, intensifying my nerves. Eventually, the psychologist validates my mother’s suspicions, revealing that my intellectual capabilities far exceed those of my peers. This revelation prompts my mother to shed light on the purpose of our enigmatic expedition:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You see, you are not stupid, you are actually very smart, you just lack self-esteem!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Was that truly the root of the issue? While self-esteem was a factor in my unhappiness, I couldn’t help but feel that my lack of effort had deeper origins.&lt;/p&gt;
&lt;p&gt;Oh, but this wasn’t the first round of this comical saga. You see, on previous occasions, my dear mother would strategically place a glass of water right between us, like a cosmic prop. And what was the grand purpose behind this visual spectacle, you might ask? Well, it was her way of nudging me into a philosophical monologue about that very glass. In simple terms:
&amp;gt; Hey, kiddo, you’ve got a shortage of optimism; you’re the sort who tends to spot the half-empty glass in life.&lt;/p&gt;
&lt;p&gt;And then we have my dear old dad, the master of responsibility training. He had this grand plan to shape my character, using internships as his secret weapon.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Off you go, my young apprentice!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He’d exclaim, nudging me into one vocational adventure after another. His hidden message?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Kid, I’m passing down the sacred skill of handling responsibilities!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The age-old parental strategy.&lt;/p&gt;
&lt;p&gt;And there you have it, my childhood summed up, right from the time those kindergarten teachers began their chorus of complaints about my apparent “refusal” to embrace the songs that my peers had effortlessly committed to memory months before.&lt;/p&gt;
&lt;p&gt;As the days went by, I began to adopt a personal mantra:
&amp;gt; I’m the poster child for laziness, the embodiment of irresponsibility, with motivation and vision nowhere to be found.&lt;/p&gt;
&lt;p&gt;Oddly enough, despite knowing full well the significance of education and being genuinely captivated by the realms of science and math, my actions seemed to tell a different story altogether. It’s as if I was presenting evidence that contradicted my own beliefs. Perhaps deep down, I questioned my care for my parents, struggled to find motivation, or maybe I secretly aspired to master the art of freeloadery.&lt;/p&gt;
&lt;p&gt;The haze of doubt began to lift when I embarked on an &lt;abbr title=&quot;Attention-Deficit / Hyperactivity Disorder&quot; tabindex=&quot;0&quot;&gt;ADHD&lt;/abbr&gt; medication journey, and lo and behold, I experienced the novel sensation of being able to sit down and read a paragraph without my mind spiraling into chaos. It was like finally playing a video game where you no longer wonder if you’re in control of that character’s movements or not. My epiphany was quite the reverse: “Oh, wait a minute, I can indeed make decisions and stick with them?”&lt;/p&gt;
&lt;p&gt;Let me tell you, this realization was liberating, to put it mildly. Suddenly, I had the capacity to invest time in the very things that had ignited my curiosity.&lt;/p&gt;
&lt;p&gt;&lt;abbr title=&quot;Attention-Deficit / Hyperactivity Disorder&quot; tabindex=&quot;0&quot;&gt;ADHD&lt;/abbr&gt; has had a profound impact on my life since childhood. One revelation that became clear after seeking medication was the extent to which I had surrendered agency and intentionality.&lt;/p&gt;
&lt;p&gt;My existence had been defined by reactivity, with a noticeable absence of honed decision-making skills. I found myself in a state of passivity, or even worse, mere reactivity. Nonetheless, I consistently strive to reclaim it.&lt;/p&gt;
&lt;section id=&quot;Recent-Victories&quot;&gt;
&lt;h2&gt;Recent Victories&lt;/h2&gt;
&lt;p&gt;Over the past few years, I’ve encountered an almost comically disproportionate share of misfortune and have found myself under substantial duress. Yet, I’ve navigated my way through these challenges.&lt;/p&gt;
&lt;p&gt;I won’t delve into the specifics of these misfortunes, although those in my social circles can attest to their unusual frequency.&lt;/p&gt;
&lt;p&gt;However, I can share that I’ve achieved several noteworthy milestones during this time span: acquiring programming skills, entering the workforce, entering marriage, and most recently, opting to unofficially change my name.&lt;/p&gt;
&lt;p&gt;Formally, I remain &lt;strong&gt;Amirhossein&lt;/strong&gt;, and I’m content should anyone choose to continue addressing me as such-I hold no animosity toward it. Nevertheless, it inadequately captures the depth of my identity.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Amirhossein-and-Perma&quot;&gt;
&lt;h2&gt;Amirhossein and Perma&lt;/h2&gt;
&lt;p&gt;The name Amirhossein is a composite of two Arabic names, Amir and Hossein, both of which carry two meanings. As for the firsts of these meanings, Amir translates to “prince,” while Hossein signifies “Good-junior.” The amalgamation results in the interpretation of “Junior Good Prince.”&lt;/p&gt;
&lt;p&gt;However, I find myself at a loss when attempting to establish a personal connection with any aspect of this interpretation of this name. This brings us to its secondary and perhaps more intended connotation.&lt;/p&gt;
&lt;p&gt;In Shia Islam, there exists a concept akin to Christianity’s sainthood, known as “Imam”. However, these Imams are asserted to be leaders of the Islamic community. The first of these figures holds the title &lt;strong&gt;Amir-al-momenin&lt;/strong&gt;, or the “prince of the faithful”, commonly abbreviated as Amir. The third Imam, the second son of the first, was named &lt;strong&gt;Hossein&lt;/strong&gt; . Both individuals deviate significantly from pacifism.&lt;/p&gt;
&lt;p&gt;While these historical and linguistic connections hold merit, I must underscore a significant twist: since the age of 15, I have consciously disavowed Islam and theism in their entirety.&lt;/p&gt;
&lt;p&gt;I find “&lt;a href=&quot;/about/&quot;&gt;Perma&lt;/a&gt;” to be a more fitting option, resonating more harmoniously with my ears. Moreover, it aligns with certain themes and passions that hold significance in my life. It closely aligns with the ethos underpinning this blog. I’m captivated by the philosophy of the &lt;strong&gt;PermaCulture&lt;/strong&gt; and &lt;strong&gt;PermaComputing&lt;/strong&gt; movements-albeit not necessarily their current implementations. My fascination lies in harmonizing with the world rather than coercing it to conform to my presence. Moreover, the notion of leaving a lasting imprint on the world holds a special allure for me. However, this yearning leans more toward the aesthetic realm rather than being rooted in &lt;strong&gt;utilitarian&lt;/strong&gt; aspirations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Reader&quot;&gt;
&lt;h2&gt;Dear Reader&lt;/h2&gt;
&lt;p&gt;If you’ve known me previously, you might have observed my recent shifts in usernames, emails, and name. Across the internet, I’ve opted for &lt;code&gt;Prma&lt;/code&gt; instead of the more direct &lt;code&gt;Perma&lt;/code&gt;, as the latter is frequently claimed or could serve other entities more fittingly.&lt;/p&gt;
&lt;p&gt;However, this change isn’t indicative of a complete unveiling of my authentic self. Thus, referring to me by my previous name isn’t as insensitive as the act of dead-naming. Rather, this transition signifies the inception of a renewed chapter, one marked by heightened purpose and intention.&lt;/p&gt;
&lt;p&gt;While I do prefer and hope for the usage of &lt;strong&gt;Perma&lt;/strong&gt; moving forward, I’m entirely at ease if you choose otherwise. Your decision in this regard is genuinely respected.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Dishonesty of Optimizing for Developer Time</title><id>urn:uuid:5dec2b05-0a04-494d-8eff-ec8a14f6f22f</id><updated>2025-05-30T15:50:25+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="permacomputing" label="permacomputing"/><category term="longevity" label="longevity"/><category term="opinion" label="opinion"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/dishonesty-of-optimizing-for-developers-time" rel="alternate" hreflang="en" type="text/html"/><published>2023-07-31T10:54:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">The argument claiming &quot;optimizing for developer&apos;s time&quot; is fallacious.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Based on some individuals’ viewpoints, they emphasize optimizing for developer time or productivity as their main priority, rather than giving top precedence to aspects such as performance, robustness, or correctness.&lt;/p&gt;
&lt;section id=&quot;The-Thesis&quot;&gt;
&lt;h2&gt;The Thesis&lt;/h2&gt;
&lt;p&gt;Their argument revolves around the idea that developers’ time is more valuable and expensive than server resources. They often use phrases like “You can always refactor,” “You can always optimize for performance,” or “We will fix bugs later on” to support their viewpoint. While this perspective may be considered ingenious, it is contingent on proper planning, weighing the trade-offs, and actually acting upon those decisions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;My-Antithesis&quot;&gt;
&lt;h2&gt;My Antithesis&lt;/h2&gt;
&lt;p&gt;However, if this were genuinely the case, more substantial effort would have been invested in refactoring or choosing a more rigorous language than JavaScript, for example, a language that can significantly boost performance in the long run.&lt;/p&gt;
&lt;p&gt;Fixing bugs in backends written in JavaScript, PHP, or Python is certainly feasible, but adding performance improvements can become challenging, if not improbable. More meticulous programming tools automate the process of finding and fixing even the most elusive bugs and come with significant performance optimizations. The ability to make well-founded assumptions about the program allows for better optimization.&lt;/p&gt;
&lt;p&gt;This approach often leads to a situation where future engineers, tasked with rewriting the &lt;abbr title=&quot;Minimal Viable Product&quot; tabindex=&quot;0&quot;&gt;MVP&lt;/abbr&gt; program in a more scalable language, face an archeological rediscovery process.&lt;/p&gt;
&lt;p&gt;So, if they are not genuinely optimizing for shorter development time, what are they doing?&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Lifting-The-Veil-The-Actual-Thesis&quot;&gt;
&lt;h2&gt;Lifting The Veil: The Actual Thesis&lt;/h2&gt;
&lt;p&gt;It appears that they prioritize short-term gains over achieving greater long-term goals.&lt;/p&gt;
&lt;p&gt;A language like Rust, while providing benefits like enhanced safety and reliability, requires significantly more time to produce a binary or &lt;abbr title=&quot;Application Programming Interface&quot; tabindex=&quot;0&quot;&gt;API&lt;/abbr&gt;s. The manual labor of finding bugs is taken over by the compiler and the language’s semantics. If the focus is on developer productivity, then this automation is naturally desirable. However, what one truly desires to convey is “I have this feature, even though it may have some bugs and performance issues, I have it nonetheless.”&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;The-Synthesis&quot;&gt;
&lt;h2&gt;The Synthesis&lt;/h2&gt;
&lt;p&gt;That may be a positively good idea for trying the market to see if there is any for that specific idea, for most software developments though, the actual intention is not experimentation, as the novelty of product and business plan do not warrant a need for experimentation. Rather, having something to sell, as fast as possible. That’s for start-ups. Where there is both legitimate and illegitimate short-termism. But more established enterprises may have this pairing as well. While there are A/B experimentations going on, trying different approaches to see which works, middle management might also like the addition of another achievement in their yearly reports.&lt;/p&gt;
&lt;p&gt;A rapid way to discern whether it falls under the category of experimentation/prototyping &lt;abbr title=&quot;Minimal Viable Product&quot; tabindex=&quot;0&quot;&gt;MVP&lt;/abbr&gt; achievement-oriented project is to examine whether there is a notably extended period allocated for the program’s rewrite compared to its initial development phase.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Reader&quot;&gt;
&lt;h2&gt;Dear Reader&lt;/h2&gt;
&lt;p&gt;Similar to many phenomena, short-termism can indeed have legitimate applications. The reluctance of many to embrace this term is rooted in its improper and illegitimate uses.&lt;/p&gt;
&lt;p&gt;Certainly, there are well-intentioned individuals who advocate for developer productivity. However, those with ample experience will acknowledge that long-term developer productivity is not synonymous with low-overhead development, and, more often than not, these two objectives are incompatible.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Criteria For Choosing Tools</title><id>urn:uuid:803c48f3-c5b7-41d6-8e96-be3ff10b2fc2</id><updated>2025-05-30T15:45:43+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="technology" label="technology"/><category term="software" label="software"/><category term="tools" label="tools"/><category term="opinion" label="opinion"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/criteria-for-choosing-tools" rel="alternate" hreflang="en" type="text/html"/><published>2023-07-29T10:44:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">The criteria that I consider for choosing a good tool.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;The web is utterly fucked. But anyone with some resources at hand and curiosity at heart and intentional tool selection can have a decent experience.&lt;/p&gt;
&lt;section id=&quot;The-Reasons&quot;&gt;
&lt;h2&gt;The Reasons&lt;/h2&gt;
&lt;p&gt;The web’s lamentable state can be attributed to several factors. Allow me to enumerate them concisely for clarity:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Bloated beyond reason.
&lt;/li&gt;
&lt;li&gt;
Plagued with incessant ads.
&lt;/li&gt;
&lt;li&gt;
Prioritizing feature over bug fixes, if addressed at all.
&lt;/li&gt;
&lt;li&gt;
Designed to cater to journalists and advertisers, neglecting your needs.
&lt;/li&gt;
&lt;li&gt;
Imposing confinement and isolation upon you.
&lt;/li&gt;
&lt;li&gt;
Failing to empower users like yourself.
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id=&quot;A-Brief-Digression&quot;&gt;
&lt;h3&gt;A Brief Digression&lt;/h3&gt;
&lt;p&gt;The final point warrants further elaboration.&lt;/p&gt;
&lt;p&gt;The internet is, in fact, a tool. It is &lt;strong&gt;something&lt;/strong&gt; that is made to help &lt;strong&gt;someone&lt;/strong&gt; achieve &lt;strong&gt;some goal&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The captivating world of &lt;strong&gt;Web 2.0&lt;/strong&gt; and &lt;strong&gt;Social Media&lt;/strong&gt; (the somethings) - initially promising to empower people (the someones), granting them enriched social connections (the some goal). A promising start, indeed, leaving many with pleasant experiences during the inception of Web 2.0.&lt;/p&gt;
&lt;p&gt;But, alas, as time went by, the very incentives that drove these Social Media companies veered them off their intended course. They embarked on a divergent path, straying from their professed mission, and now, Web 2.0 primarily serves as a platform to amplify the voices of journalists and celebrities (the actual someones), propelling them towards greater fame and recognition (the actual some goals).&lt;/p&gt;
&lt;p&gt;The driving force behind these shifts? The ever-persistent quest for revenue from advertisers, pushing them to create content that captures maximum engagement. The more captivating, the more lucrative.&lt;/p&gt;
&lt;p&gt;Regrettably, the landscape has birthed what I would call the “four horsemen of reactionary engagement”: the doomsday, super political reporter; the enraging, populist racist politician; the trolling, impulsive &lt;abbr title=&quot;Chief Executive Officer&quot; tabindex=&quot;0&quot;&gt;CEO&lt;/abbr&gt;; and the drama-driven, vacuous celebrity.&lt;/p&gt;
&lt;p&gt;In a nutshell, it appears you’ve been played for a fool. Social media’s purported aim of empowering you is nothing but a delusion.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id=&quot;Go-Empower-yourself&quot;&gt;
&lt;h2&gt;Go Empower yourself&lt;/h2&gt;
&lt;p&gt;Before you proceed, there’s a prerequisite to address: overcoming the fear of missing out. Now, how one achieves this is not within my scope to divulge, but I can assist you in understanding why these fears are unfounded.&lt;/p&gt;
&lt;p&gt;Consider this: Have you truly missed out on anything of genuine importance? Reflect on whether the latest controversial statement from Donald Trump has genuinely altered the course of your life. And if it did, was Twitter (or whatever they dub it these days) truly the sole or optimal medium for receiving such information?&lt;/p&gt;
&lt;p&gt;Even in Iran, where official channels are notorious for propagating falsehoods, Twitter appears to be excessive. For me, friends and private messages reliably convey essential information. And indeed, individuals might spend considerable time on Twitter, but isn’t the fundamental pledge of social media the relay of information? If that need is already being fulfilled through other means, what purpose does Twitter truly serve?&lt;/p&gt;
&lt;p&gt;If you find yourself fortunate enough to reside in a country with trustworthy official channels, and your well-being hinges on crucial information like hurricane alerts, rest assured that dedicated services cater specifically to such needs. Similarly, if you derive pleasure from reading news articles, I suggest identifying the authors whose work you value and following them directly. However, if these activities do not align with your interests, then quite frankly, you have no real necessity for engaging with this “stuff”.&lt;/p&gt;
&lt;p&gt;Oh, my friend, let me share with you a sobering truth about these companies — they’re akin to emotionally abusive partners, manipulating you into believing you’re nothing without them. They demean you, calling you stupid and incapable of managing your life without their presence. They cunningly weave a narrative of how your life is all thanks to them, that your friendships exist solely because of their benevolence.&lt;/p&gt;
&lt;p&gt;But don’t be fooled by their deceiving ways. They mangle your interactions, force-feeding you ads and utter nonsense, all while claiming it’s an act of love. And when their misdeeds come to light, they stage a grand spectacle of apologies and vows to change, only to strike back even harder later on.&lt;/p&gt;
&lt;p&gt;It’s time to break free from this toxic cycle. I know it’s daunting, and fear may grip your heart initially, but liberate yourself from their clutches. You will discover a life far better than you ever imagined. You deserve more than this relentless manipulation. Embrace the freedom that awaits, my dear friend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;How-to-find-a-good-tool&quot;&gt;
&lt;h2&gt;How to find a good tool&lt;/h2&gt;
&lt;section id=&quot;Step-One-Find-The-Low-Hanging-Fruits&quot;&gt;
&lt;h3&gt;Step One: Find The Low-Hanging Fruits&lt;/h3&gt;
&lt;p&gt;You stand at the precipice of transformation, ready to change your life for the better. The first step is to identify the areas in your life that require attention. What needs are you seeking to fulfill? And upon which inadequate services are you currently relying?&lt;/p&gt;
&lt;p&gt;In my case, I sought:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
A steady flow of lightweight information.
&lt;/li&gt;
&lt;li&gt;
Daily interactions with fellow enthusiasts akin to myself.
&lt;/li&gt;
&lt;li&gt;
A means to uncover specific data.
&lt;/li&gt;
&lt;li&gt;
A reliable way to send emails.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For too long, I depended on subpar sources to meet these needs. For the first two, I found myself reliant on Twitter, Instagram, Reddit, and Google News. As for the third and fourth requirements, I resorted to Google’s services. However, all of these platforms consistently fell short and inflicted undue stress upon me.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Step-Two-Find-Effective-Replacements&quot;&gt;
&lt;h3&gt;Step Two: Find Effective Replacements&lt;/h3&gt;
&lt;p&gt;In my earlier post I have mentioned that I already have replaced most of these services with better ones. But I have not mentioned what constitutes an effective solution.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&quot;../entries/web-experience-makeover&quot;&gt;my previous post&lt;/a&gt;, I alluded to having replaced many of these services with superior alternatives. However, I haven’t delved into what exactly makes a solution effective.&lt;/p&gt;
&lt;p&gt;Allow me to outline the criteria and guiding principles for an empowering tool:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
It should not cause you any harm.
&lt;/li&gt;
&lt;li&gt;
It should not lock you in.
&lt;/li&gt;
&lt;li&gt;
It should not feel frugal.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, let me delve into the rationale behind these criteria:&lt;/p&gt;
&lt;section id=&quot;1-It-should-not-cause-you-more-harm-than-good&quot;&gt;
&lt;h4&gt;1. It should not cause you more harm than good&lt;/h4&gt;
&lt;p&gt;If a tool causes more harm than good, why persist in using it at all?&lt;/p&gt;
&lt;p&gt;To safeguard your interests, ensure that the tool operates with transparency. Platforms that intentionally harm users are less inclined to be forthcoming about their inner workings. Opt for open-source and audited software, provided you trust the incentives and capabilities of the auditors, as this fosters transparency.&lt;/p&gt;
&lt;p&gt;Moreover, it is crucial to align the incentives of the tool’s creators with your own. While there will always be some degree of misalignment, not all cases are equal. Selling or renting software may incentivize developers to plan for obsolescence, sell incomplete products, or enforce lock-ins. Yet, these misalignments are overshadowed by the egregious discrepancies inherent in ad-driven models.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;2-It-should-not-lock-you-in&quot;&gt;
&lt;h4&gt;2. It should not lock you in&lt;/h4&gt;
&lt;p&gt;Indeed, the peril of being locked into a tool becomes evident when the company’s incentives undergo a shift. I experienced this firsthand in 2015 when I was a loyal Evernote user with a premium subscription, trusting it with all my valuable information. However, when Evernote decided to drop right-to-left language support crucial for the Middle Eastern languages, my pleas for assistance fell on deaf ears. They deemed the region unworthy of attention, leaving me stranded and unable to utilize my data effectively.&lt;/p&gt;
&lt;p&gt;The true pain emerged when I attempted to export my information and realized I was trapped in their ecosystem. They held my notes’ hostage, providing them back only in a non-standard format through &lt;abbr title=&quot;Extensible Markup Language&quot; tabindex=&quot;0&quot;&gt;XML&lt;/abbr&gt; or &lt;abbr title=&quot;Java Script Object Notation&quot; tabindex=&quot;0&quot;&gt;JSON&lt;/abbr&gt; files. This, my friends, was the dreaded lock-in, and I had to endure a labyrinthine journey of manual extraction to break free.&lt;/p&gt;
&lt;p&gt;To avoid such a predicament, one essential question should be posed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Will it be more difficult for me to switch to a competitor once I’ve fully adopted this service compared to my current situation before using it?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the service retains your data and only offers it back in a non-standard format, it becomes significantly more challenging to transition to a competitor after investing your notes into the first service. Be vigilant and consider the implications before getting entangled in such situations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;3-It-should-not-feel-frugal&quot;&gt;
&lt;h4&gt;3. It should not feel frugal.&lt;/h4&gt;
&lt;p&gt;Let us keep in mind the essence of this endeavor: to enhance the quality of our lives. Undoubtedly, there are noble causes that may necessitate adopting a certain level of frugality, as was the case for me with animal rights, which amusingly led me to embrace veganism.&lt;/p&gt;
&lt;p&gt;However, advocating for these causes demands energy, and it might inadvertently lead to isolation. We must acknowledge that not everything can or should be a constant battle. The purpose of utilizing these tools is to improve our lives, not to make them more arduous.&lt;/p&gt;
&lt;p&gt;If safeguarding your privacy to the utmost extreme is your goal, then by all means, employ complex passwords for each site and commit them to memory. Nevertheless, we must be mindful that our fighting energy is finite. Thus, it becomes essential to prioritize and channel our limited energy toward the most urgent and meaningful issues that truly resonate with our hearts.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Reader&quot;&gt;
&lt;h2&gt;Dear Reader&lt;/h2&gt;
&lt;p&gt;You are on the right path, and I believe in you wholeheartedly! Trust me, I’ve been through this journey myself, and it turned out to be a delightful and straightforward experience. Take heart, for you can certainly achieve it too! Keep going, and you’ll soon realize how much better and easier life becomes. You’ve got this!&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Giving My Experience of Web a Makeover</title><id>urn:uuid:e5669e8a-a403-4c0d-aed9-7080c7f72536</id><updated>2023-07-19T10:34:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="search-engine" label="search-engine"/><category term="kagi" label="kagi"/><category term="feedbin" label="feedbin"/><category term="rss" label="rss"/><category term="opinion" label="opinion"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/web-experience-makeover" rel="alternate" hreflang="en" type="text/html"/><published>2023-07-19T10:34:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I&apos;m changing somethings about my web. For my own sake.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Back in the good old days, I found myself drawn to the wonders of the internet, captivated by its virtual world, teeming with individuals who resonated with me, people I admired, or at least aspired to emulate. The communication channels of that era felt more personal, more akin to a lively conversation passed on through word of mouth.&lt;/p&gt;
&lt;section id=&quot;More-of-Those-Days&quot;&gt;
&lt;h2&gt;More of Those Days&lt;/h2&gt;
&lt;p&gt;In those youthful days, I’d eagerly scour the web for words that piqued the interests of my teenage self, and with a simple search, Google would present me with a treasure trove of blogs authored by kindred spirits. I’d venture into the realms of Twitter, FriendFeed, Facebook, Orkut, and the myriad other social platforms, spending precious moments escaping the painful realities of feeling marginalized by my parents, teachers, and peers at school.&lt;/p&gt;
&lt;p&gt;The internet of that era held a special place in my heart; it offered solace and kinship. Even though I may not have been as popular as some within those social circles, I cherished engaging in conversations within a vibrant crowd of amazing individuals, the very ones I admired deeply.&lt;/p&gt;
&lt;p&gt;As time marched on, many of the cherished online spaces I once loved to fell by the wayside, while others morphed into monstrous entities, becoming tools of ostracization. Although I personally may not have been the target of such mistreatment, I could discern the toxic environment that fostered and emboldened bullies.&lt;/p&gt;
&lt;p&gt;Even the search engines, once a source of discovery and connection, began to falter. Each passing day brought forth an ever-increasing deluge of hyper-SEO-optimized, meaningless content and tech-centric sites merely driven by profit, overtaking the slots that were once reserved for passionate individuals with independent blogs.&lt;/p&gt;
&lt;p&gt;As the landscape transformed, I gradually came to terms with the nostalgic allure of those bygone days, realizing that it had become a remnant of the lost innocence of the early internet or clouded by my own flawed perception of what truly transpired.&lt;/p&gt;
&lt;p&gt;The sense of desperation that had gripped me started to crumble when Elon Musk’s actions on Twitter triggered a disillusionment, pushing me to reconsider Fosstodon-an open-source social platform. And oh, what a fortuitous decision that turned out to be. It was as if I had stumbled upon the early days of FriendFeed, where genuine exchange of information thrived, embodying the very essence of the social web I yearned for.&lt;/p&gt;
&lt;p&gt;But a part of me questioned this fortunate discovery. Could it merely be a chance occurrence, a fluke in the otherwise distorted realm of human-generated nonsense? I grappled with doubts.&lt;/p&gt;
&lt;p&gt;Then, as if destiny had a hand in it, the second revelation struck-a website called Kagi, delivering yet another blow to the illusion I had held onto. The cracks in my previous beliefs widened, challenging me to confront the harsh realities of the digital landscape.&lt;/p&gt;
&lt;p&gt;Kagi, an unconventional paid search engine, piqued my curiosity, prompting me to give it a try. What unfolded before my eyes left me astounded-a screen brimming with blog posts dedicated to the concept of &lt;strong&gt;PermaComputing&lt;/strong&gt; occupied the very first page of results. At that moment, it dawned on me that the beloved world of independent blogging, which I had presumed to be on life support, had not faded away as I had believed. Instead, it thrived, resilient and as potent as ever. It was the so-called social media platforms and search engines, the very entities I had placed my trust in, that had ultimately let me down, betraying the internet I held dear.&lt;/p&gt;
&lt;p&gt;The illusion that once clouded my perception had dissipated into thin air.&lt;/p&gt;
&lt;p&gt;Determined to instigate a change, I took my first footsteps in the path full of transformations. I am currently in the midst of that process, but I have successfully identified the type of experience I desire. I have pinpointed a few readily available opportunities and have taken proactive measures to secure them for myself.&lt;/p&gt;
&lt;p&gt;Foremost, I yearn for an authentic perspective of the internet-a genuine representation of the collective human experience rather than a mere showcase of the glossiest and most superficial elements. To fulfill this aspiration, I sought out a suitable search engine, and as I mentioned earlier, I found my answer in Kagi-it aligns perfectly with my vision.&lt;/p&gt;
&lt;p&gt;Furthermore, I crave a steady stream of thoughtful and sincere content. To achieve this, I turned to an RSS aggregator to curate and deliver such material to me consistently. Feedbin emerged as the ideal choice, serving as the conduit for fulfilling my appetite for meaningful discourse.&lt;/p&gt;
&lt;p&gt;I discovered another low-hanging fruit on my path towards a more fulfilling online experience-a social website optimized for community rather than being driven solely by journalists. This gem came in the form of Mastodon.&lt;/p&gt;
&lt;p&gt;In my quest for a trustworthy email service that respects my privacy and shields me from the relentless influx of spammers, I received a recommendation for ProtonMail. Taking heed of the suggestion, I made the switch and, so far, I find it to be a satisfactory choice.&lt;/p&gt;
&lt;p&gt;Update: I am using Migadu these days. 2023-11-14&lt;/p&gt;
&lt;p&gt;You may have noticed that out of the four aforementioned solutions, three are paid services. Additionally, two of them are closed-sourced, while one-the email service-poses the risk of vendor lock-in. Although this may not be the ideal scenario, I weighed my options against a set of criteria that I had established. In the end, these choices emerged as the better alternatives, despite their limitations.&lt;/p&gt;
&lt;p&gt;However, I realize that this post has already grown quite lengthy, and the criteria I employed deserve a &lt;a href=&quot;/entries/criteria-for-choosing-tools&quot;&gt;more thorough elaboration&lt;/a&gt;. Therefore, I will save their exploration for a future post, where I can delve deeper into these ideas deserving of greater attention.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Reader&quot;&gt;
&lt;h2&gt;Dear Reader&lt;/h2&gt;
&lt;p&gt;At present, I find immense joy in my renewed online experience-a sense of tranquility and refuge washes over me whenever I delve into the internet. I wholeheartedly urge you, dear reader, who may be experiencing similar frustrations to those of my past self, to take a moment and reevaluate your internet usage. There is a strong possibility that the internet can be a much more pleasant and gratifying space than what you might be feeling at this moment. I know this to be true because I am living it right now. Embrace the journey of exploring better alternatives and reclaim the joy in your online interactions.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">HTML, The Programming Language</title><id>urn:uuid:79b252dc-ade4-4f07-8497-e5b1a779bb8e</id><updated>2025-05-30T15:27:28+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="html" label="html"/><category term="language" label="language"/><category term="opinion" label="opinion"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/html-the-programming-language" rel="alternate" hreflang="en" type="text/html"/><published>2023-06-24T10:20:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I argue that HTML is a programming language and saying it is not, is just gatekeeping.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">
&lt;p&gt;The eternal dispute over whether &lt;abbr title=&quot;HyperText Markup Language&quot; tabindex=&quot;0&quot;&gt;HTML&lt;/abbr&gt; counts as a proper programming language seems to bring out the best and worst of our community’s collective rational faculties. A veritable feast of half-baked attempts to define away the problem by appealing to whatever convenient characteristics the speaker happens upon, combined with a sprinkling of more serious thinkers seeking some grand philosophical theory to explain it all. But don’t get your hopes up - you won’t find any silver bullet solutions here folks. Just a parade of armchair theoreticians grasping blindly for some sense of clarity amidst the fog of poorly thought out positions. So gather ’round, listen up, and prepare yourself for another round of pointless squabbling. The fun is just beginning!&lt;/p&gt;
&lt;section id=&quot;The-Loops-And-The-Features&quot;&gt;
&lt;h2&gt;The Loops And The Features&lt;/h2&gt;
&lt;p&gt;Individuals frequently endeavor to delineate programming languages by differentiating them from &lt;abbr title=&quot;HyperText Markup Language&quot; tabindex=&quot;0&quot;&gt;HTML&lt;/abbr&gt;, contending that a programming language possesses specified traits. Traits that might encompass looping structures, conditional statements, or even compilations. Alas, these efforts are founded upon retrospective comprehension - reliant on past personal observations of what constitutes a programming language. This flawed methodology, inherently, undermines the legitimacy of their claims inasmuch as they concurrently explore discrepancies between what is deemed not to be a programming language. A circular argument ensues, lacking genuineness, and thus futile in supporting the allegation that &lt;abbr title=&quot;HyperText Markup Language&quot; tabindex=&quot;0&quot;&gt;HTML&lt;/abbr&gt; lacks programming language attributes.&lt;/p&gt;
&lt;p&gt;Alright, listen up! Let’s say I’m dead set on accusing Tom of being a thieving scoundrel while vehemently asserting that Amanda is as innocent as can be. To make my case, I start off by drawing a sharp contrast between Tom and Amanda. Then, after much contemplation, I concoct a ridiculously specific definition of a thief: “Anyone who happens to be a man in his sixties with an academic background in History.” Can you believe that? Now, picture this - imagine we go ahead and convict every poor soul who fits this outrageous description. Well, I’ll tell you right now, that’s a load of nonsense! It simply won’t fly, and anyone with half a brain can see how utterly flawed and impractical that notion is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;The-Turing-Completeness&quot;&gt;
&lt;h2&gt;The Turing Completeness&lt;/h2&gt;
&lt;p&gt;Now, let me tell you about those folks who prefer a more unified approach when it comes to defining something, like a programming language. They often rely on axioms, you know, those fundamental principles that serve as the bedrock of reasoning. One of the most famous examples is the notion of &lt;strong&gt;Turing completeness&lt;/strong&gt; being the ultimate defining factor. At first glance, it may not seem problematic. But here’s the burning question: Why on earth would we go down that route?&lt;/p&gt;
&lt;p&gt;Think about it. We create distinctions in definitions to aid us in effectively communicating a concept among ourselves. As far as I know, most programmers couldn’t care less about whether a programming language can perform every single computation imaginable in theory. No, sir! Instead, they value the practical aspects like ease of use and reliability when it comes to solving a specific set of problems. So, how in the world would that earlier theoretical claim serve us in our day-to-day tasks? It’s a real head-scratcher, especially when you consider that such a filter would let languages like brain-fuck and whitespace pass through, while disregarding &lt;strong&gt;total&lt;/strong&gt; programming languages that could actually lead to more robust and dependable software.&lt;/p&gt;
&lt;p&gt;But here’s the kicker - some people actually advocate for this madness. They’ve come up with a seemingly cohesive definition of a programming language, but their motivations for choosing that definition are nothing more than an afterthought. As a result, their definitions are utterly useless, or at the very least, useless to those who couldn’t care less about denigrating a language. Can you believe it? What a ridiculous state of affairs!&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Reader&quot;&gt;
&lt;h2&gt;Dear Reader&lt;/h2&gt;
&lt;p&gt;Now, let me be clear, my intention here is not to rally behind &lt;abbr title=&quot;HyperText Markup Language&quot; tabindex=&quot;0&quot;&gt;HTML&lt;/abbr&gt; and extol its virtues. Instead, I aim to shed light on our incessant desire to bestow added significance upon the definition of our work. And, quite frankly, I implore you to put an end to it. You see, a programming language can possess capabilities or be lacking in them, and a programmer may be focused on orchestrating the flow of information or on its presentation. We come in all shapes and forms, each with our unique approaches. Attempting to establish some sort of gate-keeping mechanism in this endeavor will only result in programmers overlooking the fact that they may just require &lt;abbr title=&quot;HyperText Markup Language&quot; tabindex=&quot;0&quot;&gt;HTML&lt;/abbr&gt; and &lt;abbr title=&quot;Cascading Style Sheets&quot; tabindex=&quot;0&quot;&gt;CSS&lt;/abbr&gt; to fulfill their job requirements. This, in turn, contributes to the sorry state of the web-bloated and disheartening.&lt;/p&gt;
&lt;p&gt;Let us cherish our roles as creators and refrain from placing undue emphasis on the definition of our jobs, but rather, let us focus on the outcomes we produce. After all, we are all creators and problem-solvers at heart.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Consider Developer&apos;s Snack</title><id>urn:uuid:a3c4dab4-6abc-40cf-a5da-3b54cdd6eea2</id><updated>2025-05-30T15:48:03+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="programming" label="programming"/><category term="permacomputing" label="permacomputing"/><category term="opinion" label="opinion"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/consider-developers-snack" rel="alternate" hreflang="en" type="text/html"/><published>2023-06-21T10:13:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Making a case for considering everything when considering sustainability of a program.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;During my early 20s, I found myself immersed in the world of sustainable architecture as an architecture student. Engaging in various workshops centered around this field, one particular experience stands out as a monumental turning point in my life. It was a workshop conducted by a renowned professor in Iran, where I gained valuable insights.&lt;/p&gt;
&lt;p&gt;Within this workshop, we collectively brainstormed strategies to harness heat sources for a four-member family’s house, aiming to optimize its thermal efficiency. We considered a range of possibilities, including solar and geothermal heat, as well as the heat generated by the kitchen oven. However, there was one significant heat source that eluded our attention, as pointed out persistently by the professor.&lt;/p&gt;
&lt;p&gt;Eventually, he provided us with a clue: “You seem to have overlooked four 37-degree Celsius heaters.” It dawned on us that we had forgotten to factor in the heat generated by the family members themselves. Their body heat, a natural source of warmth, had slipped our minds entirely.&lt;/p&gt;
&lt;p&gt;Reflecting on a more recent occurrence, a certain paper began circulating, comparing the energy usage footprint of different programming languages. Yet, I couldn’t help but notice that the discussions surrounding this paper overlooked a crucial aspect-it solely measured the energy footprint at one specific point in the application’s life-cycle.&lt;/p&gt;
&lt;p&gt;It is essential to recognize that the energy usage of a programming language extends beyond a mere snapshot analysis. To truly grasp the overall impact, we must consider the entire life-cycle of the application, accounting for factors such as development, deployment, maintenance, and eventual retirement. Only then can we gain a comprehensive understanding of the energy implications associated with different programming languages.&lt;/p&gt;
&lt;section id=&quot;The-Paper-As-The-Thread-We-Pull&quot;&gt;
&lt;h2&gt;The Paper, As The Thread We Pull&lt;/h2&gt;
&lt;p&gt;The paper, titled “Energy Efficiency Across Programming Languages,” delves into the exploration of various problems and their corresponding solutions, which are implemented across multiple programming languages. The researchers conducted an analysis of the electricity consumption associated with each implementation. In essence, the primary focus of the study revolves around determining the relative energy efficiency of different programming languages, with C emerging as the most efficient and serving as the benchmark for measurement.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;C      | 01.00 | ▓
Rust   | 01.03 | ▓
Java   | 01.98 | ▓▓
Python | 75.88 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
Perl   | 79.58 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These results carry considerable weight, although it is essential to address a common misconception surrounding their implications. Contrary to popular belief, these findings do not unequivocally assert that a C program is inherently more environmentally sustainable than its Java counterpart.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Consider-The-Snack&quot;&gt;
&lt;h2&gt;Consider The Snack&lt;/h2&gt;
&lt;p&gt;In the field of sustainability literature, there exists a concept known as Life-Cycle Assessment(&lt;abbr title=&quot;Life-Cycle Assessment&quot; tabindex=&quot;0&quot;&gt;LCA&lt;/abbr&gt;). &lt;abbr title=&quot;Life-Cycle Assessment&quot; tabindex=&quot;0&quot;&gt;LCA&lt;/abbr&gt; involves evaluating the environmental impact of a product throughout its entire life cycle, encompassing aspects such as raw material extraction, manufacturing, and disposal or recycling.&lt;/p&gt;
&lt;p&gt;When applying this concept to the assessment of software life cycles, we realize that there are several significant factors that have been overlooked. Allow me to provide some insights on these important considerations.&lt;/p&gt;
&lt;p&gt;Firstly, the authors of the paper have primarily focused on the runtime of a specific set of problems. This means that their applications follow a sequence of starting up, solving the given problem, and then exiting. Consequently, the results obtained are biased towards programming languages that excel at efficient startup and shutdown processes. However, this perspective fails to account for the behavior of servers and long-running processes. Servers, for instance, typically start up once per day or even less frequently and spend extended periods in the computational phase. If a programming language is efficient during the initial startup but requires frequent restarts during runtime, this crucial aspect is overlooked.&lt;/p&gt;
&lt;p&gt;But we shouldn’t stop there. Another aspect to consider is compilation. While Rust is indeed an impressive language, its compilation process is significantly more resource-intensive compared to Go. Rust yields highly efficient binaries, but the energy expended during the compilation process is also considerably higher.&lt;/p&gt;
&lt;p&gt;Furthermore, the improved quality of Rust’s compiled binaries becomes relevant when we consider the potential presence of bugs and the subsequent need for recompilation. More permissive compilers may result in programs with a higher likelihood of bugs, necessitating additional rounds of debugging, fixing, and retesting. It’s important to acknowledge that this discussion goes beyond the developer’s running computer and includes factors such as sustenance needs, energy consumption to support their biological functioning during the process of bug fixing, and the overall impact on the environment.&lt;/p&gt;
&lt;p&gt;Additionally, the continuous deployment or release cycles, repackaging efforts, and the use of &lt;abbr title=&quot;Continuous Integration&quot; tabindex=&quot;0&quot;&gt;CI&lt;/abbr&gt;/&lt;abbr title=&quot;Continuous Delivery&quot; tabindex=&quot;0&quot;&gt;CD&lt;/abbr&gt; practices all contribute to the &lt;strong&gt;ecological footprint&lt;/strong&gt;. Recompilation for each platform targeted, as well as the network costs associated with distributing binaries or source code to different endpoints, also significantly impact the environment.&lt;/p&gt;
&lt;p&gt;The problem of compatibility further compounds the issue. Programming languages with runtimes shipped separately from the package, such as Python, Lua, and other scripting or &lt;abbr title=&quot;Just-In-Time&quot; tabindex=&quot;0&quot;&gt;JIT&lt;/abbr&gt; languages, as well as those based on virtual machines like &lt;abbr title=&quot;Java Virtual-Machine&quot; tabindex=&quot;0&quot;&gt;JVM&lt;/abbr&gt;, often require reprogramming or the inclusion of older runtime versions when breaking changes occur. This adds to the complexity and environmental impact of software development and packaging.&lt;/p&gt;
&lt;p&gt;Furthermore, poorly designed programs can accumulate significant technical debt over time, resulting in rewriting. Although the language and toolchain themselves may not directly cause this, the ecosystem surrounding languages like JavaScript, PHP, and Python tends to encourage short-term thinking. In contrast, languages like Rust, C, Fortran, and others that focus on system-level development promote long-term support and are home to projects that have thrived for several decades.&lt;/p&gt;
&lt;p&gt;Moreover, the variability in usage patterns must be taken into account. While languages like C and C++ require substantial energy for compilation across different platforms, languages such as Rust, Go, and Java mitigate the duplication of energy required to support multiple platforms within a single application.&lt;/p&gt;
&lt;p&gt;Finally, we must consider the energy expended in the development, maintenance, and support of programming languages. Languages like Rust offer remarkable expressive capabilities, not merely due to better timing or superior thinking but also as a result of extensive collaborative efforts. Conversely, languages like Elm undergo minimal changes over time.&lt;/p&gt;
&lt;p&gt;It is worth emphasizing that the energy required to learn a language, the environmental consequences of mistakes made during coding (e.g., unintentionally sending a million requests to thousands to different servers), variations in energy usage among developers from different countries, and the decreasing lifespan of hardware are all factors that contribute to the overall consideration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Reader&quot;&gt;
&lt;h2&gt;Dear Reader&lt;/h2&gt;
&lt;p&gt;The crux of the matter is that complexity pervades these considerations, demanding our thoughtful attention and appropriate mitigation for each aspect. Failing to acknowledge and address each facet places us at risk of optimizing solely for one element while sacrificing the other to the extent of rendering our efforts absurd.&lt;/p&gt;
&lt;p&gt;It is important to note that I have deliberately omitted discussions about post-harm mitigation. Our focus has been on reducing harm itself. Exploring the costs associated with bootstrapping and averting catastrophic scenarios would expand beyond the scope of this essay.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">FLOSS For Software Longevity</title><id>urn:uuid:159d003a-6e32-4555-bc0d-c979fced95db</id><updated>2025-05-30T16:02:22+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="programming" label="programming"/><category term="permacomputing" label="permacomputing"/><category term="floss" label="floss"/><category term="opinion" label="opinion"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/floss-for-longevity" rel="alternate" hreflang="en" type="text/html"/><published>2023-06-14T09:56:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I argue that Free and open source licenses are good for longevity of software.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Free/Libre and Open Source Software (&lt;abbr title=&quot;Free/Libre and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FLOSS&lt;/abbr&gt;) is a captivating realm within software development. What makes &lt;abbr title=&quot;Free/Libre and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FLOSS&lt;/abbr&gt; particularly intriguing is its deviation from conventional business goals, leading to planned longevity and a distinct approach to sustainability.&lt;/p&gt;
&lt;section id=&quot;Reasons&quot;&gt;
&lt;h2&gt;Reasons&lt;/h2&gt;
&lt;p&gt;Let us delve into the unique qualities of &lt;abbr title=&quot;Free/Libre and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FLOSS&lt;/abbr&gt; and the factors that contribute to its better suitability for longevity.&lt;/p&gt;
&lt;section id=&quot;The-longevity-of-the-business-model-serves-it-well&quot;&gt;
&lt;h3&gt;The longevity of the &lt;abbr title=&quot;Free/Libre and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FLOSS&lt;/abbr&gt; business model serves it well&lt;/h3&gt;
&lt;p&gt;The common business models are better suited for short-term goals. There are two major approaches: selling or renting.&lt;/p&gt;
&lt;p&gt;Small to mid-sized software companies predominantly prioritize the sale of their products. The concept of product longevity, while acknowledged as necessary, assumes a secondary role rather than being a central objective. Its primary function lies in establishing trust among consumers. Once the initial excitement surrounding the launch of a new and captivating product subsides, these companies swiftly shift their attention to the next innovation. The success of marketing these novel products heavily relies on users’ fear of missing out and the perceived loss of functionality associated with the previous iteration. Unfortunately, this often leads to the inclusion of unnecessary features, deliberate planning for obsolescence, and resistance against the right to repair. In this cycle, longevity takes a backseat as the perpetual replacement of one product with another take precedence.&lt;/p&gt;
&lt;p&gt;Conversely, larger companies place a premium on the rental model for software. Instead of users owning the software outright, they opt for subscription-based payment models for continuous usage. One might assume that these companies would prioritize stability to retain their subscribers. However, practical implementation often takes a different route. These companies rely on monopolistic tactics, such as acquiring competitors or launching extensive marketing campaigns to stifle new entrants. In cases where competition persists, they resort to content exclusivity, coercing users to purchase their product alongside competitors’ offerings. Consequently, users find themselves utilizing these products for prolonged periods not due to their exceptional quality, but rather because they perceive limited alternative options. The subscription model may make sense when paying for a service, but it doesn’t align with current software development. Paying subscription for developing and bug-fix of a product is simply paying for the privilege of using an incomplete version of a product.&lt;/p&gt;
&lt;p&gt;In contrast, companies adopting a pay-for-enterprise-support model for open-source products, such as Canonical and Red Hat, exhibit commendable practices. Their primary emphasis lies on longevity. If the software is functioning adequately, their tasks are straightforward, eliminating the need to address the same issue repeatedly for each client. Longevity serves as both their evidence and &lt;em&gt;modus operandi&lt;/em&gt;. They provide support for software that has already weathered numerous instabilities. They employ different development stages, such as alpha, unstable, stable, and long-term releases. These features can subsequently be passed on to other distributions with more robust objectives, such as &lt;abbr title=&quot;Red Hat Enterprise Linux&quot; tabindex=&quot;0&quot;&gt;RHEL&lt;/abbr&gt;.&lt;/p&gt;
&lt;p&gt;Although these companies may impose charges for bug fixes, their underlying offering revolves around selling stability and longevity (think &lt;strong&gt;Ubuntu Pro&lt;/strong&gt;). This approach is not driven solely by inherent benevolence but rather stems from a lack of alternatives. They are unable to monopolize a product that can be cloned, forked, and utilized to initiate independent ventures. Nor can they vend software that others can fork, enhance, and sell at higher prices or even distribute for free. Their sole viable course of action entails creating a product that strikes a balance, avoiding both excessive limitations that render it futile and excessive complexity that complicates support.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;engineers-prioritize-quality-over-quantity&quot;&gt;
&lt;h3&gt;&lt;abbr title=&quot;Free/Libre and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FLOSS&lt;/abbr&gt; engineers prioritize quality over quantity&lt;/h3&gt;
&lt;p&gt;As we discussed, most businesses prioritize product quality only until it reaches a level sufficient for selling.&lt;/p&gt;
&lt;p&gt;This often leads to engineers being pushed and encouraged to develop faster, sacrificing quality and stability when it hinders “beating the competition to market”. I’m sure I’m not alone in feeling dissatisfied with creating instant legacy products and leaving behind a trail of subpar, useless software. It leaves no room for pride in one’s work.&lt;/p&gt;
&lt;p&gt;As a result, engineers who value quality find satisfaction in other avenues, such as personal projects or contributing to libraries and tools they use themselves.&lt;/p&gt;
&lt;p&gt;The dynamics of development in these situations differ. Open-source software often lacks the same level of resources, making maintainability a crucial concern. Allowing technical debt to accumulate in a project one maintains can result in paying a hefty price, even in a short period. The more users a project has, the more the burden of technical debt becomes apparent-quite the opposite of the industry’s “move broken things, fast” mentality.&lt;/p&gt;
&lt;p&gt;Consequently, successful open-source products tend to have meticulous and uncompromising maintainers.&lt;/p&gt;
&lt;p&gt;Another important aspect to consider is that open-source software greatly enhances one’s resume. Similar to a resume, open-source projects showcase an individual’s best work. They are like first dates, where you present yourself at your best. Consequently, open-source projects motivate developers to create their finest code and documentation.&lt;/p&gt;
&lt;p&gt;Furthermore, transparency is a vital aspect of open-source projects. Engaging in dubious practices, such as intrusive telemetry, can agitate the surrounding community.&lt;/p&gt;
&lt;p&gt;In summary, there are four main reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
The cost of maintainability
&lt;/li&gt;
&lt;li&gt;
The positive impact on one’s resume
&lt;/li&gt;
&lt;li&gt;
Counteracting the lack of satisfaction caused by lower quality software in daily work
&lt;/li&gt;
&lt;li&gt;
Embracing transparency
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id=&quot;exhibits-a-greater-degree-of-diversity&quot;&gt;
&lt;h3&gt;&lt;abbr title=&quot;Free/Libre and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FLOSS&lt;/abbr&gt; exhibits a greater degree of diversity&lt;/h3&gt;
&lt;p&gt;When it comes to a biological ecosystem, its resilience stems from the diversity of its members. Let’s imagine a scenario involving a moth that feeds on maple tree branches. In a jungle filled with maple trees, the moth can feast and reproduce endlessly. However, there’s a twist.&lt;/p&gt;
&lt;p&gt;Around 10% of the maple trees have developed a variation of their membrane that is toxic to the moth, purely by chance. Now, if the moth tries to feed on these trees, it has a 1 in 10 chance of being fatally poisoned. If there were only a single moth, it would be the end of its lineage. However, imagine a population of 100 moths, and 10% of them have accidentally developed immunity. These “super moths” may be larger and more resistant to the trees, but they are also more visible to predators like birds. And so, the cycle continues.&lt;/p&gt;
&lt;p&gt;The diversity of approaches within a biological ecosystem is crucial. In the context of biological beings, the exchange of random sets of genes through sexual reproduction likely emerged as a means to enhance resilience. Microbes that prey on others, on the other hand, face a more challenging situation, as the result.&lt;/p&gt;
&lt;p&gt;These advantageous mechanisms resulting from diversity are also present in the software ecosystem.&lt;/p&gt;
&lt;p&gt;The needs and threats faced by a server differ from those faced by a German student’s laptop. While Linux is ubiquitous in the open-source desktop realm, there are numerous slightly different Linux distributions available. These variations encompass different themes, preinstalled applications, package managers, and even packaging architecture models. Additionally, there are kernels compiled with different flags and versions.&lt;/p&gt;
&lt;p&gt;Given this remarkable diversity, it comes as little astonishment that Microsoft’s ardent campaign during the 2000s against the comparably youthful, less cohesive, and resource-limited Linux met with abysmal failure. Strikingly, in a twist of events, Microsoft has lately unveiled its very own Linux distribution and dedicated years to crafting the Windows Subsystem for Linux.&lt;/p&gt;
&lt;p&gt;To the proprietary realm, an ecosystem characterized by the development, redesign, and forking of diverse products, yielding a multitude of solutions, may appear inherently inefficient. Yet, from the perspective of permaculture and PermaComputing, such an ecosystem manifests as nothing short of utopia.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;demonstrates-a-higher-level-of-robustness&quot;&gt;
&lt;h3&gt;&lt;abbr title=&quot;Free/Libre and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FLOSS&lt;/abbr&gt; demonstrates a higher level of robustness&lt;/h3&gt;
&lt;p&gt;&lt;abbr title=&quot;Free/Libre and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FLOSS&lt;/abbr&gt; transcends being a mere generator of independent variations that begin anew each time. It represents a system where progress builds upon existing foundations, with each subsequent layer amplifying the importance of the underlying ones. Irrespective of how many stories above the ground one ascends, the ground level remains a paramount concern if its integrity is jeopardized. Prominent examples of this phenomenon can be observed in projects like curl, the kernel, and OpenSSL. Although these initiatives were initially initiated by individuals, they have evolved into integral components of numerous other undertakings. The driving force compelling many individuals to contribute to these projects stems from the realization that the cost of abstaining from participation would be significantly greater.&lt;/p&gt;
&lt;p&gt;However, it is important to recognize that this process is not always pleasant. Consider the immense pressure on OpenSSL developers. If they were to become overwhelmed and exhausted like many other open-source maintainers, the consequences could be significant.&lt;/p&gt;
&lt;p&gt;Yet, when such challenges arise (and they do), we all become aware of them. We sense the danger and collectively strive to find solutions. This is in stark contrast to the situation when a proprietary software developer abandons a company. Until a replacement is found, users are left unaware and vulnerable to potential security threats posed by malicious hackers.&lt;/p&gt;
&lt;p&gt;Thanks to this collective effort and attention to robustness, many foundational open-source software programs have remained the best tools for the job even after decades of use.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Reader&quot;&gt;
&lt;h2&gt;Dear Reader&lt;/h2&gt;
&lt;p&gt;Now, esteemed reader, I trust you comprehend the rationale behind why individuals with a penchant for enduring solutions find the realm of &lt;abbr title=&quot;Free/Libre and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FLOSS&lt;/abbr&gt; far more fertile than its alternatives.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Moving in Rust is Pure</title><id>urn:uuid:36d44665-f9a3-4f1c-830b-d0094c30a1b7</id><updated>2023-04-09T09:14:00+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="functional-programming" label="functional-programming"/><category term="programming" label="programming"/><category term="rust" label="rust"/><category term="opinion" label="opinion"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/moving-is-pure" rel="alternate" hreflang="en" type="text/html"/><published>2023-04-09T09:14:00+02:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I argue that in rust, moving a variable is pure, in the sense of functional programming.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;The act of moving arguments within Rust’s functions serves as a compelling means to uphold the &lt;strong&gt;purity&lt;/strong&gt; of the function. By embracing this practice, we ensure that the function operates on unique ownership of its inputs, preserving the integrity and &lt;strong&gt;immutability&lt;/strong&gt; of data, which are fundamental tenets of &lt;strong&gt;functional programming&lt;/strong&gt;.&lt;/p&gt;
&lt;section id=&quot;Moving-a-Variable-to-a-Function-in-Rust-Doesn’t-Make-It-Impure&quot;&gt;
&lt;h2&gt;Moving a Variable to a Function in Rust Doesn’t Make It Impure&lt;/h2&gt;
&lt;p&gt;So as an introduction, if you don’t know Rust:&lt;/p&gt;
&lt;p&gt;In Rust, we have this concept of &lt;strong&gt;moving&lt;/strong&gt; variables. It is like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; A variable is made.&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; a_variable = some_value&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; It moves into this function.&lt;/span&gt;
_ = &lt;span class=&quot;function&quot;&gt;a_function_that_takes_ownership&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;a_variable&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; We cannot use a_variable anymore! So, we cannot do this!&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; b_variable = a_variable&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I consider &lt;code&gt;a_function_that_takes_ownership&lt;/code&gt; to be a &lt;strong&gt;pure function&lt;/strong&gt;. However, it raises a possible confusion:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Doesn’t a function that takes ownership change the state of the outer function? Isn’t that a side effect?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I argue that it doesn’t. Here is why: a function is not a function call. Let’s visualize it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;      ________outer_function_______
--in-&amp;gt;|       __inner_f___        |-out-&amp;gt;
      | -in-&amp;gt; |          | -out-&amp;gt; |
      |       ------------        |
      -----------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So we have two functions. One outer, and one inner:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Each function should have inputs and an output
&lt;/li&gt;
&lt;li&gt;
Other than their outputs, they should not change anything outside their function space
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If these conditions are not met, our function is not &lt;strong&gt;pure&lt;/strong&gt;.&lt;/p&gt;
&lt;section id=&quot;Step-1&quot;&gt;
&lt;h3&gt;Step 1&lt;/h3&gt;
&lt;p&gt;Now consider a variable &lt;code&gt;[V]&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;      _____________________________
-----&amp;gt;| [v]   ____________        |-----&amp;gt;
      | ----&amp;gt; |          | -----&amp;gt; |
      |       ------------        |
      -----------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;/section&gt;
&lt;section id=&quot;Step-2&quot;&gt;
&lt;h3&gt;Step 2&lt;/h3&gt;
&lt;p&gt;With our outer function, we create a function call for the inner function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;      _____________________________
-----&amp;gt;|       ____________        |-----&amp;gt;
      | [v]-&amp;gt; |          | -----&amp;gt; |
      |       ------------        |
      -----------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;/section&gt;
&lt;section id=&quot;Step-3&quot;&gt;
&lt;h3&gt;Step 3&lt;/h3&gt;
&lt;p&gt;It is no longer in the state space of the outer function. The inner function takes &lt;strong&gt;ownership&lt;/strong&gt; of it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;      _____________________________
-----&amp;gt;|       ____________        |-----&amp;gt;
      | ----&amp;gt; |   [v]    | -----&amp;gt; |
      |       ------------        |
      -----------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Semantically, for the outer function &lt;code&gt;[v]&lt;/code&gt; was used in the function call and then dropped. Which does not violate our rules. For the inner function, it just got an input and returns an output. So it makes semantic sense.&lt;/p&gt;
&lt;p&gt;In practice, it also makes the same guarantees as any other &lt;strong&gt;pure function&lt;/strong&gt;:
- No null pointers
- No &lt;strong&gt;mutable state&lt;/strong&gt;
- No &lt;strong&gt;side effects&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If the caller &lt;code&gt;.clone()&lt;/code&gt; our value and make a copy of it and pass that to the inner function, it provides us with no other guarantees, other than more memory usage and slightly longer code.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id=&quot;Why-does-it-matter&quot;&gt;
&lt;h2&gt;Why does it matter?&lt;/h2&gt;
&lt;p&gt;Well, honestly, it doesn’t. I just had to decide if in a &lt;strong&gt;pure function&lt;/strong&gt; I can consume a self, if I want to make it a &lt;strong&gt;pure function&lt;/strong&gt;, considering that I cannot make it &lt;strong&gt;const&lt;/strong&gt;. This was my thinking output. Now you are the outer function.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Pure Rust</title><id>urn:uuid:c7710efe-e767-404c-951c-22bb1b0a99ef</id><updated>2025-05-30T15:49:34+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="type-system" label="type-system"/><category term="functional-programming" label="functional-programming"/><category term="programming" label="programming"/><category term="rust" label="rust"/><category term="guide" label="guide"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/pure-rust" rel="alternate" hreflang="en" type="text/html"/><published>2023-03-25T20:06:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">Transforming Rust code into pure functions with immutability, no side effects, and declarative style for clarity and testability.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;If you are not familiar with Functional Programming &lt;abbr title=&quot;Functional Programming&quot; tabindex=&quot;0&quot;&gt;FP&lt;/abbr&gt;, you are in for a ride.
I will try to explain &lt;abbr title=&quot;Functional Programming&quot; tabindex=&quot;0&quot;&gt;FP&lt;/abbr&gt; in more practical terms.&lt;/p&gt;
&lt;section id=&quot;A-definition-to-work-with&quot;&gt;
&lt;h2&gt;A definition to work with&lt;/h2&gt;
&lt;p&gt;&lt;abbr title=&quot;Functional Programming&quot; tabindex=&quot;0&quot;&gt;FP&lt;/abbr&gt; is a declarative way of writing a program that consists mostly of &lt;strong&gt;pure functions&lt;/strong&gt; that operate on and produce &lt;strong&gt;immutable data&lt;/strong&gt;.
That was many other unfamiliar words. Let’s make it concrete.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Making-it-more-concrete&quot;&gt;
&lt;h2&gt;Making it more concrete&lt;/h2&gt;
&lt;p&gt;Here is a function in Rust that we will work on:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; Calling `calculate_my_lateness` seems like magic.&lt;/span&gt;
  &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; We don&amp;#x27;t know how it calculates it, and why it is doing that.&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; status&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; status&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; This sometimes crashes and sometimes, it does not.&lt;/span&gt;
  &lt;span class=&quot;function macro&quot;&gt;assert_eq&lt;/span&gt;&lt;span class=&quot;function macro&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;status&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant builtin&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; The point of this function is to tell us if we are late&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; Ask yourself, how would you write a test for such a function?&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable parameter&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; current_time = std&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;time&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; expected_time = std&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;time&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SOME_SPECIFIED_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

    status = current_time &amp;lt;= date_time&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let’s make it &lt;strong&gt;pure&lt;/strong&gt; and while we are at it, we introduce &lt;strong&gt;pure functions&lt;/strong&gt; and some principles as well.&lt;/p&gt;
&lt;section id=&quot;Pure-functions-return-at-least-one-output&quot;&gt;
&lt;h3&gt;Pure functions return at least one output&lt;/h3&gt;
&lt;p&gt;That means that if you have a function named &lt;code&gt;some_function&lt;/code&gt;, you will have at least one argument &lt;code&gt;some_input&lt;/code&gt; and it will return at least one output &lt;code&gt;some_output&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;some_function&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;some_input&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type&quot;&gt;some_output&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why do we do this? When we are calling a function, we are expecting something to happen.
In &lt;abbr title=&quot;Functional Programming&quot; tabindex=&quot;0&quot;&gt;FP&lt;/abbr&gt; world, the only acceptable &lt;strong&gt;something&lt;/strong&gt; is an output argument.
A lack of output is &lt;strong&gt;symptomatic&lt;/strong&gt; of one of these two unacceptable situations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;strong&gt;Our function does nothing&lt;/strong&gt;&lt;/strong&gt;. In which case, why are we even bothering to write it at all?
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;strong&gt;Our function is doing a side effect&lt;/strong&gt;&lt;/strong&gt;. Which means that it is changing something other than what is inside the function.
These functions don’t let us know or control what they are doing inside, without making us look at the source code.
We will get back to this throughout this post.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Please note the emphasis on &lt;strong&gt;symptomatic&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;So let’s make it return the output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; status&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; output = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; status&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;--^^^^^^------------ we have an output now&lt;/span&gt;

  &lt;span class=&quot;function macro&quot;&gt;assert_eq&lt;/span&gt;&lt;span class=&quot;function macro&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;output&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant builtin&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;---------^^^^^^----- which we use here&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable parameter&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;-notice that we are returning something--^^^^--&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; current_time = std&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;time&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; expected_time = std&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;time&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SOME_SPECIFIED_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

    status = current_time &amp;lt;= date_time&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

    status &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; &amp;lt;- what we are returning&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/section&gt;
&lt;section id=&quot;Pure-functions-dont-mutate-state&quot;&gt;
&lt;h3&gt;Pure functions don’t mutate state&lt;/h3&gt;
&lt;p&gt;As I mentioned before, a function does something when it returns something and changes the state of something outside itself.
We call that a side-effect.
You may have noticed that our function takes a mutable variable of type &lt;code&gt;bool&lt;/code&gt; and changes it.
In our first iteration of the function, we needed it. But now, we grew out of it. So let’s just delete it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; let mut status: bool;  &amp;lt;- we don&amp;#x27;t need this&lt;/span&gt;

  &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; output = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;--------------------------------^ we don&amp;#x27;t need to take status any more&lt;/span&gt;

  &lt;span class=&quot;function macro&quot;&gt;assert_eq&lt;/span&gt;&lt;span class=&quot;function macro&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;output&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant builtin&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;------------------^^- we don&amp;#x27;t need to take a mutable variable&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; current_time = std&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;time&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; expected_time = std&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;time&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SOME_SPECIFIED_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

    current_time &amp;lt;= date_time &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;  &amp;lt;- what we are returning&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now isn’t this better? When I call &lt;code&gt;calculate_my_lateness()&lt;/code&gt;
I’m not worried about the function changing anything it’s not supposed to anymore.
Let’s move on.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Pure-functions-return-output-only-based-on-their-argument&quot;&gt;
&lt;h3&gt;Pure functions return output only based on their argument&lt;/h3&gt;
&lt;p&gt;Which means that when I call &lt;code&gt;calculate_my_lateness()&lt;/code&gt;, I should not expect it to do something different each time I run it.
Why is that? There are two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;strong&gt;Transparency&lt;/strong&gt;&lt;/strong&gt;: You should know what parameters change the output of a function, without needing to reading the function body.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;strong&gt;Testing&lt;/strong&gt;&lt;/strong&gt;: It is hell of a lot easier to test a function that you can just control without needing to change the time of your computer. Won’t you say?
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s do it in two steps this time.&lt;/p&gt;
&lt;section id=&quot;Step-one-Dont-use-global-variables&quot;&gt;
&lt;h4&gt;Step one: Don’t use global variables&lt;/h4&gt;
&lt;p&gt;You may have noticed &lt;code&gt;SOME_SPECIFIED_TIME&lt;/code&gt;.
This is a variable we use to make a &lt;code&gt;SystemTime&lt;/code&gt; which we compare current time with to know if we are late or not.
The problem here is these two:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
We need to write a new function, each time we have a new meeting.
&lt;/li&gt;
&lt;li&gt;
We also don’t know what time current time is being compared to, unless we first read the function, and then find out what it uses as &lt;code&gt;SOME_SPECIFIED_TIME&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; output = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SOME_SPECIFIED_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;---------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-&lt;/span&gt;
  &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; now the caller is supposed to provide the time&lt;/span&gt;

  &lt;span class=&quot;function macro&quot;&gt;assert_eq&lt;/span&gt;&lt;span class=&quot;function macro&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;output&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant builtin&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable parameter&quot;&gt;late_as_of&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;-------------------^^^^^^^^^^^^^^^^^^^^^^-----------&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; current_time = std&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;time&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

    current_time &amp;lt;= late_as_of
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/section&gt;
&lt;section id=&quot;Step-Two-dont-use-functions-with-side-effects-inside-your-function&quot;&gt;
&lt;h4&gt;Step Two: don’t use functions with side effects inside your function&lt;/h4&gt;
&lt;p&gt;Imagine that you have a non-alcoholic drink, if you add another non-alcoholic drink to it, it is still non-alcoholic.
But if you add an alcoholic drink to it, it will not remain non-alcoholic anymore.
A pure function is only pure, if all the functions that are being called in it, are pure.
And &lt;code&gt;std::time::SystemTime::now()&lt;/code&gt; is definitely not pure.
Now, at some point we need to get the current time, but we don’t need to do that where it is hidden from the caller.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; output = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;
                   &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SOME_SPECIFIED_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
                   &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;&amp;lt;------ we provide the time&lt;/span&gt;
  &lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;function macro&quot;&gt;assert_eq&lt;/span&gt;&lt;span class=&quot;function macro&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;output&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant builtin&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable parameter&quot;&gt;late_as_of&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;variable parameter&quot;&gt;target_time&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;-------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^-----------&lt;/span&gt;
    target_time &amp;lt;= late_as_of
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the nice thing here is that we can easily test this function now!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; main and calculate_my_lateness are not shown here. Don&amp;#x27;t be alarmed.&lt;/span&gt;

&lt;span class=&quot;attribute&quot;&gt;#&lt;span class=&quot;punctuation bracket&quot;&gt;[&lt;/span&gt;cfg&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;test&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;mod&lt;/span&gt; tests &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;calculate_my_lateness&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; std&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;time&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;attribute&quot;&gt;#&lt;span class=&quot;punctuation bracket&quot;&gt;[&lt;/span&gt;test&lt;span class=&quot;punctuation bracket&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;being_late_works&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; res = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;A_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;A_TIME_THAT_IS_AFTER_LATE_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;function macro&quot;&gt;assert_eq&lt;/span&gt;&lt;span class=&quot;function macro&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant builtin&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;attribute&quot;&gt;#&lt;span class=&quot;punctuation bracket&quot;&gt;[&lt;/span&gt;test&lt;span class=&quot;punctuation bracket&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;being_early_works&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; res = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;A_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;A_TIME_THAT_IS_BEFORE_LATE_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;function macro&quot;&gt;assert_eq&lt;/span&gt;&lt;span class=&quot;function macro&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant builtin&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Imagine doing this with the first function!&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;One-more-step&quot;&gt;
&lt;h4&gt;One more step&lt;/h4&gt;
&lt;p&gt;OK, I lied… Somewhat. Have you noticed the one glaring, lack of transparency and control here?
It’s the &lt;code&gt;&amp;lt;=&lt;/code&gt;. You may need to read the function here, if you have this simple question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If I call the function exactly, at the precise moment that I specified to be &lt;code&gt;late_as_of&lt;/code&gt;, will return true, or false?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, not answering this question using the function signature,won’t make my function less pure,but still, it is a much nicer experience for the caller to be able to rely on their IDE’s autocomplete to tell them what happens.But how the hell should we do that? Easy! We take a comparator function as input!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; output = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;
                   &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SOME_SPECIFIED_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
                   &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
                   |late&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; target| target &amp;gt; late&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; here the caller passes the function&lt;/span&gt;
                                                 &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; you can also provide a few different functions yourself to make it easier for the caller&lt;/span&gt;
  &lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;function macro&quot;&gt;assert_eq&lt;/span&gt;&lt;span class=&quot;function macro&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;output&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant builtin&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;variable parameter&quot;&gt;late_as_of&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;variable parameter&quot;&gt;target_time&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;variable parameter&quot;&gt;comparer&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; magic happens here&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;function&quot;&gt;comparer&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;late_as_of&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; target_time&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the caller is providing us we have everything we need. We did not hide one single thing.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id=&quot;Isnt-this-just-more-work-for-caller&quot;&gt;
&lt;h3&gt;Isn’t this just more work for caller?&lt;/h3&gt;
&lt;p&gt;Well, yes. Yes, it is… if calling functions without understanding them is the only work that the caller of our function is doing.&lt;/p&gt;
&lt;p&gt;Otherwise, our caller knows everything they need using their language server, can change everything they need, have the assurance of our tests and don’t need to crawl through our source code, and they will face much fewer bugs where they don’t know where it came from.&lt;/p&gt;
&lt;p&gt;It may seem unnecessary for this simple function, but imagine much more complex functions.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id=&quot;Making-things-nicer-A-spicy-problem&quot;&gt;
&lt;h2&gt;Making things nicer: A spicy problem&lt;/h2&gt;
&lt;p&gt;So we have all this power and transparency. But the elephant is in it room: We have a very shitty &lt;abbr title=&quot;Application Programming Interface&quot; tabindex=&quot;0&quot;&gt;API&lt;/abbr&gt;. Let’s make it nicer using a technique called currying (hence the “spicy” pun). What it means is: as well as taking functions as argument, we can return functions. That way, our &lt;code&gt;calculate_my_lateness&lt;/code&gt; function can become a function-maker. Let me make it more concrete.&lt;/p&gt;
&lt;section id=&quot;Consider-the-use-case&quot;&gt;
&lt;h3&gt;Consider the use case&lt;/h3&gt;
&lt;p&gt;Let us suppose that we want to find time in our list of times that is not late.
Currently, we have to call the whole function, repeatedly, and include every argument.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; we are in main, don&amp;#x27;t be alarmed&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; output_time1 = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SOME_SPECIFIED_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;FIRST_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;&amp;lt;------ we provide the time&lt;/span&gt;
    |late&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; target| target &amp;gt; late&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; output_time2 = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SOME_SPECIFIED_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SECOND_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;&amp;lt;------ we provide the time&lt;/span&gt;
    |late&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; target| target &amp;gt; late&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; output_time3 = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SOME_SPECIFIED_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;THIRD_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;&amp;lt;------ we provide the time&lt;/span&gt;
    |late&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; target| target &amp;gt; late&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; etc...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is not great.
Here, We can just make a function that only takes our target time.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;variable parameter&quot;&gt;late_as_of&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; target_time: SystemTime &amp;lt;------------ we don&amp;#x27;t need to take this argument anymore&lt;/span&gt;
    &lt;span class=&quot;variable parameter&quot;&gt;comparer&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable parameter&quot;&gt;late_as_of&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;variable parameter&quot;&gt;target_time&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable parameter&quot;&gt;target_time&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---- notice that we are now returning a function&lt;/span&gt;

    |&lt;span class=&quot;variable parameter&quot;&gt;target_time&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;| -&amp;gt; &lt;span class=&quot;type builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;comparer&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;target_time&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; late_as_of&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;^^^^^^^^^^^^^^^^^^^^^^           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f;         |                this is where the calculation of lateness happens&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; we are taking target time here&lt;/span&gt;
 &lt;span class=&quot;punctuation bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might ask, “well, how does this help?”&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; we are in  main&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; now our late_before_time_x is not of type bool,&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; rather it is of type Fn(SystemTime) -&amp;gt; bool&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; late_before_time_x = &lt;span class=&quot;function&quot;&gt;calculate_my_lateness&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;type&quot;&gt;SystemTime&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SOME_SPECIFIED_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
    |late&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt; target| target &amp;gt; late&lt;span class=&quot;punctuation delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; So we can just:&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; first_result = &lt;span class=&quot;function&quot;&gt;late_before_time_x&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;FIRST_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; second_result = &lt;span class=&quot;function&quot;&gt;late_before_time_x&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;SECOND_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; third_result = &lt;span class=&quot;function&quot;&gt;late_before_time_x&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor&quot;&gt;THIRD_TIME&lt;/span&gt;&lt;span class=&quot;punctuation bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;&amp;#x2f;&amp;#x2f; ...much less boilerplate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/section&gt;
&lt;section id=&quot;Why-const-just-wont-do&quot;&gt;
&lt;h3&gt;Why &lt;code&gt;const&lt;/code&gt; just won’t do&lt;/h3&gt;
&lt;p&gt;Veteran rustaceans among the readers of this blog might ask: “why not just use &lt;code&gt;const&lt;/code&gt; to mark that functions are pure?”
Well dear veteran, if you can make a function &lt;code&gt;const&lt;/code&gt;, do every one a favor and actually do it.
In fact, I regularly use &lt;code&gt;clippy::missing_const_for_fn&lt;/code&gt; lint and suggest you to use it as well.
But that does not guarantee that our functions are pure, or that every pure function can be &lt;code&gt;const&lt;/code&gt;.
Here are my reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;const&lt;/code&gt; functions can take &lt;code&gt;&amp;amp;mut something&lt;/code&gt; as their arguments. Taking mutable references is definitely not very pure-function-y.
&lt;/li&gt;
&lt;li&gt;
You cannot &lt;code&gt;const&lt;/code&gt; trait methods in stable Rust, as of now. And considering that every function call inside a &lt;code&gt;const&lt;/code&gt; function should be &lt;code&gt;const&lt;/code&gt; as well, you are extremely limited, without any reasons that have to do with pure functions.
&lt;/li&gt;
&lt;li&gt;
Many libraries don’t to use &lt;code&gt;const&lt;/code&gt; on the functions that are &lt;code&gt;const&lt;/code&gt;. Again, limitation without pureness reasons.
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id=&quot;Making-things-declarative&quot;&gt;
&lt;h2&gt;Making things declarative&lt;/h2&gt;
&lt;p&gt;There is this often repeated old joke that says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There two hard problems in programming&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Cache invalidation
&lt;/li&gt;
&lt;li&gt;
Naming things
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;– Phil Karlton&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And here we are concerned with the second one.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
In the &lt;strong&gt;&lt;strong&gt;imperative&lt;/strong&gt;&lt;/strong&gt; universe, we usually name our functions using &lt;strong&gt;verbs&lt;/strong&gt;. Think &lt;code&gt;calculate_my_lateness&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
In the &lt;strong&gt;&lt;strong&gt;declarative&lt;/strong&gt;&lt;/strong&gt; universe we are concerned with our output, we use &lt;strong&gt;nouns&lt;/strong&gt;. Think &lt;code&gt;lateness_calculator&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This makes the intent of our function clear.
How it is implemented under-the-hood is not what matters to the caller.
They only care about what they get out of it.
If you now are thinking that you cared about that part before, consider the things that we just can answer by seeing the arguments that our function takes.
We don’t need to rely on our function name anymore to tell use how the function is calculating lateness.
We only need to know what it’s intention is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Reader&quot;&gt;
&lt;h2&gt;Dear Reader&lt;/h2&gt;
&lt;p&gt;In this post, I just preferred to focus on the heart of &lt;abbr title=&quot;Functional Programming&quot; tabindex=&quot;0&quot;&gt;FP&lt;/abbr&gt;: &lt;strong&gt;pure declarative functions&lt;/strong&gt;.
However, functional programming brings with it a set of extremely useful tools, patterns, etc. most well known are &lt;strong&gt;iterators&lt;/strong&gt;, &lt;strong&gt;maps&lt;/strong&gt;, &lt;strong&gt;folds&lt;/strong&gt;, &lt;strong&gt;filters&lt;/strong&gt;, etc.
Honestly, they are well explained in other resources. My only suggestion would be to check out &lt;a href=&quot;https://docs.rs/itertools/latest/itertools/&quot;&gt;itertools&lt;/a&gt; crate.&lt;/p&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Hachyderm or Fosstodon</title><id>urn:uuid:f276bd65-f4e9-4465-a5cd-c1e43cbde74e</id><updated>2025-05-30T16:04:10+02:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="fediverse" label="fediverse"/><category term="opinion" label="opinion"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/hachyderm-or-fosstodon" rel="alternate" hreflang="en" type="text/html"/><published>2022-11-25T19:47:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I go through the trends in hachyderm and fosstodon and make decision about which one I like to be a part of.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Ever since I have moved to the mastodon platform after &lt;strong&gt;the great twitter migration&lt;/strong&gt;, I was curious about two main instances.
One being &lt;a href=&quot;https://fosstodon.org&quot;&gt;Fosstodon&lt;/a&gt;, an instance oriented around &lt;abbr title=&quot;Free and Open Source Software&quot; tabindex=&quot;0&quot;&gt;FOSS&lt;/abbr&gt;, another being &lt;a href=&quot;https://hachyderm.io&quot;&gt;Hachyderm&lt;/a&gt;, an instance that introduces itself as social media for technical professionals.&lt;/p&gt;
&lt;p&gt;Eventually, I decided to go with Fosstodon, as I liked what I was seeing there more.
But I couldn’t put my finger on what it was that I liked more about Fosstodon, even though many of my favorite people resided on Hachyderm, the instance owner of the Hachyderm herself, being one examples.&lt;/p&gt;
&lt;section id=&quot;Initial-Theories&quot;&gt;
&lt;h2&gt;Initial Theories&lt;/h2&gt;
&lt;p&gt;Initially I thought Hachyderm was more business-oriented. It seemed that people on Hachyderm were more interested about talking about broader technologies like &lt;strong&gt;kubernetes&lt;/strong&gt; and &lt;strong&gt;docker&lt;/strong&gt;, while at the same time there was a lot of talk about codes and &lt;strong&gt;programming practices&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I thought maybe all the programmers on Hachyderm are working with more proprietary and enterprise solutions and as such they were less likely to share details of their daily programming.&lt;/p&gt;
&lt;p&gt;But that theory didn’t hold true, as there was as much toots in my timeline on Fosstodon about business related stuff as there was on Hachyderm.&lt;/p&gt;
&lt;p&gt;Until last night that I realized that maybe what I was seeing was the difference of ideas between operations interested people vs people involved in developing software. And as a backend-developer, I could see more relevant content from the development side.&lt;/p&gt;
&lt;p&gt;So I set to examine my assumptions.
Like a good &lt;a href=&quot;https://www.lesswrong.com/tag/bayes-theorem&quot;&gt;Bayesian&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;s-Searches-and-Methods&quot;&gt;
&lt;h2&gt;&lt;abbr title=&quot;Application Programming Interface&quot; tabindex=&quot;0&quot;&gt;API&lt;/abbr&gt;s, Searches and Methods&lt;/h2&gt;
&lt;p&gt;To start with, I looked into different websites that could help me search per-instance results.
That way I could search different keywords in each instance and compare the results.
However I could not find such a thing. Every search engine I tried lacked the ability of filtering by instance.&lt;/p&gt;
&lt;p&gt;After that, I looked into the Mastodon &lt;abbr title=&quot;Application Programming Interface&quot; tabindex=&quot;0&quot;&gt;API&lt;/abbr&gt;s myself.
Long-story short, I found &lt;a href=&quot;https://docs.joinmastodon.org/methods/timelines/#tag&quot;&gt;timeline &lt;abbr title=&quot;Application Programming Interface&quot; tabindex=&quot;0&quot;&gt;API&lt;/abbr&gt;&lt;/a&gt; to be particularly useful:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GET &amp;#x2f;api&amp;#x2f;v1&amp;#x2f;timelines&amp;#x2f;tag&amp;#x2f;:hashtag HTTP&amp;#x2f;1.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using this I could get a list of toots in &lt;abbr title=&quot;Java Script Object Notation&quot; tabindex=&quot;0&quot;&gt;JSON&lt;/abbr&gt; format that had specific hashtags.
And then filter those results to only get the actual &lt;abbr title=&quot;Uniform Resource Locator&quot; tabindex=&quot;0&quot;&gt;URL&lt;/abbr&gt;.
I used &lt;code&gt;curl&lt;/code&gt; to make &lt;abbr title=&quot;Application Programming Interface&quot; tabindex=&quot;0&quot;&gt;API&lt;/abbr&gt; requests and &lt;code&gt;jq&lt;/code&gt; to filter-out the keys I was not interested in.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl &amp;#x27;https:&amp;#x2f;&amp;#x2f;hachyderm.io&amp;#x2f;api&amp;#x2f;v1&amp;#x2f;timelines&amp;#x2f;tag&amp;#x2f;container?&amp;amp;limit=1000&amp;#x27; | jq &amp;#x27;.[].url&amp;#x27; &amp;gt;&amp;gt; hash.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then, I had to filter out results that were not from Hachyderm or Fosstodon. And sort each.
For filtering awk was perfect, and then for sorting the &lt;code&gt;sort&lt;/code&gt; command is good enough.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;awk &amp;#x27;&amp;#x2f;fosstodon|hachyderm&amp;#x2f; {print $0}&amp;#x27; hash.json | sort &amp;gt; res-ops
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I just had to come up with a few keywords that I could associate more with operations and a few for development.&lt;/p&gt;
&lt;div class=&quot;note&quot;&gt;
&lt;p&gt;As you may have noticed, my methodology is hardly scientific and extremely reliant on subjective definitions.
My goal was to find a good-enough-for-my-decision result. Not anything more.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I ended up with these words on different sides:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Operations&lt;/th&gt;
&lt;th&gt;Development&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes&lt;/td&gt;
&lt;td&gt;Refactor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;td&gt;Debugging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;Greenfield&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container&lt;/td&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terraform&lt;/td&gt;
&lt;td&gt;Compiler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy&lt;/td&gt;
&lt;td&gt;Interpreter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Baremetal&lt;/td&gt;
&lt;td&gt;Testing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vm&lt;/td&gt;
&lt;td&gt;Ide&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Admin&lt;/td&gt;
&lt;td&gt;Library&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server&lt;/td&gt;
&lt;td&gt;DesignPatterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;_&lt;/td&gt;
&lt;td&gt;LSP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;_&lt;/td&gt;
&lt;td&gt;NodeJS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;_&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;_&lt;/td&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;The difference in their numbers are not important to us, only the proportions of the results of each may be relevant.&lt;/p&gt;
&lt;div class=&quot;details&quot;&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;The eventual code looks like this.&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!&amp;#x2f;usr&amp;#x2f;bin&amp;#x2f;env bash

# Ops-related keywords
curl &amp;#x27;https:&amp;#x2f;&amp;#x2f;hachyderm.io&amp;#x2f;api&amp;#x2f;v1&amp;#x2f;timelines&amp;#x2f;tag&amp;#x2f;kubernetes?&amp;amp;limit=1000&amp;#x27; | jq &amp;#x27;.[].url&amp;#x27; &amp;gt; hash.json
# ... (additional curl commands)
awk &amp;#x27;&amp;#x2f;fosstodon|hachyderm&amp;#x2f; {print $0}&amp;#x27; hash.json | sort &amp;gt; res-ops
rm hash.json

# Dev-related keywords
curl &amp;#x27;https:&amp;#x2f;&amp;#x2f;hachyderm.io&amp;#x2f;api&amp;#x2f;v1&amp;#x2f;timelines&amp;#x2f;tag&amp;#x2f;develop?&amp;amp;limit=1000&amp;#x27; | jq &amp;#x27;.[].url&amp;#x27; &amp;gt; hash.json
# ... (additional curl commands)
awk &amp;#x27;&amp;#x2f;fosstodon|hachyderm&amp;#x2f; {print $0}&amp;#x27; hash.json | sort &amp;gt; res-develop
rm hash.json
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;The-Result&quot;&gt;
&lt;h2&gt;The Result&lt;/h2&gt;
&lt;p&gt;On the ops query we have &lt;code&gt;32&lt;/code&gt; toots from Fosstodon and &lt;code&gt;44&lt;/code&gt; toots from Hachyderm.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Fosstodon ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
Hachyderm ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far Hachyderm seems to have more activity with Operations related hashtags.
On the other hand it could be that people on Hachyderm are generally more talkative than Fosstodon about every part of the stack.
So let’s hold development as the control.&lt;/p&gt;
&lt;p&gt;On the development queries we have &lt;code&gt;49&lt;/code&gt; results from Fosstodon and &lt;code&gt;24&lt;/code&gt; results from Hachyderm.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Fosstodon ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
Hachyderm ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That seems like a staggering difference. &lt;a id=&quot;fnref1&quot; href=&quot;#fn1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Dear-Reader&quot;&gt;
&lt;h2&gt;Dear Reader&lt;/h2&gt;
&lt;p&gt;I have no idea why this difference is so harsh. But for my purposes I have enough information to update my beliefs to make a decision for now that satisfies my accuracy-requirements for this decision.&lt;/p&gt;
&lt;/section&gt;
&lt;section role=&quot;doc-endnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;
&lt;p&gt;Staggering differences are often a sign of weak research. So take this part with a grain of salt.&lt;a href=&quot;#fnref1&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content></entry><entry><title xml:base="https://theleafslug.com" xml:lang="en">Power Structure of Social Networks</title><id>urn:uuid:4ac2f578-079d-470f-8e36-5dbda5ba9b3f</id><updated>2022-11-15T21:38:00+01:00</updated><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><author><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></author><category term="opinion" label="opinion"/><category term="fediverse" label="fediverse"/><category term="essays" label="essays"/><contributor><name>Perma Alesheikh</name><email>me@prma.dev</email><uri>https://theleafslug.com</uri></contributor><link href="https://theleafslug.com/entries/power-structure-of-social-networks" rel="alternate" hreflang="en" type="text/html"/><published>2022-11-15T21:38:00+01:00</published><summary xml:base="https://theleafslug.com" xml:lang="en">I talk about the structure and centrality of social networks.</summary><content xml:base="https://theleafslug.com" xml:lang="en" type="html">&lt;p&gt;Why do some nations fail and rise so quickly?
The answer to these questions has a surprisingly relevant answer to the recent migrations from a Twitter to Mastodon.&lt;/p&gt;
&lt;section id=&quot;Power-Centrality&quot;&gt;
&lt;h2&gt;Power Centrality&lt;/h2&gt;
&lt;p&gt;Basically the idea is that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
In any system of governance the authority is constrained to the resources it has available.
&lt;/li&gt;
&lt;li&gt;
And for the authority to make a change, it has to answer to the resource providers.
&lt;/li&gt;
&lt;li&gt;
Given a set interdependent institution one could form check-and-balance system.
&lt;/li&gt;
&lt;li&gt;
If the dependence is not formed in a way that is biased towards zero-sum relationships the authority thrives.
&lt;/li&gt;
&lt;li&gt;
For the society to thrive it should be considered an institution on its own.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s make a few different forms of government considering the rules I just discussed.&lt;/p&gt;
&lt;div class=&quot;note&quot;&gt;
&lt;p&gt;As dependence on involvement of people only comes when governments want more power and cannot retain the resources necessary from the land, High Natural-Resources and High People-involvement tend to be mutually exclusive.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;High-Centrality-High-Natural-Resources-Low-People-involvement&quot;&gt;
&lt;h2&gt;High Centrality, High Natural-Resources, Low People-involvement&lt;/h2&gt;
&lt;p&gt;Let’s imagine a dictatorship on a land with rich natural resources. Dictatorship is a strongly centralized form of government. As such, the dictator does not have any dependencies. You might think that the government does need its people. But most of the time, such dictatorship has all that it needs from the naturally available resources.&lt;/p&gt;
&lt;p&gt;The dictator does not have to answer to anyone, and they have all the means necessary to make rapid changes, good or bad. The whole of the nation rise and fall quickly. The civic progression does not accumulate in time and only will be there while the dictator let it be.&lt;/p&gt;
&lt;p&gt;The government does not need people uniting, form a danger to the government. Such authorities are highly motivated to bring social conflict, such as racism. Which may even lead to genocide by members of the society.&lt;/p&gt;
&lt;div class=&quot;example&quot;&gt;
&lt;p&gt;Think of Middle-east with its rich natural oil.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;High-Centrality-Low-Natural-Resources-Low-People-involvement&quot;&gt;
&lt;h2&gt;High Centrality, Low Natural-Resources, Low People-involvement&lt;/h2&gt;
&lt;p&gt;Now, let’s imagine a dictatorship on a land with no natural resources, and no inclination to involve people.&lt;/p&gt;
&lt;p&gt;Such a nation will not flourish. The dictator is extremely constrained in its power.&lt;/p&gt;
&lt;p&gt;It has no validity among its people. As such it is unsuccessful in enforcing any law, good or bad. Such a nation sees lots and lots of &lt;em&gt;coup d’états&lt;/em&gt;. The authority is more alike a warlord.&lt;/p&gt;
&lt;div class=&quot;example&quot;&gt;
&lt;p&gt;Think of Central African nations.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;High-centrality-Low-Natural-Resources-High-People-involvement&quot;&gt;
&lt;h2&gt;High centrality, Low Natural-Resources, High People-involvement&lt;/h2&gt;
&lt;p&gt;Such a dictatorship, is a highly populist government. The dictator threats people as the main form of resource. Such nations can rise quickly. But before too long, the authority will figure out that he only needs society’s approval, but not its growth. And if you need approval, there is no quicker and better way than a common enemy. As such, such nations become too hostile to other nations. And may end-up using genocide as a means of keeping the country united.&lt;/p&gt;
&lt;div class=&quot;example&quot;&gt;
&lt;p&gt;Think of Germany during the Hitler era.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;Low-Centrality-High-Natural-Resources-Low-People-involvement&quot;&gt;
&lt;h2&gt;Low Centrality, High Natural-Resources, Low People-involvement&lt;/h2&gt;
&lt;p&gt;Such a nation looks great from the outside, but inside? It is polarized to say the least. These nations, just like any other nation with Low-Centrality is stable. The is formed by a group of institutions which keep each other in check. But alas, what good is it, if it is not for people?&lt;/p&gt;
&lt;p&gt;Such governments end up becoming extremely rich. But because people are not required for the government to perform, most of what the government is doing is providing value for the few that can provide them the resources they need.&lt;/p&gt;
&lt;p&gt;Such governments nations are subject to low progression in the civic laws, are extremely hard to change, and form strong bonds with few entities. As people are seen as a barrier, government’s like this tend to have a lot of controversial and theatrical surfaces, but end-up deciding things behind closed doors.&lt;/p&gt;
&lt;div class=&quot;example&quot;&gt;
&lt;p&gt;Think of the USA during recent years, as it managed to put a huge people’s involvement.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;Low-Centrality-Low-Natural-Resources-Low-People-involvement&quot;&gt;
&lt;h2&gt;Low Centrality, Low Natural-Resources, Low People-involvement&lt;/h2&gt;
&lt;p&gt;These governments are stable, but irrelevant. They fail to bring order, or protection for their people. And they don’t provide any infrastructural benefits the society.&lt;/p&gt;
&lt;div class=&quot;example&quot;&gt;
&lt;p&gt;Think of Afghanistan Right after the USA army left it.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;Low-Centrality-Low-Natural-Resources-High-People-involvement&quot;&gt;
&lt;h2&gt;Low Centrality, Low Natural-Resources, High People-involvement&lt;/h2&gt;
&lt;p&gt;This, at least for now, seems to be somewhat the better of them all, but with some caveats. These governments are highly stable, and highly motivated by providing value to the people. They accumulate wealth and culture overtime. They are, also, resilient to hostile neighbors and bad actors. These societies tend to look good on the outside, but much better on the inside.&lt;/p&gt;
&lt;p&gt;However, such governments are only weak to adapt to any radical changes, as the changes only happen when the people will it to happen. That means that these societies tend not to be the leaders or experimenters of different sorts of progress. However, they may end up reaching the top of the leader board in time.&lt;/p&gt;
&lt;div class=&quot;example&quot;&gt;
&lt;p&gt;Think of Germany, today.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;How-does-it-relate-to-the-Twitter-and-Fediverse-and…&quot;&gt;
&lt;h2&gt;How does it relate to the Twitter and Fediverse and… ?&lt;/h2&gt;
&lt;p&gt;Well, there is an analogy to be made here.&lt;/p&gt;
&lt;p&gt;We can see the body(s) that runs, maintains, develop and moderate a social network as a form of a government. The users as the people and society.
And the way that the proverbial social-network governments are being funded as the determining factor of people’s involvement in governance.&lt;/p&gt;
&lt;p&gt;In that regard we can think of Twitter, Facebook as highly concentrated. Considering that their power is immensely related to the number of users they have, we may be tempted to see them as somewhat of high in involvement of people.
But in actuality, people do not need to be actually participating in governing such a system. As they are the product, and the value comes from external means. That means that the users ended up being the natural resource of the land that is being sold for resources to the external actors.&lt;/p&gt;
&lt;p&gt;As such we end up with both exploitation of the users and their lack of ownership of their own data.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;So-what-can-be-the-solution&quot;&gt;
&lt;h2&gt;So, what can be the solution?&lt;/h2&gt;
&lt;p&gt;Considering how unfortunate this situation is, there have always been a few different alternatives. Let’s just review them.&lt;/p&gt;
&lt;p&gt;There are systems that don’t count users as product, but as the customer. Such services, though small have a better record of listening to users.&lt;/p&gt;
&lt;p&gt;However, as any centralized system, they are unstable, they remain small, and to keep users, they resort to vendor lock-ins. They also resort advertisement instead of increasing real value. Think of apple with its anti-advertisement campaigns against Microsoft.&lt;/p&gt;
&lt;p&gt;Another solution might be highly centralized systems without any sort of resources. These tend to be highly volatile and fast to disappear.&lt;/p&gt;
&lt;p&gt;So, decentralization might be the way to go.&lt;/p&gt;
&lt;p&gt;As low-centrality but highly-resourcefulness goes, I can only think of mailing groups. Mailing groups stand on the shoulders of mail providers.&lt;/p&gt;
&lt;p&gt;Decentralized as mailing is, the ecosystem overwhelmingly is provided by a few companies that their main products are again, people.
As discussed earlier, such systems tend to not have much progress. At least, not for the non-governing bodies. And indeed, that has been true.
Mailing and mailing groups is as user-friendly and feature-full as they have been 15 years ago.&lt;/p&gt;
&lt;p&gt;Which makes us resort to our last option. Low centrality and High involvement of people. Such a system has been the model for open-source development. Where the governance is highly motivated to help the people the same time as the people are highly motivated to help the governance.
Such a model has ended up being extended into forms of social governance. Where users fund their instances, help development and do volunteer moderation. And indeed, again, the parallel is not surprising: These systems tend not to have the greatest of the starts, but they end up enduring, and becoming more resilient.&lt;/p&gt;
&lt;p&gt;Mastodon, Pixelfed and other federated, open-sourced social networks, operate in such a model. And I like to think of people moving from Twitter to Mastodon as realizing that they matter and can should be more.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Credit&quot;&gt;
&lt;h2&gt;Credit&lt;/h2&gt;
&lt;p&gt;This work is highly inspired and heavily reliant on Daron Acemoglu’s fantastic book, &lt;em&gt;Why Nations Fail&lt;/em&gt;. A must-read.&lt;/p&gt;
&lt;/section&gt;
</content></entry></feed>