<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Slow Coder</title>
    <subtitle>My Name is Sam Vente, and I&#x27;m a data scientist and open source maintainer. Here is where I showcase my work and share my (personal) opinions.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://slowcoder.org/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://slowcoder.org"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-12-29T00:00:00+00:00</updated>
    <id>https://slowcoder.org/atom.xml</id>
    <entry xml:lang="en">
        <title>2025 in Review</title>
        <published>2025-12-29T00:00:00+00:00</published>
        <updated>2025-12-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/2025-in-review/"/>
        <id>https://slowcoder.org/blog/2025-in-review/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/2025-in-review/">&lt;p&gt;2025 has been quite the year, with its own league of ups and downs. I feel like it&#x27;s been a really turbulent year for me personally and professionally, though I won&#x27;t go into either of those here. All of those things have been quite a big drain on my bandwidth to consume and produce media.&lt;&#x2F;p&gt;
&lt;p&gt;Thankfully, 2025 has also been a year with some highlights. I started some really cool projects (most notably, my newsletter and Snakedown), made some amazing progress in others (the blog redesign and Project Lascaux) and in which I found some new all time favourite pieces of media. So as with most years, it&#x27;s a bit of a mixed bag.&lt;&#x2F;p&gt;
&lt;p&gt;As I now finally have a record of some of the things I&#x27;ve been up to in this year I thought it would be fun to have a look at some of the highlights of the past year, both in terms of things I worked on and the media I consumed that really stood out to me. These are not going to be balanced reviews, but rather a victory lap for the things I loved most this year. I&#x27;m going to only touch on each of the entries rather briefly, especially when talking about media I consumed since I talked about all of those in much more detail in their respective news letters. I&#x27;ll link to those in case you&#x27;d like to read more.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;things-consumed&quot;&gt;Things consumed&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;books&quot;&gt;Books&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;man-s-search-for-meaning&quot;&gt;Man&#x27;s search for meaning&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-June-Wrap-up-L4L11HC5XN&quot;&gt;Read in June&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Viktor E. Frankl&#x27;s incredible book about the meaning of life in the face of suffering has been quite well known in some circles. It is both a harrowing description of life in the concentration camps, and an exploration of the philosophy that came out of it which is gone on to spawn an entire branch of psychology called &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Existential_therapy&quot;&gt;Existential therapy&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This book is special to me not just because it spoke to thoughts and anxieties I had, but also because it gave me answers I needed to embark on a few journeys that I&#x27;d been on the fence about for a long time. I&#x27;ve found that this book is very well known in some circles and not at all in others which is always funny to see. I think I&#x27;d recommend this book to anyone, especially if like me, you are prone to existential dread.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;fahrenheit-451-f451&quot;&gt;Fahrenheit 451 (F451)&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-October-Wrap-up-N4N31NR1KR&quot;&gt;read in October&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Fahrenheit 451 doesn&#x27;t need me to sing it&#x27;s praises, and yet I will. As I said when I talked about it in my newsletter, I was quite apprehensive about this book because of it&#x27;s reputation. I am so thankful that that turned out to be unfounded. Fahrenheit 451 is an amazingly written book that is nonetheless easy to follow. It is a poignant and spirited defence of depth and human connection, something that we need in today&#x27;s world more than ever.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-beautiful-decay-tbd&quot;&gt;The Beautiful Decay (TBD)&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-April-Wrap-up-G2G21EJ6X0&quot;&gt;Read in April&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been a fan of Veo Corva&#x27;s writing for a long time now. And by golly, they did it again. The Beautiful Decay is the sequel to their first book Books &amp;amp; Bone. Books &amp;amp; Bone being their first book was much more subdued in terms of queer representation, because at that time they were still trying to traditionally publish if I remember correctly.&lt;&#x2F;p&gt;
&lt;p&gt;Bare with me for a moment, but I&#x27;m glad that they never managed to traditionally publish that book. Because you can clearly see that with every new book they write and self-publish&#x2F;crowdfund they are more and more authentic about their experience, and that sort of things shows (in a good way). I think that had they trad published their first book, we might not have gotten amazing, authentic and open books like TBD.&lt;&#x2F;p&gt;
&lt;p&gt;TBD is a beautiful tale that includes grief, openly queer relationships and characters, good worldbuilding and Corva&#x27;s telltale lovable characters. Corva is agender themselves rather than transfem, but god dammit did they nail the portrayal of a trans feminine character in Persephone.&lt;&#x2F;p&gt;
&lt;p&gt;I genuinely could not put TBD down because of it&#x27;s great characters, open and honest story telling and beautiful portrayal of characters that I can actually identify with, in stark contrast to most mainstream media. I think we need this type of fiction now more than ever, and I wish Corva the best in the future for both our sakes.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sorcery-and-small-magics-sasm&quot;&gt;Sorcery and Small Magics (SASM)&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-October-Wrap-up-N4N31NR1KR&quot;&gt;read in October&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Like TBD, SASM is a queer fantasy novel, and it is just exquisite. It is an absolutely delightful gay romance with some great neurodivergent and trans representation. The characters don&#x27;t explicitly labelled as having ADHD and Autism respectively, and I actually like that, but I will eat my hat if they weren&#x27;t written that way. The writing is beautiful, the characters are three dimensional, side characters have their own wants, desires and agency beyond what they mean to the main characters and the worldbuilding is magnificently well thought out. This is the Doocy&#x27;s first book and it just blows many &quot;veterans&quot; out of the water. I honestly cannot wait what they produce next, or recommend this book highly enough.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;movies-tv&quot;&gt;Movies &amp;amp; TV&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;game-changer-gc-make-some-noise-msn&quot;&gt;Game Changer (GC) &amp;amp; Make Some Noise (MSN)&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-June-Wrap-up-L4L11HC5XN&quot;&gt;Discussed in June&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m lumping GC and MSN into the same section because they are both Dropout.tv shows that I&#x27;ve come to love for very similar reasons this year. Both GC and MSN are very improvisational in nature, and while improv can be somewhat hit or miss usually, I think the folks at dropout somehow manage to knock it out of the park almost every single time.&lt;&#x2F;p&gt;
&lt;p&gt;The conceit of Game Changer is that the rules of the game change every episode. The hose Sam Reich is just incredibly charismatic. I love seeing how he really highlights the contestants on his show and how he clearly tries to help them shine instead of trying to hog the spotlight.&lt;&#x2F;p&gt;
&lt;p&gt;But what really elevates the Dropout shows for me above others, is that they very clearly love and take care of the people on the show. Even though GC has a bit of a reputation for basically being Sam Reich&#x27;s torture play ground, I think it is very obvious that all the fun had on camera is in good nature.&lt;&#x2F;p&gt;
&lt;p&gt;In a world where nothing feels safe to enjoy because any kind of scandal can come out at any time ruining my enjoyment of something, it feels so refreshing to have something where a lot of care and attention gets put not just into the production, but also the people running the production.&lt;&#x2F;p&gt;
&lt;p&gt;Game Changer and Make some Noise have quickly become some of my favourite comfort shows and I hope they continue doing what they are doing for a long time yet.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;12-angry-men&quot;&gt;12 Angry Men&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-May-Wrap-up-B0B61FUZUZ&quot;&gt;Discussed in May&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I am not a film nerd, so I have no idea how well known this film is, but my god, did I love it. TAM is a 1957 black and white film about 12 jurors discussing whether to convict or acquit a boy accused of murder. The film starts out with all but one of them wanting to convict, and since the vote has to be unanimous this turns into much deliberation and rehashing of the evidence.&lt;&#x2F;p&gt;
&lt;p&gt;The film is shot almost (if not entirely) exclusively in 2 rooms: the room where the jurors deliberate and the adjoining lavatories. By today&#x27;s standards it really moves at a snail&#x27;s pace. The shots are much longer, there are much fewer camera angles there are barely if any special effects. All of this puts all of the focus of the movie on the dialogue and it does excellent with that spotlight.&lt;&#x2F;p&gt;
&lt;p&gt;What I love most of all about this movie, is that it convinced me that being old or new isn&#x27;t a good criticism. I think 12 angry men holds up incredibly well even my more modern standards, and I love it for that. It is a piece of timeless cinema I&#x27;d happily recommend to anyone.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;games&quot;&gt;Games&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve played plenty of games this year, however thinking back to them, there were only a few that really stood out to me. There are the odd replays here and there like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.celestegame.com&quot;&gt;Celeste&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.cross-code.com&#x2F;en&#x2F;home&quot;&gt;CrossCode&lt;&#x2F;a&gt;, a few demos here and there, and mechanical bite sized games like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ballxpit.com&quot;&gt;BALL X PIT&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.playbalatro.com&quot;&gt;Balatro&lt;&#x2F;a&gt; for the odd dead moment, but I had honestly forgotten about them until I looked at my steam wrapped for the year. However, there were definitely also some highlights. They were, in no particular order: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blacktabbygames.com&quot;&gt;Slay the Princess (StP)&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.expedition33.com&quot;&gt; Expedition 33 (E33) &lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;baldursgate3.game&quot;&gt;Baldur&#x27;s Gate 3 (BG3)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;slay-the-princess&quot;&gt;Slay the Princess&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-June-Wrap-up-L4L11HC5XN&quot;&gt;Discussed in June&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not usually one for horror, which is why I originally left StP by the wayside when it came out. However, when the YouTuber &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@SulMatul&quot;&gt;SulMatul&lt;&#x2F;a&gt; did a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=WGWHFu6mDE0&quot;&gt;live stream&lt;&#x2F;a&gt; of the game I got completely sucked into the game. In fact I liked it so much that my first ever &lt;a href=&quot;https:&#x2F;&#x2F;slowcoder.org&#x2F;blog&#x2F;slay-the-princess&#x2F;&quot;&gt;atrsy-fartsy media analysis&lt;&#x2F;a&gt; was on that game. The writing of it was just so... dripping with atmosphere (as well as several other icky liquids).&lt;&#x2F;p&gt;
&lt;p&gt;I feel like I&#x27;ve seen most of what StP has to offer for the time being, but I still love it dearly. It is one of those things that I might go back to from time to time when I want writing inspiration. The game is subtle when it wants to be, and gorey and bombastic when it matters. The characters, descriptions and dialogue are written with such a deft touch and the performances are some of the best I&#x27;ve ever seen. I feel like there is so much to learn from. I feel like many people, myself included could find much worse works to draw inspiration from.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;expedition-33&quot;&gt;Expedition 33&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-May-Wrap-up-B0B61FUZUZ&quot;&gt;Discussed in May&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;E33 has certainly been this year&#x27;s darling in terms of gaming, and for good reason. It&#x27;s art and graphics are stunning, the music is so beautiful that it&#x27;s entered my regular rotation for writing music (quite a high bar for me) and the gameplay is an almost flawless execution of the JRPG tropes it chooses to indulge in.&lt;&#x2F;p&gt;
&lt;p&gt;E33 is just damn fun to play. It&#x27;s that kind of rare game with a low floor (you can absolutely drop the difficulty and just bulldoze your way through the game if you don&#x27;t care about the combat), as well as a very high skill ceiling (you can do some truly ridiculous things if you know the right buffs to rub together and learn the parry timings). People have remarked before me that E33 did not invent any of the mechanics it uses, but does execute them nearly flawlessly. I think it is one of the best examples about how originality can come from execution instead of &quot;new ideas&quot; as I discussed in &lt;a href=&quot;https:&#x2F;&#x2F;slowcoder.org&#x2F;blog&#x2F;originality-not-required&#x2F;&quot;&gt;Originality not required&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;But those are all the things that merely make E33 a good game. What truly stets it apart from the rest, is, as it is so often in my opinion, the writing. The writing in E33 is unlike anything we&#x27;ve seen in a game of it&#x27;s magnitude. I honestly can&#x27;t name another piece of audiovisual media that has been this widely enjoyed while at the same time being this open and honest about being &lt;em&gt;emotional&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;E33 tackles themes of grief, death, legacy and family and does all of those expertly and with compassion for it&#x27;s characters from the word go. I especially want to give it props for extending that emotionality to it&#x27;s male protagonists as well. All too often the only emotions male protagonists are allowed to feel on screen are some linear combination of anger and stoic heroism, whereas E33 really lets it&#x27;s characters feel fear, loss, anxiety and grief and gives those emotions the space they deserve.&lt;&#x2F;p&gt;
&lt;p&gt;E33 is one of those games that I think you can best enter knowing nothing about it, so I won&#x27;t go into more detail here, but seriously, it is not cut from the same cloth as many other mainstream pieces of media.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;baldur-s-gate-3&quot;&gt;Baldur&#x27;s Gate 3&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-November-Wrap-up-T6T81PH1BE&quot;&gt;Discussed in November&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This year I finally joined the rest of civilisation and played Baldur&#x27;s Gate 3. I think it took me this long precisely because I expected to love it as much as I did. I have a nasty habit of putting off consuming media I think I&#x27;ll really like because I &quot;want to have the bandwidth to really appreciate it&quot; which often leads to me putting off things I love.&lt;&#x2F;p&gt;
&lt;p&gt;BG3 is something that I knew I&#x27;d love. I&#x27;ve loved similar games in the past from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;larian.com&quot;&gt;Larian Studios&lt;&#x2F;a&gt;, I love a good cRPG, and the praise for BG3 from the start of it&#x27;s release has been quite positive to say the least. For example, this is the game that was so universally loved after it&#x27;s release that a AAA game industry bozo went on twitter to tell the world not to expect this level of quality from other studios. So much for market competition being the driver of quality I guess.&lt;&#x2F;p&gt;
&lt;p&gt;In any case, BG3 is massive. It is the only game I know that I think deserves it 100+ GB install size. It&#x27;s fully voice acted, the writing is deep and varied, the performances are great, and the amount of choices you can make in the game mean that I feel like I&#x27;ve barely scratched the surface with my one playthrough (which clocked in at 70+ hours).&lt;&#x2F;p&gt;
&lt;p&gt;The game is so large that I don&#x27;t feel very qualified to talk about it in more detail, there is just so much stuff there. I waited a long time to go through it, and I wish I hadn&#x27;t. All I can say is well done to Larian, god speed on the next journey, and go play it to anyone that might be vaguely interested in it and hasn&#x27;t yet. It is truly something special.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;things-made&quot;&gt;Things made&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;project-lascaux&quot;&gt;Project Lascaux&lt;&#x2F;h3&gt;
&lt;p&gt;Looking back, I think Project Lascaux (PL) is the thing I worked on the most this year. Sadly, it still isn&#x27;t finished, which means that I still don&#x27;t want to talk about it in too much detail. Like I talked about in my &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-October-Wrap-up-N4N31NR1KR&quot;&gt;October newsletter&lt;&#x2F;a&gt; this year talking in too much detail about creative works in progress tends to kill my motivation somewhat. I realise this is a bit of a pity, but sometimes these are the things that the muses demand of us, and I don&#x27;t want to lose steam so close to the end. I will definitely do a big retrospective on it when it is finished, but you will have to wait until then. If that really bothers you please send any complaints to &lt;a href=&quot;mailto:apollo@olympus.gr&quot;&gt;apollo@olympus.gr&lt;&#x2F;a&gt;, I don&#x27;t make the rules.&lt;&#x2F;p&gt;
&lt;p&gt;That said, PL has seen a tremendous amount of progress this year, as well as evolving in scope some what. I think it is the better for it. I&#x27;m incredibly happy with where it is at right now. PL has been a hard but incredibly rewarding journey. It&#x27;s been the biggest writing project I&#x27;ve undertaken to date, and in that it has helped me grow as a writer. It has also given me the opportunity to work with incredibly talented people, such as editors, translators and artists, and I am so thankful for that privilege.&lt;&#x2F;p&gt;
&lt;p&gt;Even though the creative part of PL is starting to near the finish line, there is still plenty to do and figure out. Unfortunately I am now having to start wading into the boring and tedious parts of creative projects, mostly to do with various kinds of administration, but I&#x27;m trying not to let that deter me. I&#x27;m telling myself that the hard part is already done. That might turn out not to be the case, but I&#x27;m choosing to remain wilfully ignorant on that subject for now to keep my motivation up.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;snakedown&quot;&gt;Snakedown&lt;&#x2F;h3&gt;
&lt;p&gt;Snakedown, for those who might need a reminder, is the python API documentation tool I&#x27;m building so that I can use zola to build my Python documentation because I get very frustrated with the current solutions. The idea is that almost all documentation hosted online is just a static website and that modern static site generators like Zola (which I also use to host this site) have a much better user experience than for example Sphinx. However, one of the major reasons I can&#x27;t use Zola for hosting my documentation is that it doesn&#x27;t do API docs generation, which is quite important for software documentation.&lt;&#x2F;p&gt;
&lt;p&gt;So the idea currently for snakedown is to use the rust based Python Parser used by for example &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;astral-sh&#x2F;ruff&quot;&gt;ruff&lt;&#x2F;a&gt; to be able to parse the Python code and generate the API docs in a format that Zola can work with. From there you should just be able to use Zola (at least, that&#x27;s the idea!)&lt;&#x2F;p&gt;
&lt;p&gt;I started this back June of this year, and I&#x27;m honestly quite pleased with the state it&#x27;s in after just 6 months. It is a hobby project that I have to work on in my free time, so the progress is a bit stop and start. In the time that I&#x27;ve been sitting on the idea there have been months that I haven&#x27;t been able to work on it. That&#x27;s just kinda how it goes with small open source projects like this.&lt;&#x2F;p&gt;
&lt;p&gt;I originally thought that doing the parsing would be the most difficult but so far that&#x27;s actually not been the case. Even though the API can be a bit gnarly (mostly because of how Python is defined) but once I was able to wrap my head around that I was able to work with it all fairly efficiently.&lt;&#x2F;p&gt;
&lt;p&gt;Things like doing the linking so far, have been harder, because I have to do more original work. Finding a good way to store the data in a way that makes everything accessible when the engine needs it. Originally I tried to keep everything in the same structure as the package we were parsing, but I realised that that would add so much complexity in terms of being able to find things when rendering and verifying links that I decided to backpedal on that.&lt;&#x2F;p&gt;
&lt;p&gt;Instead I&#x27;ve moved towards a more flat structure of just giving each individual object it&#x27;s own page and path so that searching for things becomes much easier. This is actually how Sphinx (the thing I&#x27;m trying to replace) also does things and I guess now I know why! That just goes to show again that even if you&#x27;re trying to build &quot;A better X&quot; it&#x27;s still useful and important to learn from the things that X does. There may be reasons for why it does things the way it does than you were aware of!&lt;&#x2F;p&gt;
&lt;p&gt;I wouldn&#x27;t call it really ready for use yet, as the internal linking doesn&#x27;t work yet, (although we&#x27;re getting pretty close!) and I definitely want to make a usable theme for zola to go with it. As I like to say, make sure to nail the basics first!&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve also started to really appreciate using snakedown as a playground for dev practices. At work, under the pressure of deadlines, it&#x27;s easy to let best practices fall by the wayside, especially if you&#x27;re working with colleagues that disagree what the best practices should look like.&lt;&#x2F;p&gt;
&lt;p&gt;As I&#x27;m starting to become more and more senior in my career, people are starting to look towards me more and more for opinions on the right way to do things. It can be hard to remember what things are supposed to look like and what the pros and cons of a particular way or working is especially under the pressure of said deadlines and colleagues.&lt;&#x2F;p&gt;
&lt;p&gt;I must say I&#x27;ve been surprised by how much I&#x27;ve started to appreciate this way of working. I know that working with others will always require a degree of compromise, and that&#x27;s fine, but there is also a very particular pleasure in being able to work the way you like it, and experiment with different ways of doing things. I&#x27;d say it&#x27;s somewhat similar to the pros and cons of living by yourself. You get to do everything the way you like it, but on the flip side, if you don&#x27;t do it, then it doesn&#x27;t happen.&lt;&#x2F;p&gt;
&lt;p&gt;Snakedown has helped me grow as a maintainer I think, and I&#x27;m quite happy with that, whether I get to a usable product or not. Of course I hope so, because it is a project I started because I wanted to solve a particular problem, and I hope it will, but even just as a learning project I&#x27;ve very much enjoyed it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;this-blog&quot;&gt;This blog&lt;&#x2F;h3&gt;
&lt;p&gt;This blog has been a little neglected over the past few years. Even though it wasn&#x27;t quite the nearly-year-long hiatus that 2024 was, I still only wrote one blog post: the &lt;a href=&quot;https:&#x2F;&#x2F;slowcoder.org&#x2F;blog&#x2F;slay-the-princess&#x2F;&quot;&gt;Slay the Princess&lt;&#x2F;a&gt; post. While I do still really like that post, it is a bit of a shame that the blog hasn&#x27;t seen that much action.&lt;&#x2F;p&gt;
&lt;p&gt;This has various reasons. One one being that 2025 was simply a very chaotic year for me, both personally and professionally. It pulled me in many different directions at times, leaving me with limited bandwidth overall. I don&#x27;t really think this is avoidable while I have my day job to contend with, and that isn&#x27;t changing any time soon.&lt;&#x2F;p&gt;
&lt;p&gt;What is a genuine achievement in that regard is that I haven&#x27;t started resenting the blog yet. That might sound like a silly thing to call an achievement, but as someone that has a real tendency to invent stress and pressure out of thin air, that&#x27;s always a danger lurking around the corner with projects like this. It means that I&#x27;ve been able to give myself enough space to not get stressed about writing for the blog. WHile it does mean that the blog might not see updates as often as I&#x27;d like, it does mean that the blog will continue to keep existing, so in the long run, it&#x27;s definitely a plus point!&lt;&#x2F;p&gt;
&lt;p&gt;Another reason that the blog has not seen many updates is that I&#x27;ve just felt very burnt out on the stuff I usually talk about here: tech, work, advice, etc. etc. I&#x27;ve had many frustrations at work both technical and non-technical and I don&#x27;t find that to be a good headspace for writing. I don&#x27;t want to write blogs here in anger, because while it might feel good at the moment, its never something I&#x27;m happy with looking back.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, (and this has been the case both at and off work) the state of AI and tech at the moment is the most exhausting I have ever experienced it, which is really saying something. I just so resent the way that &quot;AI&quot; taints absolutely everything at the moment, more than undoing pretty much all the advances we&#x27;ve collectively made in the last few decades to combat climate challenge, and all for no tangible benefit besides soothing the C-suite&#x27;s FOMO. I don&#x27;t want to turn this into an AI rant post, so I&#x27;ll leave it at that, but this really has put a damper on my motivation to write about anything tech adjacent.&lt;&#x2F;p&gt;
&lt;p&gt;This is probably at least part of why I turned to other topics to write about, like media and my newsletter (which I&#x27;ll talk about in the next section). I&#x27;m not sure where I&#x27;ll focus my efforts going forward with the blog. Perhaps after this whole AI shitstorm dies down a little bit and I finish other projects I&#x27;ll get back to the regular kind of content. I do definitely intend to return to the blog more consistently at some point.&lt;&#x2F;p&gt;
&lt;p&gt;The final reason that I&#x27;ve also been working very hard this year on other projects, such a Project Lascaux and Snakedown, and I only have so much creative energy. It&#x27;s easy to forget (at least for me), but time and energy aren&#x27;t the only limited resource that go into making something like this. I like having multiple projects to work on, so that I can pick and choose a bit what to work on as my fancy strikes me, even if it means that the individual projects progress slower.&lt;&#x2F;p&gt;
&lt;p&gt;The upside of it being something independent that I don&#x27;t earn money on, is that I can just leave it until the fancy strikes me again. My interest in things always comes in waves so I&#x27;m sure there will be something again in the future that will make me come back. Hopefully you&#x27;re looking forward to that as much as I am.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-media-newsletter&quot;&gt;The media newsletter&lt;&#x2F;h3&gt;
&lt;p&gt;In case you didn&#x27;t know yet, this year I started a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;post&#x2F;2025-December-Wrap-up-G2G21R38H7&quot;&gt;monthly newsletter&lt;&#x2F;a&gt; on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;slowcoder&quot;&gt;my Ko-Fi page&lt;&#x2F;a&gt;, where I talk about all the media I&#x27;ve consumed (mostly books, games, movies and TV shows), as well as some of the projects I&#x27;ve been working on. It is also free and available for anyone, so you don&#x27;t have to donate to read it ;)&lt;&#x2F;p&gt;
&lt;p&gt;I must say that I&#x27;ve come to love it much more than I originally expected. Usually I really struggle to keep a consistent schedule with stuff like this, and once a month certainly isn&#x27;t high output compared to some full time content creators, but I&#x27;ve found it to be about the most that is sustainable for me.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;d personally rather think twice and speak once, which means that I often struggle to keep a consistent output. I&#x27;d rather just say nothing if I&#x27;m not sure, instead of just running my mouth, and that means that the blog output can be sparse. Even when I&#x27;ve already figured out my stance, it can still be a lot of work to polish it to the degree that I&#x27;m happy to put it out there. The newsletter has been a nice break from that attitude without having to abandon it completely.&lt;&#x2F;p&gt;
&lt;p&gt;I am also surprised at how much I&#x27;ve come to enjoy media analysis and criticism over all. Sometimes when I talk about this letter I joke about how much I hated doing book reports while I was in school, while now I&#x27;m basically doing them just for fun.&lt;&#x2F;p&gt;
&lt;p&gt;It has also really enhanced my enjoyment of the media that I consume. I think that in a similar way that photography used to help me appreciate the beauty in the everyday environments around me, doing this newsletter has given me an incentive to pay much closer attention to the media I interact with. Trying to articulate what I do and don&#x27;t like about something has helped me cultivate much more of my aesthetic taste as well.&lt;&#x2F;p&gt;
&lt;p&gt;Just as with photography, I don&#x27;t have any aspirations of becoming a very serious critic that people need to pay attention to, but I do really enjoy doing it for its own sake. It&#x27;s an opportunity to slow down, which, if you hadn&#x27;t noticed from the title of the blog yet, I think is quite a good thing.&lt;&#x2F;p&gt;
&lt;p&gt;Speaking of the blog, I think in a certain way the newsletter is quite similar to the blog in that I just do it for myself. Of course I &lt;em&gt;want&lt;&#x2F;em&gt; other people to read and enjoy it, but I&#x27;m taking it at my own pace, and doing in a way that I enjoy, and that is the most important.&lt;&#x2F;p&gt;
&lt;p&gt;And that&#x27;s it! 2025 has been one hell of a year, and while it did have some good highlights, I&#x27;m personally glad to see it go. I&#x27;m hoping that 2026 will be a bit calmer for all of us. For myself in particular I&#x27;d love to use that calm to focus on finishing (and probably starting) projects. Here&#x27;s to a creative and fulfilling 2026!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Zola.nvim</title>
        <published>2025-07-18T00:00:00+00:00</published>
        <updated>2025-07-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/projects/zola-nvim/"/>
        <id>https://slowcoder.org/projects/zola-nvim/</id>
        
        <content type="html" xml:base="https://slowcoder.org/projects/zola-nvim/">&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;savente93&#x2F;zola.nvim&quot;&gt;Zola.nvim&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; is a Neovim plugin to build, serve, check, and create content for your &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.getzola.org&#x2F;&quot;&gt;Zola&lt;&#x2F;a&gt; static sites without ever leaving Neovim.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sparkles-why-zola-nvim&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#sparkles-why-zola-nvim&quot;
   aria-label=&quot;Anchor link for: sparkles-why-zola-nvim&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
✨ Why Zola.nvim?&lt;&#x2F;h3&gt;
&lt;p&gt;I build most of my personal sites and documentation with Zola, and constantly switching between the terminal and Neovim to run commands disrupted my flow. With &lt;code&gt;zola.nvim&lt;&#x2F;code&gt;, I can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;🛠 &lt;strong&gt;Build&lt;&#x2F;strong&gt;, &lt;strong&gt;serve&lt;&#x2F;strong&gt;, and &lt;strong&gt;check&lt;&#x2F;strong&gt; my Zola sites directly from Neovim with some simple keybindings&lt;&#x2F;li&gt;
&lt;li&gt;📝 &lt;strong&gt;Scaffold new pages and sections&lt;&#x2F;strong&gt; with sensible TOML front matter by default&lt;&#x2F;li&gt;
&lt;li&gt;🔧 Configure options per command for a streamlined, focused workflow&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;zap-features-at-a-glance&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#zap-features-at-a-glance&quot;
   aria-label=&quot;Anchor link for: zap-features-at-a-glance&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
⚡️ Features at a glance&lt;&#x2F;h3&gt;
&lt;p&gt;✅ User commands: &lt;code&gt;:ZolaBuild&lt;&#x2F;code&gt;, &lt;code&gt;:ZolaServe&lt;&#x2F;code&gt;, &lt;code&gt;:ZolaCheck&lt;&#x2F;code&gt;, &lt;code&gt;:ZolaCreatePage&lt;&#x2F;code&gt;, &lt;code&gt;:ZolaCreateSection&lt;&#x2F;code&gt;
✅ Full Lua API for advanced workflows
✅ Dynamic content creation with &lt;code&gt;vim.ui.input()&lt;&#x2F;code&gt; integration
✅ No default keymaps to keep your Neovim lean and fast&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rocket-get-started&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#rocket-get-started&quot;
   aria-label=&quot;Anchor link for: rocket-get-started&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
🚀 Get Started&lt;&#x2F;h3&gt;
&lt;p&gt;Install with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;folke&#x2F;lazy.nvim&quot;&gt;lazy.nvim&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lua&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;savente93&#x2F;zola.nvim&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;dependencies &lt;&#x2F;span&gt;&lt;span&gt;= { &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;nvim-lua&#x2F;plenary.nvim&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; },
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;config &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;zola&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;setup&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;bulb-example-create-a-new-blog-post-instantly&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#bulb-example-create-a-new-blog-post-instantly&quot;
   aria-label=&quot;Anchor link for: bulb-example-create-a-new-blog-post-instantly&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
💡 Example: Create a new blog post instantly&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;lua&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;vim&lt;&#x2F;span&gt;&lt;span&gt;.keymap.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;set&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;lt;leader&amp;gt;znp&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;vim&lt;&#x2F;span&gt;&lt;span&gt;.ui.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;({ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;prompt &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Enter page slug: &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; }, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span&gt;(result)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;zola&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;create_page&lt;&#x2F;span&gt;&lt;span&gt;({
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;slug &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;blog&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; .. &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;result&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;page_is_dir &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;draft &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;open &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;true
&lt;&#x2F;span&gt;&lt;span&gt;    })
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;end&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;end&lt;&#x2F;span&gt;&lt;span&gt;, { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;desc &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Create a new blog post&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; })
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Check out the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;savente93&#x2F;zola.nvim&quot;&gt;GitHub repo&lt;&#x2F;a&gt; for installation and usage details.
I’d love to hear your feedback and ideas for future improvements! (if you&#x27;re curious, yes, this post was in fact made using &lt;code&gt;Zola.nvim&lt;&#x2F;code&gt;!)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Reading Slay the Princess: the Child, the Fascist and the Woman</title>
        <published>2025-06-30T00:00:00+00:00</published>
        <updated>2025-06-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/slay-the-princess/"/>
        <id>https://slowcoder.org/blog/slay-the-princess/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/slay-the-princess/">&lt;h2 id=&quot;prologue&quot;&gt;Prologue&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;div class=&quot;dialogue-line &quot;&gt;
    &lt;div class=&quot;script-slug-line&quot;&gt;INT. THEATRE - EVENING&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;br &#x2F;&gt;


&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;action&quot;&gt;A spotlight shines on the stage, curtains down. DIRECTOR enters stage right, dressed in black tie. A polite applause emerges from the audience.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            DIRECTOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Welcome dear members of the audience. The performance you are about to watch is something truly special, if I do say so myself. It is unlike any other piece that has graced the stage of our fine platform, and because of that I thought it appropriate to give you some context before we get started. Rather than the technical or philosophical forum that you have become accustomed to; tonight&#x27;s performance is an artistic work of narrative analysis.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;
&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;action&quot;&gt;Audience murmurs&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;


&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            DIRECTOR
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Now, now, don&#x27;t you worry. Plenty of the high quality content you are used to from us will always be present. Tonight is just a little experiment if you will. I have always found the arts to be just as important to keep the mind nimble as the sciences, as I&#x27;m sure you&#x27;ll agree. Slay the Princess is a psychological horror visual novel with &lt;em&gt;many&lt;&#x2F;em&gt; thematic layers to it. It has a lot to say about the nature of trust and relationships, which is why most narrative explorations of it, have focused on those aspects. Tonight, however, we hope to give you three novel perspectives on the game.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            DIRECTOR
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        &lt;div class=&quot;parenthetical&quot;&gt;(Nervously looks around the audience)&lt;&#x2F;div&gt;
        &lt;div class=&quot;dialogue&quot;&gt;It is vital to know that tonight&#x27;s analysis will rest very firmly on the so called &#x27;death of the author&#x27;. As I&#x27;m sure you&#x27;re well aware, this simply means that we disregard any intentions the original authors may have had—or, more critically in our case, not had. Most notably, when we discuss the nature of fascist rhetoric, it is important to remember, that none of this is aimed at the original authors, as my lawyer has made me promise to remind you.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;action&quot;&gt;He wrings his hands nervously, though the larger-than-life smile never leaves his face.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            DIRECTOR
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Just like the game, our exploration is of a certain cyclical nature. It aims to explore situations in a myriad of ways to &#x27;gain many perspectives&#x27;. For the purposes we will pull material from all over the game. As such one could reasonably argue that there are many &#x27;spoilers&#x27; in tonight&#x27;s performance. However, I feel they are all placed in a sufficiently different context that they actually reveal very little about what can happen in the game—or how it can happen. Of course, it is up to you, to decide whether you are comfortable with that.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;
&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;action&quot;&gt;He claps his hands, visibly pleased to be done with this part&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;


&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            DIRECTOR
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;With all that out of the way, we can finally start tonight&#x27;s performance. Thank you for joining us, and I really hope you enjoy, this rendition of Reading Slay the Princess: the Child, the Fascist, and the Woman.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            FADE OUT
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;act-1-the-child&quot;&gt;Act 1: The Child&lt;&#x2F;h2&gt;
&lt;p&gt;Slay the Princess is a 2023 horror adventure game developed and published by Black Tabby Games. It is a visual novel that plays heavily with themes of archetypes, and meta-narratives. One of the most prominent characters in the game is The Narrator, who not only narrates the actions you take and the world around you, but with whom you argue, and who gives and reminds you the titular task of the game: that you are here, to slay a princess. The game has a beautiful monochrome hand-drawn art style that is incredibly versatile, and lends itself excellently to all the different styles you might encounter, and the excellent music and voice acting really bring the game to life.&lt;&#x2F;p&gt;
&lt;p&gt;However, at its heart, Slay the Princess is a story about being a child in a world of adults. Though it is very much a game about adults, and is not in any way suited for children, Slay the Princess is a game where you are treated as if you were a child. The stakes and consequences are kept deliberately vague, and you soon get the idea that everyone involved is very uninterested in your understanding and agency within this story. Instead, they seem much more concerned with how to manipulate you to fit their goals. This begins early on with The Narrator. If you question him about &lt;em&gt;why&lt;&#x2F;em&gt; you&#x27;re to slay the princess, he quickly becomes evasive. Look how his responses are phrased:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Don&#x27;t linger on the specifics. You have a job to do here. Just get in there and do what needs to be done. We&#x27;re all counting on you.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;There is no explanation given, no reasoning, he just appeals to authority and character.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;If you don&#x27;t slay the princess, the world will end. This is an immutable truth, you&#x27;ll just have to trust me on this.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;In the parlance of rhetorics, the Narrator is operating purely on &lt;em&gt;Ethos&lt;&#x2F;em&gt; at this point in the story. He is trying to position himself as a knowledgeable and trustworthy individual. Critically, however, he does so without providing any justification for that trust. He operates on a sort of ivory-tower model, portraying very much to us that there &lt;em&gt;are&lt;&#x2F;em&gt; good reasons for making us do this, but that they would be too complicated to explain. Only he knows what is best for us. He is not interested in what we want, despite being self-convinced he knows what we should want. In other words: a parental figure.&lt;&#x2F;p&gt;
&lt;p&gt;Phrases like these evoke the curious feelings of being a child asking questions about why the world is the way that it is, and the corresponding feelings of being met with annoyance and dismissal. It reminds me very much of conversations that myself and many others have had as children:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            CHILD
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Why do we have to go to school?&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PARENT
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;To learn how the world works.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            CHILD
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;But I am not learning anything there!&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PARENT
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;You still have to go.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            CHILD
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;But why then?&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PARENT
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;You&#x27;ll understand when you are older.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;When these sorts of conversations inevitably fail to persuade us, we move into the &lt;em&gt;Pathos&lt;&#x2F;em&gt; mode of arguing, or appeals to emotion. Suddenly the world isn&#x27;t just incomprehensible, but it is &lt;em&gt;dangerous&lt;&#x2F;em&gt;. Best not talk to anyone, best not stray from your path or terrible things will befall you. If we forgo the instructions of the narrator to bring a blade with us to exert violence on the princess, who is indeed, chained up in the basement of some forlorn cabin, we are chastised by him.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;You&#x27;re only making this more difficult. You&#x27;re making a huge mistake&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;He tries to impress upon us, in no uncertain terms, the danger we are in.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Don&#x27;t let the princess fool you, it is all part of the manipulation. You&#x27;re playing a dangerous game by coming here unarmed.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;If we progress further without doing as he says, his scolding becomes even more intense over time.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;This would have been so much easier if you&#x27;d have just taken the blade like you were supposed to&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            VOICE OF THE HERO
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Easier &lt;em&gt;for whom?&lt;&#x2F;em&gt;&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Easier &lt;em&gt;for everyone&lt;&#x2F;em&gt;. Look at the mess you&#x27;re in.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Going further forward, the scolding turns into vague threats of the future.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;You won&#x27;t like what happens if you do that...&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Ultimately no matter how much appeals to authority or emotion the narrator makes, not once does he use any logical explanation to try to convince us. In other words, the one thing he refuses to do is to provide context and detail, and then trust us to make the right decision ourselves. In simpler terms, he refuses to respect our agency.&lt;&#x2F;p&gt;
&lt;p&gt;Become disobedient enough, and he even takes matters into his own hands:&lt;&#x2F;p&gt;
&lt;p&gt;
&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;No. We won&#x27;t have any of that. The stakes are too high. You can&#x27;t just let her escape into the world. No. I can&#x27;t just let her escape into the world.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;


&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;As the princess approaches the bottom stair, your body steps forward and raises the blade&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            VOICE OF THE HERO
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Wait... this isn&#x27;t fair. You can&#x27;t just do that!&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Watch me.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;This eventually turns into:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Stop it! Stop trying to resist me! I&#x27;m trying to get you out of here alive!&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;The princess is not much better in this regard, though, perhaps less so of her own volition. If we choose to engage her in conversation, something expressly discouraged by the narrator, she is often similarly evasive on her intentions, refusing to tell us more about herself:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;You can address me as &#x27;your royal highness&#x27;. Or you can just call me &#x27;princess&#x27; if &#x27;your royal highness&#x27; is too formal.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;action&quot;&gt;Pause&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;I&#x27;m sorry, I&#x27;ve been down here so long I guess I&#x27;ve just forgotten. I must have a name though! Everyone has a name.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;She even argues with us in a similar ethos-based mode as the narrator:&lt;&#x2F;p&gt;
&lt;p&gt;
&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;What I&#x27;d do if I got out of here doesn&#x27;t really matter right? At the end of the day, whatever the two of us have going on down here is about trust. Whoever sent you to slay me claimed I was a threat to the world, but they didn&#x27;t tell you why. I don&#x27;t trust that, and I don&#x27;t think you do either, or you wouldn&#x27;t have come down here to talk. So this shouldn&#x27;t be about what I&#x27;d do if I got out of here, or me saying the right thing to convince you to save me.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;


&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;action&quot;&gt;Pause&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;


&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;So I could tell you that I&#x27;d lead a quiet life in the woods, or that I&#x27;d open an orphanage, or that I&#x27;d do any other number of &#x27;good&#x27; things that I&#x27;m sure I think you want to hear. But you don&#x27;t really know me, do you? What can my word possibly be worth in a situation like this? Like I said, it&#x27;s all about trust, blind trust.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;However, regardless of whether we invest more in the Narrator or in the Princess, our choices are always framed by either of their individual wants. At times, it feels like the Princess and the Narrator are almost having an indirect conversation with each other, mediated through the player. This is a deeply uncomfortable situation to be in. You know that you will ultimately have to make a decision on what to do, and yet both sides of the conflict are very open about the fact that they are withholding information from you. A situation very familiar to any child that remembers being caught between two authority figures with conflicting information, such as that between a teacher and a parent perhaps?&lt;&#x2F;p&gt;
&lt;p&gt;This evokes many unpleasant memories of being caught in the crossfire of two adults, debating the path forward for you to follow, and the feeling that you will inevitably have to disappoint one of them, no matter what you do. All this leads to feeling like you don&#x27;t really have a good way to resolve the tension between the two. It is a masterful dance that the game executes very well, and, as is all too often the situation, both as a child and as an adult there are no perfect ways out of a bad situation. You were put here in this place by external forces, and you must find a way out. Despite your best efforts there are very few things you can do that will not end this tale of you with the words&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Everything goes dark, and you die.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;act-2-the-fascist&quot;&gt;Act 2: The Fascist&lt;&#x2F;h2&gt;
&lt;p&gt;Slay the Princess is a 2023 horror adventure game developed and published by Black Tabby Games. It is a visual novel that plays heavily with themes of archetypes, and meta-narratives. One of the most prominent characters in the game is The Narrator, who not only narrates the actions you take and the world around you, but with whom you argue, and who gives and reminds you the titular task of the game: that you are here, to slay a princess. The game has a beautiful monochrome hand-drawn art style that is incredibly versatile, and lends itself excellently to all the different styles you might encounter, and the excellent music and voice acting really bring the game to life.&lt;&#x2F;p&gt;
&lt;p&gt;At its heart, however, Slay the Princess is a story about violent fascist whispering in your ear who will stop at nothing to get you to impose his will on the world through violence.&lt;&#x2F;p&gt;
&lt;p&gt;The Narrator of the game is very insistent and consistent on his view of the world: if you don&#x27;t slay the princess, the world will end. How or why, is left conveniently vague. It is repeatedly, and unconvincingly conveyed to us:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;If you don&#x27;t slay the princess, the world will end. This is an immutable truth, you&#x27;ll just have to trust me on this.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;What exactly does the narrator mean with this &quot;end of the world&quot;? Well, somehow he manages to answer that, too, in the least helpful way possible:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;I&#x27;m talking about the end of everything as we know it. No more birds, no more trees, and perhaps most problematically of all, no more people. You have to put an end to her.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Before we even meet the Princess the narrator is sure to impress upon us the danger of listening to her at all:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;But a word of warning- if you go in prepared to hear her out, she could easily trap you in her web of lies. And the more you listen to her honeyed words, the harder it&#x27;ll be to pull yourself out.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;We are told that having any kind of dialogue with &quot;the enemy&quot;, which, let&#x27;s reiterate, at this point, we have never seen or met, much less have had any reason to believe would mean us harm. This is putting us directly onto the path towards destruction. This all reeks of propaganda and dogma designed to scare us into hateful actions &lt;em&gt;before&lt;&#x2F;em&gt; we can discover that the other side is a lot more human, and thus, perhaps deserving of empathy.  It is explicitly told to us that it is better if we don&#x27;t know too much:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;I&#x27;ve told you everything you need to know. Going into more detail would just overcomplicate things and make an otherwise simple job more difficult. The less you know about her, the better.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;This very much evokes the dehumanisation of oppressed groups by fascist regimes. In his forward to psychologist and Holocaust survivor Viktor Frankl&#x27;s book &quot;Yes to life&quot;, Psychologist Daniel Goleman describes this very dynamic:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;[Ervin] Staub [another survivor of the Nazis] studied cruelty and hatred, and he found one of the roots of such evil to be the turning away, choosing not to see or know, of bystanders. That not-knowing was read by perpetrators as a tacit approval. But if instead witnesses spoke up in protest of evil, Staub saw, it made such acts more difficult for the evildoers.&lt;&#x2F;p&gt;
&lt;p&gt;For Frankl, the &quot;not-knowing&quot; he encountered in postwar Vienna was regarding the Nazi death camps scattered throughout that short-lived empire, and the obliviousness of Viennese citizens to the fate of their own neighbours who were imprisoned and died in those camps. The underlying motive for not-knowing, he points out, is to escape any sense of responsibility or guilt for those crimes. People in general, he saw, had been encouraged by their authoritarian rulers not to know—a fact of life today as well.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Similarly, we are always told that knowing more will only be a liability:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;A warning before you go any further...&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;She will lie, she will cheat, and she will do everything in her power to stop you from slaying her. Don&#x27;t believe a word she says.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;As if trying to avoid being slain is somehow a dark and sinister conspiracy instead of simple self-preservation.&lt;&#x2F;p&gt;
&lt;p&gt;How exactly she will come to end the world is &lt;em&gt;again&lt;&#x2F;em&gt; left similarly vague:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;She just can. Believe me, I wish I could tell you more, but you&#x27;ll just have to trust that what I&#x27;m saying is true and that, despite it all, you&#x27;re fully up to the task that&#x27;s been given to you&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, even listening to our own perceptions or trusting our own intuitions is framed as dangerous:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;But slaying the princess and saving the world is going to be much more difficult than it has to be if you&#x27;re going to spend all this time second guessing yourself.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Of course, all the justifications are incredibly vapid if not outright absent. The narrator even goes as far as telling us to not consider morals in the same breath as he is making a moral assertion himself:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Oh don&#x27;t you start grandstanding about morals. The fate of the world is at risk right now, and the life of a mere Princess shouldn&#x27;t stop you from saving us all.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;The narrator is essentially giving us a version of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Trolley_problem&quot;&gt;Trolley Problem&lt;&#x2F;a&gt;. Though he isn&#x27;t saying it out loud, his implication is that it would be &lt;em&gt;better&lt;&#x2F;em&gt; for us to Slay the Princess than let all other life die (if we accept his premise), which is a moral assertion.&lt;&#x2F;p&gt;
&lt;p&gt;This derealization and encouragement of believing dogma over one&#x27;s own deductive reasoning is a popular rhetoric tool in the induction of cults. A fact that makes this hit home even harder.&lt;&#x2F;p&gt;
&lt;p&gt;Any attempt at empathy or humanisation of &quot;the enemy&quot; is met with scorn.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            VOICE OF THE HERO
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Look how reasonable she&#x27;s being, let&#x27;s just drop the blade and talk this out.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Don&#x27;t you dare.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;And similarly:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;I don&#x27;t know what you&#x27;re hoping to accomplish here, but I can assure you there&#x27;s no reasoning with yer.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;He even frames the Princess as being as manipulative as himself:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Did they tell you &lt;em&gt;how&lt;&#x2F;em&gt; I&#x27;m supposed to end the world?&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;She knows what she&#x27;d do. She&#x27;s just searching for whatever answers she thinks you want to hear.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Eventually, the narrator starts telling us we are &quot;the chosen one&quot;, the only that can save the world from certain doom:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Look, I&#x27;m not supposed to tell you this, but it&#x27;s because you&#x27;re special. You&#x27;re the &lt;em&gt;only&lt;&#x2F;em&gt; person capable of doing this. Call it a prophecy of sorts if that helps, but it is just the way things are.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;This is very reminiscent of the siren call that fascism has been transmitting since its inception. Portraying one&#x27;s own people as &quot;the chosen people&quot; by whatever power a regime wants to appeal to is a well-trodden path for authoritarians. From the Nazi ideal of the Aryan to the contemporary idea of &quot;the great replacement&quot;, we can see that this narrative is alive and well on the very day that I write this.&lt;&#x2F;p&gt;
&lt;p&gt;The story has been and always will be the same according to the narrator: the world is about to end, and this conveniently underrepresented group of people is going to cause it if they are not stopped at all cost, preferably with violence. No matter how downtrodden and oppressed they are, such as being chained to the wall of an abandoned cabin in the middle of the woods, they are still dangerous to the world as we know it.&lt;&#x2F;p&gt;
&lt;p&gt;Not just that, but it isn&#x27;t merely their actions that are deemed dangerous, but their very existence that poses a threat to all that we hold dear.&lt;&#x2F;p&gt;
&lt;p&gt;This is even mentioned explicitly by the narrator If we later argue with him that she doesn&#x27;t seem particularly motivated to end the world, or even sure how to do it.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;She doesn&#x27;t have to know how to destroy the world to be capable of doing it.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;What exactly makes these people so dangerous is left deliberately vague, because it is &quot;plain for all to see.&quot; (again, according to him). It is clear that the narrator will accept nothing but violence being exerted on the princess. As he envisions it, only her total annihilation is acceptable to the world order.&lt;&#x2F;p&gt;
&lt;p&gt;Regardless of how much we try to empathise with the princess, the narrator is always there, whispering in our ear about the possible dangers. Which, often expressly through the consequences of the narrators meddling, always end with the words:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Everything goes dark, and you die.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;act-3-the-woman&quot;&gt;Act 3: The Woman&lt;&#x2F;h2&gt;
&lt;p&gt;Slay the Princess is a 2023 horror adventure game developed and published by Black Tabby Games. It is a visual novel that plays heavily with themes of archetypes, and meta-narratives. One of the most prominent characters in the game is The Narrator, who not only narrates the actions you take and the world around you, but with whom you argue, and who gives and reminds you the titular task of the game: that you are here, to slay a princess. The game has a beautiful monochrome hand-drawn art style that is incredibly versatile, and lends itself excellently to all the different styles you might encounter, and the excellent music and voice acting really bring the game to life.&lt;&#x2F;p&gt;
&lt;p&gt;You awaken to the game in a situation that is all too familiar for many trans women. You are in a nondescript place and are told to do something that makes no sense to you. Who tells you these things? The world itself around you, here personified by a literal Narrator. This Narrator tells you that somewhere, tucked away deeply in the crevices of some damp and forsaken place is a woman that you must slay, and if you don&#x27;t, it will mean the end of the world.&lt;&#x2F;p&gt;
&lt;p&gt;Why any of this is the way that it is seems very illogical to you, but you don&#x27;t remember the rest of your life being any different. In fact, thinking about it, you remember very little of your life before this point at all. It is all just a gray blur of meaningless actions. You don&#x27;t have goals so much as you just go places and do things. But most importantly, you know that it is dangerous to listen to your own intuition and senses. They are easily mislead by &quot;honeyed words&quot; and can lead to dangerous outcomes.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;But a word of warning- if you go in prepared to hear her out, she could easily trap you in her web of lies. And the more you listen to her honeyed words, the harder it&#x27;ll be to pull yourself out.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Like you have done so many times before, you steel your resolve and go to the cabin, to do what you are supposed to, to fulfil your destiny, to do what the world asks of you, to &lt;em&gt;be&lt;&#x2F;em&gt; what the world asks you to be. But throughout all of this there is something that gnaws at the back of your mind, that this is somehow wrong. You have been instructed not to heed these thoughts, but you can&#x27;t help it, they will not leave you alone.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            VOICE OF THE HERO
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;We&#x27;re not going to go through with this, right? She&#x27;s a princess. We&#x27;re supposed to save princesses, not slay them.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Ignore him, he doesn&#x27;t know what he&#x27;s talking about.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;You can feel that you are connected to this woman in some way, though exactly how is unclear to you. Even before you lay eyes on her, it becomes clear that there is something special about her:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;H-Hello? Is someone there?&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            VOICE OF THE HERO
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;It&#x27;s hypnotising. It&#x27;s the kind of voice you only have to hear once to remember the rest of your life.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;But the world does not want for you to recognise in her an ally:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Don&#x27;t let her voice fool you. It&#x27;s all part of the manipulation. You&#x27;re playing a dangerous game by coming here unarmed.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Something about all of this feels off to you, in more way than one. Why does the narrator have so much hatred towards the princess?  When you engage her in conversation you discover that she has been chained up and stuffed in a damp and dark basement for so long that she no longer remembers the outside world:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Is that why they threw me down there? But I don&#x27;t want to hurt anyone. I like the world!&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;action&quot;&gt;Pause&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;I think...&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;action&quot;&gt;Pause&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;I don&#x27;t remember much about it to be honest. I&#x27;ve been down there for so long.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;You talk to her. Slowly you come to realise that this woman is part of you. It is the part of you that was taken from you at your birth: your femininity. Ripped from you by the world. Though you long to be reunited with her, trust returns as slowly as the roots of an uprooted tree take to regrow.&lt;&#x2F;p&gt;
&lt;p&gt;Was it really the world that imprisoned her here? Or was it you yourself? Has the voice of hatred seeped into your very soul over time? Perhaps it was the world that taught you to hate her yes, but you wonder if it was not still by your hand that she ended up there.&lt;&#x2F;p&gt;
&lt;p&gt;In return, she has also resorted to desperate deeds from time to time. This cycle of bitterness and struggles for control serve neither of you, and breaking it demands great bravery from you both.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;I... I want to trust you. But you&#x27;re hiding something, aren&#x27;t you? Why would you help me if you weren&#x27;t helping yourself?&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PLAYER
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;You&#x27;re not the only one who yearns for freedom. I&#x27;m as trapped as you are. I think we need to leave together.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;that sounds... nice. I&#x27;m so tired of the bad blood between us. But it&#x27;s hard to let it go. You&#x27;ve hurt me... and I&#x27;ve hurt you...&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;The willingness to heal together doesn&#x27;t always come easy. Old habits have to be unlearnt, and old expectations have to be ignored until they leave by themselves,&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;She flinches again as the last of the vines is cut away, as if, after all of that, she&#x27;s still expecting you to turn on her and stab her in the heart.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Along the way there are also painful realisations to be made about yourself.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PLAYER
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;So what do I look like?&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Scary. It&#x27;s... hard to describe. It&#x27;s hard to look at you.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Though the work is slow and gruelling at times, with time comes understanding,&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;I don&#x27;t know why you did what you did, but it&#x27;s hard to be mad when you&#x27;re just as stuck as I am&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;And eventually with understanding comes healing.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PLAYER
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;You&#x27;re different. Your whole mood is different.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;I&#x27;m just trying to make the best of things.... You could always make the best of things too, if you want. We both have a chance to start over. Besides, there&#x27;s something about you being here with me that feels... Right. I never wanted to be your enemy.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;All the while the narrator is loathed to witness what is happening between you two:&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;you&#x27;d do best to remember that some wounds will never heal. Some rifts can never be mended. Even in rebirth, some things never come back the same&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;he tries again and again to regain his hold on you, his whisperings turning into darker and darker growls as time limps forward&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            NARRATOR
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;You aren&#x27;t whole. You&#x27;ll never be whole again. This struggle is meaningless. Whatever you think you&#x27;re doing, you will fall apart.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;But he is wrong. Dead wrong. Rather than fall apart you grow ever closer together. You begin to find in her a loyal confidant&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;That&#x27;s because you aren&#x27;t small, even if you act that way. We&#x27;re both so much more together than we were apart. And we can be so much more still. Vast. Unfathomable.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;As you begin to trust her, yourself, you realise that all that you have internalised is not you.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PLAYER
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;I&#x27;m sick of this guy, how do we get rid of him?&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;We push back. It may feel like he&#x27;s everywhere, but presence isn&#x27;t strength. Otherwise, we would have torn us apart by now. There must be a crack in the walls of his prison. There must be a way for us to be free from him.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;It becomes hard to describe your being, and yet, it feels right. Nobody is owed justification for your being.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;Does it matter what we call ourselves? It&#x27;s just another label, and I don&#x27;t think labels have ever helped us. All they do is cram us into boxes where we don&#x27;t fit&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;As you are able to fight back the narrator&#x27;s influence more and more with each passing moment, realisations about your past, present and future bring you their gifts again: first understanding, then healing.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PLAYER
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;None of this was ever really fair for either of us, was it?&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;No. It really wasn&#x27;t. But just because it hasn&#x27;t been fair doesn&#x27;t mean that it hasn&#x27;t been worth it. I&#x27;m... really glad I got to know you.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Until you are finally ready to show the world your true self.&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;This is it, I have no idea what it&#x27;s going to be like out there. Not that I&#x27;m scared or anything. It&#x27;s exciting, really. Anything could happen. And if it&#x27;s bad then&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;action&quot;&gt;She hesitates&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            PRINCESS
            (CONT&#x27;D)
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;It won&#x27;t be bad. Not with you.&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;

&lt;p&gt;
    &lt;div class=&quot;dialogue-line &quot;&gt;
        &lt;div class=&quot;speaker&quot;&gt;
            FADE OUT
            
        &lt;&#x2F;div&gt;
        
        &lt;div class=&quot;dialogue&quot;&gt;&lt;&#x2F;div&gt;
    &lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Dotfiles</title>
        <published>2025-02-18T00:00:00+00:00</published>
        <updated>2025-02-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/projects/dotfiles/"/>
        <id>https://slowcoder.org/projects/dotfiles/</id>
        
        <content type="html" xml:base="https://slowcoder.org/projects/dotfiles/">&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;savente93&#x2F;dotfiles&quot;&gt;Repository&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I maintain quite a lot of configuration files to keep my system working exactly as I want. This repository means that I can do my work almost anywhere I like (it doesn&#x27;t quite work on windows yet, much to my shegrin)&lt;&#x2F;p&gt;
&lt;p&gt;I also keep some scripts here that I use, to for example setup a new computer with from scratch. I tinker quite a lot, which means that I sometimes break things. When that happens I don&#x27;t want to spend ages having to setup my system again the way I like it so I wrote some scripts for it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Weather is here, wish you were fine</title>
        <published>2025-01-20T00:00:00+00:00</published>
        <updated>2025-01-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/weather-is-here/"/>
        <id>https://slowcoder.org/blog/weather-is-here/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/weather-is-here/">&lt;p&gt;Hi folks! This is a quick status update to catch you up on what’s been going on, why I’ve been quiet, and—most importantly—to assure you the blog isn’t dead. I realise my last post was all the way back in... MARCH OF LAST YEAR? wow, that&#x27;s even worse than I thought.&lt;&#x2F;p&gt;
&lt;p&gt;The biggest thing is that I moved to a new apartment. Moving is consistently rated as one of the most stressful events in a human life, and yet, somehow, everytime I think I can do it better. Well, turns out I can&#x27;t. The new apartment I moved to needed a LOT of work, such as replacing all the power sockets and heating system, which is why it took about an entire year from my offer to moving in. For the year or so that this move was going on, it consumed most of my time energy and money, which meant I just didn&#x27;t have the bandwidth required for hobbies like blogging.&lt;&#x2F;p&gt;
&lt;p&gt;Thankfully I&#x27;ve well and truly moved in now. Except for stuff like hanging pictures on the walls, it&#x27;s all done, which means that I&#x27;ll hopefully have more time to keep this show on the road going forward. I&#x27;ve never been one of those &quot;never missed an upload day in 10 years&quot; kind of people, even at the best of times. I&#x27;m more Hbomberguy and less Linus Tech Tips if you will. So I won&#x27;t make promises, but I do have some ideas of things I want to talk about so, life permitting, hopefully I&#x27;ll be posting again sometime in the future.&lt;&#x2F;p&gt;
&lt;p&gt;I also realised that the majority of my blog posts are capital B-Big Ideas: deep dives into big, complex topics that can be very insightful, but also take a long time to polish. While I don&#x27;t think those posts will ever go away, I also thought that it might be nice to have some more smaller content, that I can produce a bit more frequently. Things like how I use a few scripts to set up a new computer in minutes, (something I’ve refined over years of trial and error), to the editor &amp;amp; other tools I use, some of my open source contributions, maybe slight life updates, stuff like that.&lt;&#x2F;p&gt;
&lt;p&gt;Speaking of producing content, another reason why I haven&#x27;t taken the time to blog in a while, is that I&#x27;ve been working on an other, much bigger writing project. This project, if I manage to get it across the finish line, will be the biggest one writing wise I&#x27;ll have done with some margin. I don&#x27;t want to spoil what it is yet, but it&#x27;s quite a different beast to my usual work and in a medium I&#x27;ve never attempted before, which is as exciting as it is nerve-wrecking to me. Let&#x27;s just say, watch this space...&lt;&#x2F;p&gt;
&lt;p&gt;By now, you also may have noticed that the website has a new lick of paint. One of the coolest bits is the new logo. I worked with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;samthedesigner.com&quot;&gt;Samuel Darbouze&lt;&#x2F;a&gt;, (and by &quot;worked with&quot; I mean &quot;I gave him some vague instructions, some money, and then he did all the work for me&quot; but who&#x27;s keeping track, right?) to create it and I&#x27;m incredibly happy with it! Not just because, let&#x27;s be honest, it looks stunning, but also because Samuel was a joy to work with. He was very helpful in guiding me through the process, so if you ever find yourself in need of some pretty shapes, I would highly recommend his services. (Samuel didn’t ask for this shoutout—it’s just a personal recommendation)&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, I&#x27;m also going to do something new: mention the Ko-Fi page I have. I&#x27;ve actually had it for a long time, but I never actually mentioned it, or done much with it before. Ko-Fi, for the uninitiated, is a website where you can tip someone directly. It&#x27;s the proverbial cap on the ground in front of a street musician.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;ve been around for a while, you might recall that I blogged &lt;a href=&quot;https:&#x2F;&#x2F;slowcoder.org&#x2F;blog&#x2F;why-no-interactions&#x2F;&quot;&gt;in the past&lt;&#x2F;a&gt; about why there are no interactables on this website such as comments. I still stand by what I wrote in that post. However, I have also come to accept that does leave some people without a good way to keep up with the blog. So I&#x27;m going to be announcing blog posts there as well as monthly updates about the stuff I&#x27;ve been reading, writing and coding for free. So if you want a way to keep up with me, and RSS doesn&#x27;t gel with you for whatever reason you can follow me there. And hey, if you like what I do, and want to get me a coffee as a thank you, then you can!&lt;&#x2F;p&gt;
&lt;p&gt;All my work is publicly available, ad-free, tracker-free, and popup-free, and I want to keep it that way. However, the move and larger trends have done a number on my financial situation, making it just that bit harder to keep this blog and other hobby projects going. So if you enjoy what I do and want to help me keep it open and skeezy free, consider throwing me a tip! It will help me pay for hosting this website, feed my never ending hunger for books that inspire me to talk about interesting topics, get me an actual coffee while I&#x27;m writing, and keep my motivation high.&lt;&#x2F;p&gt;
&lt;p&gt;For those that want a little extra, I&#x27;ll be trying to flesh it out more over the coming weeks, but I&#x27;m still very much working out how I want to run it, so if there are things you would like to see I would love to hear about it!&lt;&#x2F;p&gt;
&lt;p&gt;Moving was a huge challenge, but now that it&#x27;s behind me I&#x27;m excited to come back to blogging. Thanks for sticking around and I&#x27;ll see you soon (hopefully before march of next year this time).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cite me bro</title>
        <published>2024-06-02T00:00:00+00:00</published>
        <updated>2024-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/projects/cite-me-bro/"/>
        <id>https://slowcoder.org/projects/cite-me-bro/</id>
        
        <content type="html" xml:base="https://slowcoder.org/projects/cite-me-bro/">&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;savente93&#x2F;cite-me-bro&quot;&gt;GitHub&lt;&#x2F;a&gt; • &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;cite-me-bro&quot;&gt;Crates.io&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Cite me bro is a cli-tool to output formatted citations based on your bibtex files over stdout, or expanding them in text files directly. This is mainly developed for putting citations in code, or whenever you just need to grab a citation from your bib file quickly for example to use in a presentation. No modifications to your bib file necessary. It does not support arbitrary tex commands, but should work with most bib files.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#example&quot;
   aria-label=&quot;Anchor link for: example&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Example&lt;&#x2F;h3&gt;
&lt;p&gt;you can call the tool like so&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cmb -b&lt;&#x2F;span&gt;&lt;span&gt; cite.bib&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --style&lt;&#x2F;span&gt;&lt;span&gt; ieee breiman2001
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which should produce the following output:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;L. Breiman, &amp;quot;Random forests,&amp;quot; Machine learning, vol. 45, no. 1, pp. 5-32, 2001. doi: https:&#x2F;&#x2F;doi.org&#x2F;10.1023&#x2F;a:1010933404324.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Web business card</title>
        <published>2024-06-02T00:00:00+00:00</published>
        <updated>2024-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/projects/web-business-card/"/>
        <id>https://slowcoder.org/projects/web-business-card/</id>
        
        <content type="html" xml:base="https://slowcoder.org/projects/web-business-card/">&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;savente93&#x2F;web-resume&quot;&gt;Repository&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This was a website I built to get a bit more proficient with my web development. It&#x27;s written in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;svelte.dev&quot;&gt;Svelte&lt;&#x2F;a&gt; which I really quite enjoyed, and sports a couple of features that I&#x27;m quite proud of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;interactive graphs (written in raw svg)&lt;&#x2F;li&gt;
&lt;li&gt;Fully translated, with both English and Dutch versions&lt;&#x2F;li&gt;
&lt;li&gt;multiple themes (dark, light, high-contrast)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And, if I do say so myself, it looks quite pretty. I had a lot of fun making the graphs by hand, which I think also helped flex my visualisation muscles a bit.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>3 and a half frustratingly difficult career tips</title>
        <published>2024-03-02T00:00:00+00:00</published>
        <updated>2024-03-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/three-career-tips/"/>
        <id>https://slowcoder.org/blog/three-career-tips/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/three-career-tips/">&lt;p&gt;I&#x27;ve been thinking a lot about careers lately. Or at least I was when I first thought of this blog post. More specifically, I’ve been thinking about how I&#x27;ve got to where I am and where I would like to go. Looking back over my career, there are definitely a few common themes I never did intentionally but have helped shape my career a lot.&lt;&#x2F;p&gt;
&lt;p&gt;You might be curious about why I titled this post the way I did. The reason is that the things I&#x27;m about to tell you are intentionally vague and difficult. They are the things that would have made me mad with frustration as a kid if my parents had told me about them. The reason they are this way is that I think you should never give specific instructions in unclear situations. I don&#x27;t know what your life is like, and therefore anything concrete I would have to say here would be worthless at best and a wild goose chase at worst. Instead of making it seem like this is a roadmap you could just follow, I&#x27;ve opted to describe to you how a compass works, how to make it and how to use it. However, where you would like to go once you have it will be up to you.&lt;&#x2F;p&gt;
&lt;p&gt;As a supplemental material, I’ve provided a short list of media pieces that have helped me to come to understand these things in the end. I encourage you to use both this list and this post as an orchard. Wander through it, reach out, take what appeals to you and leave the rest.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-learn-to-research&quot;&gt;1. Learn to research&lt;&#x2F;h2&gt;
&lt;p&gt;I have often told colleagues &quot;I would rather hire someone who knows how to learn than someone who knows exactly the thing I’m interested in.&quot;. This might sound weird, but I believe in it very firmly. It&#x27;s why I would hire a physicist, a philosophy major, or even a successful journalist as a software developer. Someone like that? I&#x27;ll teach them how to code, no problem. Someone who can code but doesn&#x27;t know how to investigate? That&#x27;s much harder to work with if you ask me.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t care where you are in your career or which field you are in, if you’re a knowledge worker, you&#x27;re always going to have to keep learning to stay relevant. There&#x27;s always something new to understand, whether it&#x27;s a new tool, practice, framework, language. This is something that will always keep showing up and it is by far the most useful skill I&#x27;ve learned during my maths degree. The confidence that comes with versatility and resilience is hard to overestimate.&lt;&#x2F;p&gt;
&lt;p&gt;By &quot;learn to research&quot; I mean more than just, &quot;know how to look stuff up efficiently&quot;. Although that in itself is already a tremendous advantage. Whenever I teach someone about the basics of coding, I encourage them not to fuss too much over syntax and learning APIs by heart. Experienced coders (myself included) get that wrong all the time. It also doesn’t help that those change faster than the weather in British autumn. You can look that up, no problem. Researching is about being able to apply that information in a relevant situation. It will be rare that what you find is going to be &lt;em&gt;exactly&lt;&#x2F;em&gt; what you need. You&#x27;re always going to have to cherry-pick and edit a little bit and that&#x27;s the crucial part of the skill.&lt;&#x2F;p&gt;
&lt;p&gt;You don’t even have to keep all of it in your brain, either. In school, if you ask someone else to do something for you, that’s called cheating. When you’ve got a job, it’s called delegation. As a professional, if you know very little yourself, but you know the person to go to for every question, you are still doing your job correctly. Where the information comes from doesn’t matter, as long as you know where to find it.&lt;&#x2F;p&gt;
&lt;p&gt;Being able to research also means not being intimidated (or at least paralysed) by unfamiliar theory or material. Everything looks impossible for the first time around. Being able to engage with complex material, piece by piece, and structure information so you can understand it is the name of the game.&lt;&#x2F;p&gt;
&lt;p&gt;The reason I can&#x27;t give you more specific information about how to study effectively is that you are the only one who can say what that is. I don&#x27;t care how you study or research. What is important is that it makes sense to you. Wanna get a subscription to brilliant.org? Go for it. Prefer YouTube tutorials? I&#x27;m with you. Work better with a book and some time on your own? Perfect. Prefer to jump in straight and learn as you go? Amazing. Want to find someone more experienced and ask them questions? Fantastic.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, know that learning how to research means learning how to communicate. As I’ve discussed, how you gather the information doesn&#x27;t matter. What does matter is how you present it. For work as it exists today, if you cannot communicate your knowledge to other people, it might as well not be there.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-learn-to-do-things-that-suck&quot;&gt;2. Learn to do things that suck&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s be honest, doing anything, no matter how amazing it is, is going to involve doing things that suck. Any task, let alone work, in modern life, has at least some drudgery built into it, so I hope you can see why being able to do things that suck is a competitive advantage.&lt;&#x2F;p&gt;
&lt;p&gt;Destin from the YouTube channel Smarter Every Day gives an interesting example of this. He says that the way he tries to gain trust in unknown groups is by asking what the job is that everybody hates doing the most and then doing that. While you should be careful that doesn&#x27;t become your defining feature. If people learn they can dump the shitty work on you without consequences they will. However, I think it&#x27;s a tremendous way to ingratiate yourself with people. Being willing to do the dirty work is a rare quality (and let’s be honest, for good reason). That means if you can do it, it will often make you stand out (as long as you don’t do it where nobody can see it, but that’s a conversation for a different time).&lt;&#x2F;p&gt;
&lt;p&gt;But it goes much further than that in my experience. Very often, with things that suck, it&#x27;s actually our anticipation or reaction to the thing that sucks way more than the thing itself. This is a concept known in Buddhist philosophy as “the second arrow”. As someone who struggled a lot with anxiety and depression throughout my life, I feel intimately aware of this. Because it&#x27;s the expectation that is the worst part. In my experience, when you do the sucky thing more and more often, it gets a little easier every time. Not necessarily better, but easier.&lt;&#x2F;p&gt;
&lt;p&gt;Being able to do things you hate is a skill you can learn. I&#x27;m far from qualified to talk about this subject, but as a little guidepost, I will talk about two things that have helped me hone that skill. They are meditation, and taking cold showers, both of which I still hate doing.&lt;&#x2F;p&gt;
&lt;p&gt;Meditation has helped me foster a bit of detachment, which feels like a bit of a protective layer between me and the terrible emotion, if you will. In a way, meditation felt like practising dealing with sucky emotions. This made it easier to overcome them when they came attached to doing something I hate. It also helps remind me that those emotions pass eventually, cliche though it might be.&lt;&#x2F;p&gt;
&lt;p&gt;Then there are cold showers. Yes, really. The reason I think the cold showers helped is that they suck so much. No, I&#x27;m not gonna tell you about how I&#x27;ve come to like them or whatever. It is undeniably something that sucks, and that&#x27;s why it works as practice. The one upside to it is that, besides being accessible, it&#x27;s easy to start and stop on a dime. Few things that suck come in doses small enough to make them an effective training exercise.&lt;&#x2F;p&gt;
&lt;p&gt;Another thing that I have found with doing things that suck is that starting is much harder than continuing or finishing. Take, for example, running, which many people would agree sucks. Including me when I first started with it. I would make a deal with myself. All I had to do was put on the clothes and step outside the door. That&#x27;s it. If I stepped one foot outside the door and wanted to turn around and go back, I could. Nine times out of ten, when I stood outside in my running clothes, I&#x27;d think, &quot;eh, fuck it, I&#x27;m here now anyway, might as well do the thing&quot;&lt;&#x2F;p&gt;
&lt;p&gt;The crux of all this is that if you can learn to not be too afraid of negative emotions, a bunch of options become available to you. It&#x27;s kinda liberating, and it has helped me in my career more than I think I know how to put into words.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2b-learn-to-find-your-joy&quot;&gt;2b. Learn to find your joy&lt;&#x2F;h3&gt;
&lt;p&gt;Now, some of you might assume after reading the previous part that I&#x27;ve stuck with the things like meditation and cold showers. To that I say: I wish! But I didn&#x27;t. I pick them up now and then and every time I do; they are a little easier to come back to, but I don&#x27;t maintain them as habits throughout my life.&lt;&#x2F;p&gt;
&lt;p&gt;The reason is that they take a lot of effort. I just don&#x27;t always have the bandwidth to do things like that. Especially when other things are tough, it&#x27;s unrealistic to expect yourself to do those things independently of what goes on in the rest of your life.&lt;&#x2F;p&gt;
&lt;p&gt;I think that the step to managing things like these is to make sure you have a healthy balance between hard and fun things. Consider a financial analogue. Perhaps you&#x27;ve heard of the concept of a &quot;loss leader&quot;. The idea is to actually sell something so cheap that you make a loss on it, but that sale then leads to enough sales on higher-margin products to make up for it. An example of these would be gaming consoles, which are often sold at a loss. The subsequent sales of games then more than make up for that. This is an effective strategy, but you can only do that if you make enough money in other ways to weather the initial hit. If you don&#x27;t, you&#x27;re gonna go out of business.&lt;&#x2F;p&gt;
&lt;p&gt;This is how I see work and motivation. Any work you do is going to involve things that suck. Probably quite a lot of them. These will be your loss leaders. The question then becomes, what are the other things you can do to make up for the loss you make on them? This is what I call &quot;finding your joy&quot;, and I think it&#x27;s essential for a sustainable career.&lt;&#x2F;p&gt;
&lt;p&gt;In most work situations I&#x27;ve been in, there have been at least some things that I could do that energised me. Examples include hackathons, personal projects, social time with colleagues, and attending or giving lectures. Whatever you&#x27;re interested in, doesn&#x27;t matter whether it&#x27;s part of your job description or not. In fact, it might even help if it isn&#x27;t. I won&#x27;t say that this is available to everyone, but I will say that it was available to me in a lot of jobs where you wouldn&#x27;t have expected it. So it might be worth looking around wherever you are.&lt;&#x2F;p&gt;
&lt;p&gt;This is also where I&#x27;ll have to issue a small warning to you. Because often rather than seeing these kinds of activities as enabling productivity, the powers that be usually see them as “rewards&quot;. This means that you&#x27;re only allowed to engage in them after you&#x27;ve finished all your other tasks like a good little kid. I find this incredibly frustrating and short-sighted, but it is what it is. At least, there are ways to at least mitigate it.&lt;&#x2F;p&gt;
&lt;p&gt;One of those is just not being very vocal about the fact that you&#x27;re doing them. Not that you have to lie, but it helps to not be too obvious about what you are doing, and especially how much time you&#x27;re spending on it. This is true  regardless of how high your other workload is. For whatever reason, managers don&#x27;t actually measure the time you spend on these things against how well you still do your other tasks. Rather, they measure how much time they see you spend on it compared to how much time they feel you should spend on it.&lt;&#x2F;p&gt;
&lt;p&gt;Another helpful strategy is to keep some of these joy tasks squirrelled away for when you need them. When you&#x27;re down in a slump, an easy or exciting task can really help pull you out of it. Sometimes, it&#x27;s better to pause what you&#x27;re &quot;supposed to be doing&quot; and do something that brings you happiness, even if it&#x27;s not as important. If you wait to do what brings you joy until your other work is done, you will never do it.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, I think it&#x27;s also important to note that you don&#x27;t have to find joy in your actual work. If you have a hobby that can do this for you, I say go for it. There is nothing wrong with work just being working and you finding your fulfilment outside in your own life. However, it means that you&#x27;ll have to engage in them enough to get that energy outside of work hours. Something which I have yet to figure out how to do, but I thought it at least worth mentioning.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;3-employers-are-not-your-friends-and-that-s-okay&quot;&gt;3. Employers are not your friends (and that&#x27;s okay)&lt;&#x2F;h2&gt;
&lt;p&gt;This last point differs from the other ones. Here I&#x27;m gonna have to be a bit more serious for a second. This point is uncomfortable for everyone, but it&#x27;s one that I had to learn the hard way and I want to spare you that if I can. Employers are not your friend, and that&#x27;s okay.&lt;&#x2F;p&gt;
&lt;p&gt;I am not saying you cannot have cordial, mutually beneficial, or even friendly relationships with your employer. Far from it. However, you are not their friend and you&#x27;d do well to remember that because they for sure will. The era of &quot;company loyalty&quot; has ended on both sides long ago, if it ever existed to begin with. Employment is a plain business transaction, simple as that.&lt;&#x2F;p&gt;
&lt;p&gt;I think people shouldn&#x27;t have to be &quot;thankful&quot; for being able to work in a place. That doesn’t mean that you can’t be thankful for the things you have, but you shouldn’t feel gratitude towards your employer. They didn&#x27;t give you that job out of benevolence, but because they need something from you. It is in their nature to get the most out of you, whether they do so in humane, ethical or even pleasant ways, is up to them. When you stop being able to provide whatever they need, they will end the relationship. As soon as they stop being able to provide what you need, whether that&#x27;s money, career progression, a good work environment or anything else, you should move on.&lt;&#x2F;p&gt;
&lt;p&gt;This goes for your relationship with your direct boss especially. As much as flat hierarchies are trendy these days, your boss is not your friend, and your relationship is not equal. They sign your paycheck, and they decide whether you get a promotion. In a disagreement, they will win by default. I&#x27;ve found this to be the case in startups as much as it is in the government. That&#x27;s just the nature of power. I&#x27;m not saying this is all deliberate or conscious, but it is how I have experienced things in the workplace, and it does neither of you good to deny that reality.&lt;&#x2F;p&gt;
&lt;p&gt;Because overt authoritarianism is quite frowned upon these days, I have found one realisation that can sometimes help. Some people are uncomfortable with the power they wield and would rather not acknowledge it. You see this a lot in what I&#x27;ll call &quot;faux flat hierarchies&quot;. You should know that you can simply not play that game. It&#x27;s my policy that I will obey power when someone tries to use it, but only if they will admit aloud that is what they are doing. This is not a strategy for the faint of heart, but it has worked for me more often than I had originally thought.&lt;&#x2F;p&gt;
&lt;p&gt;None of what I&#x27;m saying here is meant to demonise employers or bosses. In fact, I&#x27;ve found that being clear about the boundaries of your relationship tends to improve them. It is hard to do but in my eyes, very worthwhile. Nor am I saying that this is how things &lt;em&gt;should&lt;&#x2F;em&gt; be. I&#x27;m saying that they &lt;em&gt;are&lt;&#x2F;em&gt; like that. And like it or not, you&#x27;ll do better in the workplace if you&#x27;re willing to acknowledge that and learn to work and deal with it.&lt;&#x2F;p&gt;
&lt;p&gt;As I said at the beginning, these tips are frustratingly vague and difficult, but hopefully you can get something out of them none the less. They are lessons that have helped me enormously along the way and I hope they will do the same for you. Hopefully, wherever you are in your career, these tips can serve you as guide stones, wherever you plan to go, and wherever you may end up. Good luck out there friend, you&#x27;ll need it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;recommended-reading&quot;&gt;Recommended Reading&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;books&#x2F;details&#x2F;Cal_Newport_So_Good_They_Can_t_Ignore_You?id=g13ZDAAAQBAJ&amp;amp;hl=en&quot;&gt;So good they can&#x27;t ignore you. by Cal Newport&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;books&#x2F;details&#x2F;David_Epstein_Range?id=ma1sDwAAQBAJ&amp;amp;hl=en&quot;&gt;Range: why generalists triumph in a specialised world. By David Epstein&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;books&#x2F;details&#x2F;Bren%C3%A9_Brown_Daring_Greatly?id=3rF7vvXa_yIC&amp;amp;hl=en&quot;&gt;Daring Greatly. by Brene Brown&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;books&#x2F;details&#x2F;Bren%C3%A9_Brown_Rising_Strong?id=SeEtBQAAQBAJ&amp;amp;hl=en&quot;&gt;Rising Strong. by Brene Brown&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;books&#x2F;details&#x2F;David_Graeber_Bullshit_Jobs?id=iHVEDwAAQBAJ&quot;&gt;Bullshit Jobs, a theory. by David Graeber&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=nsxkEs6G-9s&quot;&gt;&quot;Waiting for Godot&quot; Explained with Philosophy. By Abigail Thorn&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=MVlI8GJdDGo&quot;&gt;Doing the Small Stuff Feels Pointless. by HealthyGamerGG&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=BZPRX9X5V5I&quot;&gt;Dr. K, how do I focus? by HealthyGamerGG&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A deep dive into the strange world of Python versioning</title>
        <published>2024-02-17T00:00:00+00:00</published>
        <updated>2024-02-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/python-versioning/"/>
        <id>https://slowcoder.org/blog/python-versioning/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/python-versioning/">&lt;p&gt;Have you ever looked at version numbers for software and thought, &quot;What the hell were they thinking? I just want to know which version of a software I have and to which version I should update! This gibberish means nothing to me!&quot;. I mean, how hard can it be right? Well, a lot harder than you&#x27;d think.&lt;&#x2F;p&gt;
&lt;p&gt;Recently at work we had some real headaches with versioning. So much trouble, in fact, that I dived into the actual language specification for Python versions, called &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;packaging.python.org&#x2F;en&#x2F;latest&#x2F;specifications&#x2F;version-specifiers&#x2F;#version-specifiers&quot;&gt;PEP 440&lt;&#x2F;a&gt;. After having figured all of it out, I thought I might as well write it down, since it&#x27;s a lot more subtle than you&#x27;d expect. This blog post is the post I had hoped to find while dealing with this problem. I&#x27;ll give a bit more context where necessary, but I also won&#x27;t cover every corner case. The PEP is surprisingly readable, even though it is the coding equivalent of legalese. So, if you want all the details, I&#x27;d encourage you to have a look at it yourself. For those who are content with the broad strokes, I&#x27;ll try to give a summary here of the main points. Let&#x27;s get started!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-primer-on-semantic-versioning&quot;&gt;A primer on semantic versioning&lt;&#x2F;h2&gt;
&lt;p&gt;Before we get into python versioning specifically, we&#x27;ll have to cover some basics. The python versioning specification is heavily based on semantic versioning, so I&#x27;ll give an intro to that first. Instead of just telling you the rules, I&#x27;ll take a page out of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=bOXCLR3Wric&quot;&gt;3blue1brown&lt;&#x2F;a&gt;&#x27;s book (one of my favourite youtubers) and see if we can discover it ourselves.&lt;&#x2F;p&gt;
&lt;p&gt;Say for the sake of argument that we have a software that we release updates for regularly. Because people want to know which version they have, we start by calling our first version, version &lt;code&gt;1&lt;&#x2F;code&gt; and every time we release an update we increment that number. So the next update becomes version &lt;code&gt;2&lt;&#x2F;code&gt;, version &lt;code&gt;3&lt;&#x2F;code&gt;, etc. etc.&lt;&#x2F;p&gt;
&lt;p&gt;However, now we have a problem. People want to know, will version &lt;code&gt;2&lt;&#x2F;code&gt; be able to read documents made by old versions? Or is version &lt;code&gt;2&lt;&#x2F;code&gt; &lt;em&gt;backwards compatible&lt;&#x2F;em&gt; with version &lt;code&gt;1&lt;&#x2F;code&gt;? And if we then release version &lt;code&gt;3&lt;&#x2F;code&gt;, we get even more questions about which versions are still usable. Boy, this is a big hassle already, isn&#x27;t it? Wouldn&#x27;t it be amazing if you could tell whether your documents are still usable just by looking at the version number? Enter Semantic Versioning (stage left), or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;SemVer&lt;&#x2F;a&gt; for short.&lt;&#x2F;p&gt;
&lt;p&gt;A semantic version is a way of numbering versions so that they give information about which versions are compatible with each other. So a semantic version has three components, which are in order: the major version, the minor version, and the patch number, separated by periods. So for example &lt;code&gt;1.2.3&lt;&#x2F;code&gt; means, Major version &lt;code&gt;1&lt;&#x2F;code&gt;, minor version &lt;code&gt;2&lt;&#x2F;code&gt; and patch number &lt;code&gt;3&lt;&#x2F;code&gt;. Sometimes you&#x27;ll see it written as &lt;code&gt;v1.2.3&lt;&#x2F;code&gt; but that means the same.&lt;&#x2F;p&gt;
&lt;p&gt;Any time you release a new version that can&#x27;t do everything the previous version could, you increment the major version number. Any time you release something that can do everything the previous version can, but can do new things as well, you increment the minor version number. Finally, if you release a version that has the exact features as the last, for example, because you only fixed a bug, then you increment the patch number. These are referred to as major releases, minor releases, and patch releases, respectively.&lt;&#x2F;p&gt;
&lt;p&gt;In semantic versioning, any time you increment a number, you reset all the numbers after it back to &lt;code&gt;0&lt;&#x2F;code&gt;. For example, imagine the current version of your software is &lt;code&gt;1.2.3&lt;&#x2F;code&gt;. In that case, the next major version would be &lt;code&gt;2.0.0&lt;&#x2F;code&gt;. However, if instead you do a minor release, it would be &lt;code&gt;1.3.0&lt;&#x2F;code&gt;. Finally, if you&#x27;re just releasing the next patch, it would be &lt;code&gt;1.2.4&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;As you can probably see by now, the versioning of software is very intimately intertwined with its lifecycle. So far we&#x27;ve only talked about versions of released software, but what happens before it&#x27;s released? Someone has to build the stuff first, right? This is where what I&#x27;ll call &quot;suffix versions&quot; enter the picture. They are to show various degrees of certainty that what you&#x27;re looking at is going to be like that when it actually releases.&lt;&#x2F;p&gt;
&lt;p&gt;When a piece of software is still being built but not released to the public yet, it is usually called a &lt;code&gt;dev&lt;&#x2F;code&gt; version, usually with some identifier after it. So, for example, you could read a version number like &lt;code&gt;1.2.3.dev8&lt;&#x2F;code&gt; as &quot;the 8th iteration of the software that is going to become version &lt;code&gt;1.2.3&lt;&#x2F;code&gt;&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Then there are alpha and beta versions, written as &lt;code&gt;1.2.3.alpha4&lt;&#x2F;code&gt; and &lt;code&gt;1.2.3.beta5&lt;&#x2F;code&gt;. If you&#x27;re ever heard of a company of product having a &quot;closed alpha&quot; or a &quot;public beta&quot; this is what they are referring to. Alphas and betas are nearly complete versions of a product that are released to early adopters for testing and feedback.&lt;&#x2F;p&gt;
&lt;p&gt;There are also release candidates (RC for short), which would be written as &lt;code&gt;1.2.3.rc&lt;&#x2F;code&gt; This is the &quot;speak now or forever hold your peace&quot; version. It is the final stage of testing before something goes out to the public. Depending on the size of the project, you might have all, multiple of all, or none of these &quot;testing releases&quot;. Whatever works for you.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, there are so-called post releases. These are updated versions of the software, fixing minor issues that arose (usually) during its release. An example would be if the official release of the software was signed with expired credentials.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;honourable-mentions&quot;&gt;Honourable mentions&lt;&#x2F;h2&gt;
&lt;p&gt;Before I dive into a proper example, I think it&#x27;s good to mention a few simple versioning schemes that you might see in the wild, but are much less popular.&lt;&#x2F;p&gt;
&lt;p&gt;One notable exception to the SemVer rules is when the major version is &lt;code&gt;0&lt;&#x2F;code&gt;. Before version &lt;code&gt;1.0.0&lt;&#x2F;code&gt; is released, none of the rules, and therefore none of the guarantees, apply. At least, that&#x27;s the theory. At the inception, major version &lt;code&gt;0&lt;&#x2F;code&gt; was a no-promises-use-at-your-own-risk version. However, many software products that have been used in production for years are still pre version &lt;code&gt;1&lt;&#x2F;code&gt;, so the distinction is less harsh these days. There is even a fantastic satire page about this: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;0ver.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;0ver.org&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You also have &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;calver.org&#x2F;&quot;&gt;Calendar Versioning or CalVer&lt;&#x2F;a&gt; for short. This one is much simpler than SemVer. It has a few variations, but it comes down to &quot;the version of software is the date it was released&quot;. The variations dictate exactly how much information you include. Most often you only see it formatted as &lt;code&gt;YYYY.MM&lt;&#x2F;code&gt;, &lt;code&gt;YYYY.WW&lt;&#x2F;code&gt; or &lt;code&gt;YY.minor.patch&lt;&#x2F;code&gt;, but they all come down to much the same.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, there is also unary versioning which we&#x27;ve actually already seen. It&#x27;s the first versioning system I used as an example. In unary versioning, you just have a single increasing version number that you increment any time you do any kind of release.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-fictional-case-study&quot;&gt;A fictional case study&lt;&#x2F;h2&gt;
&lt;p&gt;That was probably fairly abstract, so let&#x27;s make an example: a simple calculator app. When we start work on our calculator, it is versioned &lt;code&gt;0.1.0. dev0&lt;&#x2F;code&gt;. Currently, the app is little more than a sketch on a bar napkin. We release new versions with every new feature. Adding a display is version &lt;code&gt;0.2.0&lt;&#x2F;code&gt;. Including buttons that actually do something is version &lt;code&gt;0.3.0&lt;&#x2F;code&gt;. Implementing addition and subtraction is version &lt;code&gt;0.4.0&lt;&#x2F;code&gt;, shortly followed by multiplication in version &lt;code&gt;0.5.0&lt;&#x2F;code&gt;. Finally, we add in a history in version &lt;code&gt;0.6.0&lt;&#x2F;code&gt;, after which we go to our first alpha version: &lt;code&gt;1.0.0-alpha1&lt;&#x2F;code&gt;. After thorough testing and feedback, we decide we&#x27;re happy with the product and eventually release version &lt;code&gt;1.0.0&lt;&#x2F;code&gt;. Our app is put out into the world and people love it.&lt;&#x2F;p&gt;
&lt;p&gt;However, after some time, people want to calculate roots as well, so we add that in. Calculations that people made before still work the same, but now they have more options, so this would be version &lt;code&gt;1.1.0&lt;&#x2F;code&gt;. Some time after that, we release a few patches that improve performance (&lt;code&gt;1.1.1&lt;&#x2F;code&gt;) and fix a security problem (&lt;code&gt;1.1.2&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;For a while everything seems hunky dory, but eventually a problem surfaces. Back when we implemented addition and subtraction, we found out that dealing with negative numbers is really complicated. Since having a negative number of something makes no sense, we used a shortcut. We just decided that it&#x27;s enough for our calculator to just return &lt;code&gt;0&lt;&#x2F;code&gt; as the answer any time you tried to subtract a larger number from a smaller number. So, in our calculator  &lt;code&gt;5 - 8 = 5 - 13 = 8 - 100000 = 0&lt;&#x2F;code&gt;. For our early customers, this worked fine, but now that our calculator has become so popular, accountants have started using it. They are very grumpy, because now they can&#x27;t track debts.&lt;&#x2F;p&gt;
&lt;p&gt;Now we&#x27;re at an impasse. Until now, you could check if a number was larger or equal than the other by just subtracting them and seeing if the answer was &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;However, if we implement negative numbers, this no longer works! Eventually, we decided to make the accountants happy (our own accountant insisted). So we implement negative numbers. Since calculations that gave one answer in version 1 might now give a different answer, we release this as version &lt;code&gt;2.0.0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;python-versioning&quot;&gt;Python versioning&lt;&#x2F;h2&gt;
&lt;p&gt;Okay, I have a confession to make. Technically, we didn&#x27;t have to cover anything to do with semantic versioning. The python version specification dictates nothing about the meaning of numbers or even how many there should be. The only requirement Python makes is that there is at least one number, the numbers are non-negative, and increasing across time.&lt;&#x2F;p&gt;
&lt;p&gt;So technically, some weird versioning schemes, such as the Tex versioning scheme, are actually Python compliant:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Since version 3.1, updates have been indicated by adding an extra digit at the end, so that the version number asymptotically approaches the number π. […] As of February 2021, the version number is 3.141592653. […] TeX developer Donald Knuth has stated that the &quot;absolutely final change (to be made after [his] death)&quot; will be to change the version number to π, at which point all remaining bugs will become permanent features.&lt;&#x2F;p&gt;
&lt;p&gt;— &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tug.org&#x2F;TUGboat&#x2F;tb11-4&#x2F;tb30knut.pdf&quot;&gt;Knuth, Donald E. (December 1990) &quot;The Future of TeX and Metafont&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So why then, you ask, did I make you go through all that theory? First of all, because I can (muahahaha). But more importantly, because it is a really solid foundation. Almost every serious versioning scheme used in software today is at least &lt;em&gt;loosely&lt;&#x2F;em&gt; based on semver and its syntax. How much it actually matters varies across communities. For example, communities such as JavaScript, or the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;lkml.org&#x2F;lkml&#x2F;2019&#x2F;3&#x2F;3&#x2F;236&quot;&gt;Linux kernel&lt;&#x2F;a&gt; (yeah, I know) play especially fast and loose with the rules. The precise distinction between major, minor, and patch versions isn&#x27;t that critical. However, people can get very, &lt;em&gt;very&lt;&#x2F;em&gt; angry if your versioning doesn&#x27;t communicate what they think it does. Just do yourself and your users a favour and use SemVer if you can, use CalVer if you can&#x27;t.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;version-specifiers&quot;&gt;Version specifiers&lt;&#x2F;h2&gt;
&lt;p&gt;So we&#x27;ve covered how to compare different versions, but what if you need to tell someone which version you actually want? This is where version specifiers enter the fray. A version specifier is a way to describe a range of versions that are usable to you.&lt;&#x2F;p&gt;
&lt;p&gt;To quote &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;packaging.python.org&#x2F;en&#x2F;latest&#x2F;specifications&#x2F;version-specifiers&#x2F;#id5&quot;&gt;PEP 440&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A version specifier comprises a series of version clauses, separated by commas.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;What is a clause, you ask? Well, it&#x27;s one of these 6:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;~=&lt;&#x2F;code&gt;: Compatible release clause&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;==&lt;&#x2F;code&gt;: Version matching clause&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;!=&lt;&#x2F;code&gt;: Version exclusion clause&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;=&lt;&#x2F;code&gt;, &lt;code&gt;&amp;gt;=&lt;&#x2F;code&gt;: Inclusive ordered comparison clause&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;&lt;&#x2F;code&gt;, &lt;code&gt;&amp;gt;&lt;&#x2F;code&gt;: Exclusive ordered comparison clause&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;===&lt;&#x2F;code&gt;: Arbitrary equality clause.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;What these clauses exactly do is where all the subtlety comes in (and where my mistakes came from). Python does also allow for unary versioning or CalVer, but as those are quite straight forward I won&#x27;t spend more time on them.&lt;&#x2F;p&gt;
&lt;p&gt;Exactly how equality works is where things get more tricky. So I first want to cover that in more depth before I explain any of the other components. It&#x27;s gonna get a little in the weeds, but bear with me because this is where our woes started.&lt;&#x2F;p&gt;
&lt;p&gt;As I am writing this, I am developing on python &lt;code&gt;3.9.18&lt;&#x2F;code&gt;. Python 3.9 is the oldest version we still support. To make sure we don&#x27;t use functionality that won&#x27;t work for all our versions, I try to work with the most restrictive set. But here&#x27;s the kicker, if I write, as a dependency &lt;code&gt;python==3.9&lt;&#x2F;code&gt; what do you think I will get? Do I get &lt;code&gt;3.9.0&lt;&#x2F;code&gt; or &lt;code&gt;3.9.whatever&lt;&#x2F;code&gt; or &lt;code&gt;3.9.latest&lt;&#x2F;code&gt;? Yeah, that&#x27;s what I&#x27;d thought too, but no. Sadly, it&#x27;s not &lt;code&gt;3.9.18&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To understand why, we first have to talk about two more concepts: zero padding and prefix matching. In zero padding, you make the shorter version number longer by adding 0 segments until it&#x27;s the same length as the other version number when comparing them. Prefix matching is the opposite in a way. If you add a wildcard segment like &lt;code&gt;1.2.*&lt;&#x2F;code&gt;, you can compare versions by making them the same length, even though the documentation doesn&#x27;t explain it in this way. When you encounter a wildcard segment, you do not consider any additional segments.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s look at a few examples again. Is &lt;code&gt;1.2&lt;&#x2F;code&gt; the same as &lt;code&gt;1.2.3&lt;&#x2F;code&gt;? well no, because when you apply zero padding (the default if there is no wildcard) you get &lt;code&gt;1.2.0&lt;&#x2F;code&gt; which is not the same as &lt;code&gt;1.2.3&lt;&#x2F;code&gt;. What about &lt;code&gt;1.3&lt;&#x2F;code&gt; and &lt;code&gt;1.1.8.4.32&lt;&#x2F;code&gt; (which is a valid python version)? This one is a bit more straightforward, but again we expand &lt;code&gt;1.3&lt;&#x2F;code&gt; to &lt;code&gt;1.3.0.0.0&lt;&#x2F;code&gt; which is not the same.&lt;&#x2F;p&gt;
&lt;p&gt;Conversely, is &lt;code&gt;1.2&lt;&#x2F;code&gt; the same as &lt;code&gt;1.2.*&lt;&#x2F;code&gt;? yes, because they are the same until we encounter the wild card and prefix matching tells us that is all we have to consider. What about &lt;code&gt;1.*&lt;&#x2F;code&gt; and &lt;code&gt;1.2.3&lt;&#x2F;code&gt;? Again, yes. Because when we see the &lt;code&gt;*&lt;&#x2F;code&gt; we stop considering segments. Okay, how about &lt;code&gt;1.*&lt;&#x2F;code&gt; and &lt;code&gt;1.0.0.alpha1-dev0&lt;&#x2F;code&gt;? Yup, you got it; they are. Finally, what about &lt;code&gt;0.*&lt;&#x2F;code&gt; and &lt;code&gt;1.2.*&lt;&#x2F;code&gt;? Thankfully, this time we are safe, because even though both contain a wild card, they don&#x27;t have any common prefix so they are not the same.&lt;&#x2F;p&gt;
&lt;p&gt;I hope you can see how zero padding and prefix matching represent the opposite sides of the permissiveness spectrum. With 0 padding you miss out on potentially useful stuff like patch releases. With prefix matching, you get a lot more stuff that you might not expect.&lt;&#x2F;p&gt;
&lt;p&gt;Now that we have a deeper understanding of how equality works, we can look at the others. So &lt;code&gt;==&lt;&#x2F;code&gt; we just discussed. When you use exclusion (&lt;code&gt;!=&lt;&#x2F;code&gt;) you do the same as with &lt;code&gt;==&lt;&#x2F;code&gt; but flip the decision you come to. What about &lt;code&gt;===&lt;&#x2F;code&gt;? With arbitrary equality, the versions are just string matched and have to be exactly the same. This ascertains which version you will get. However, it has the unfortunate side effect that, if you specify &lt;code&gt;1.2.3.dev0&lt;&#x2F;code&gt; instead of &lt;code&gt;1.2.3.dev0&lt;&#x2F;code&gt; you will get told that the version does not exist.&lt;&#x2F;p&gt;
&lt;p&gt;Okay, 3 down, 3 to go. What about &lt;code&gt;&amp;gt;&lt;&#x2F;code&gt;? Well, here the same rules for zero padding and prefix matching apply, except that you&#x27;re allowed to change your prefixes. So &lt;code&gt;&amp;gt;0.8.*&lt;&#x2F;code&gt; will actually match &lt;code&gt;0.9.0&lt;&#x2F;code&gt; as well as &lt;code&gt;1.2.3&lt;&#x2F;code&gt; or even &lt;code&gt;9999999.999999.99999.rc4&lt;&#x2F;code&gt; so beware. The same gotcha goes for &lt;code&gt;&amp;lt;&lt;&#x2F;code&gt; of course.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, there is the &quot;compatibility clause&quot;. This one is actually just a shorthand. &lt;code&gt;~= 2.2&lt;&#x2F;code&gt;  actually just means &lt;code&gt;&amp;gt;= 2.2, == 2.*&lt;&#x2F;code&gt;. Now let&#x27;s return to my original question. Which python version do you get if you specify &lt;code&gt;python==3.9&lt;&#x2F;code&gt;? You get Python &lt;code&gt;3.9.0&lt;&#x2F;code&gt;. Okay, what about the &quot;compatibility clause&quot;? if you specify &lt;code&gt;python~=3.9&lt;&#x2F;code&gt; what do you get? Why, it&#x27;s python &lt;code&gt;3.12&lt;&#x2F;code&gt;, of course, and not &lt;code&gt;3.9.18&lt;&#x2F;code&gt;, which is why part of our CI testing actually did nothing for quite a few months.&lt;&#x2F;p&gt;
&lt;p&gt;I think the confusion is that when we say something like &lt;code&gt;3.9&lt;&#x2F;code&gt; as humans, what we usually mean is &lt;code&gt;3.9.*&lt;&#x2F;code&gt; not &lt;code&gt;3.*&lt;&#x2F;code&gt; or &lt;code&gt;3.9.0&lt;&#x2F;code&gt; as the computer interprets it. So actually that means that &lt;code&gt;==3.9.*&lt;&#x2F;code&gt; and &lt;code&gt;~=3.9.0&lt;&#x2F;code&gt; are equivalent to each other but are not equivalent to &lt;code&gt;==3.9&lt;&#x2F;code&gt;, neither of which are equivalent to &lt;code&gt;~=3.9&lt;&#x2F;code&gt;. You see why I got confused?&lt;&#x2F;p&gt;
&lt;p&gt;So, if at the end of all this you&#x27;re still confused, I get you. It feels much more complicated than it actually ought to be. But I&#x27;ve come away from this adventure with two rules of thumb:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;if you&#x27;re a developer: use SemVer if you can, use CalVer if you can&#x27;t&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;if you&#x27;re requesting software: use &lt;code&gt;==X.Y.*&lt;&#x2F;code&gt; in 90% of cases it will be what you want.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I hope this has been useful to you! I&#x27;d be lying if I&#x27;d say that it wasn&#x27;t an enormous pain to figure out, but hopefully by writing this I&#x27;ll have spared you some of that pain. Take care, and good luck!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Performance isn&#x27;t just for FORTRAN</title>
        <published>2024-02-10T00:00:00+00:00</published>
        <updated>2024-02-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/performance-is-not-just-for-fortran/"/>
        <id>https://slowcoder.org/blog/performance-is-not-just-for-fortran/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/performance-is-not-just-for-fortran/">&lt;p&gt;Performance in software can be a very contentious thing. On the one hand, you have people who say that allocating even one string on the heap is too slow and why don&#x27;t you just handcraft your own assembly instructions come on. On the other hand, you have people say that performance is a non issue these days because computers got so fast that almost anything you do is &quot;fast enough&quot;. Finally, there are the corporate bozos that keep reminding us that the future of cloud computing is here, and with the click of a credit card you can have a box 10 times as large, so stop worrying will you.  I&#x27;m here to tell each of these people that they are incorrect. That&#x27;s right, all of them.&lt;&#x2F;p&gt;
&lt;p&gt;The problem is that it seems to be that people can only ever exist at the ends of this spectrum and that annoys me. So I&#x27;m about to argue against both positions. It might appear as if my opinions are contradictory, and maybe they are, but hey, I am human; I contain multitudes. Not just that, but I&#x27;m not just trying to convince you of something specific in this article, but open up a conversation. If anything, what I want to do in this article is convince you that performance is worth thinking about, whatever conclusions you&#x27;ll end up with. With all of that out of the way, let&#x27;s get started!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;just-write-better-code-brah&quot;&gt;Just write better code, brah&lt;&#x2F;h2&gt;
&lt;p&gt;There will always be people who say that &quot;it&#x27;s not that hard, just write better code&quot;. While this is pretty much always a disingenuous statement made without thinking of the people on the other side, it is especially false with performance. Before we get into my dissertation proper, I want to lie out a few examples of why performance can be so hard. The major reason is that we already get so much of those improvements &quot;for free&quot;. To improve what is there, you need to at least nominally understand what is already there.&lt;&#x2F;p&gt;
&lt;p&gt;If you want things to become faster, there are two things you can do: make the work go faster, or figure out a way to do less work. Let me show what I mean with a few examples. Consider why the following two snippets are equivalent (given there is only one answer), but the latter is faster:&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;guess_password1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;hashed_password&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; ans;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1e6&lt;&#x2F;span&gt;&lt;span&gt;; i++) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span&gt;(i) == hashed_password) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            ans = i;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; ans;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;guess_password2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;hashed_password&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; ans;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1e6&lt;&#x2F;span&gt;&lt;span&gt;; i++) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span&gt;(i) == hashed_password) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; i;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The second answer stops searching once it finds the answer, while the first one continues searching until it has tried all possibilities before giving the answer. It&#x27;s literally doing less work.&lt;&#x2F;p&gt;
&lt;p&gt;Now here&#x27;s a more tricky one. Which of these two functions do you think will be faster than the other, if any (given the if conditions are true in the same number of cases)?&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;array&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; sum = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; ARRAY_SIZE; i++) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;rand&lt;&#x2F;span&gt;&lt;span&gt;() % &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            sum += array[i];
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; sum;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;bar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;array&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; sum = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; ARRAY_SIZE; i++) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(array[i] &amp;gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            sum += array[i];
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; sum;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you&#x27;re like me, you&#x27;d expect these functions to be about the same, right? Yeah, about that...&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;❯ hyperfine .&#x2F;foo .&#x2F;bar -w 20 -r 500
&lt;&#x2F;span&gt;&lt;span&gt;  Benchmark 1: .&#x2F;foo
&lt;&#x2F;span&gt;&lt;span&gt;  Time (mean ± σ):      35.7 ms ±  15.0 ms    [User: 30.7 ms, System: 5.0 ms]
&lt;&#x2F;span&gt;&lt;span&gt;  Range (min … max):    22.6 ms …  68.5 ms    500 runs
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Benchmark 2: .&#x2F;bar
&lt;&#x2F;span&gt;&lt;span&gt;  Time (mean ± σ):      18.1 ms ±   5.7 ms    [User: 10.4 ms, System: 7.6 ms]
&lt;&#x2F;span&gt;&lt;span&gt;  Range (min … max):     7.0 ms …  23.9 ms    500 runs
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Summary
&lt;&#x2F;span&gt;&lt;span&gt;  .&#x2F;bar ran
&lt;&#x2F;span&gt;&lt;span&gt;    1.97 ± 1.03 times faster than .&#x2F;foo
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One of them is literally twice as fast as the other. Your mileage may vary if you run the benchmarks yourself, depending on your computer etc. but I think it&#x27;s fairly clear that there is a difference. Do you know why? It&#x27;s because of branch prediction. This is an optimisation that happens at the CPU level. I won&#x27;t go into detail about it here, but if you&#x27;re curious &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Branch_predictor&quot;&gt;the wikipedia article&lt;&#x2F;a&gt; provides an excellent overview. The point I&#x27;m trying to make is how incredibly subtle the difference can be, and how much you need to know about for spotting them.&lt;&#x2F;p&gt;
&lt;p&gt;Another optimisation that people might not know about is that compilers have a lot more leeway with your code than you think. They are allowed to ignore or reorder bits of your code as long as they believe it won&#x27;t make a difference. (fun fact, did you know that reordering code by the system was invented by a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lynn_Conway&quot;&gt;trans woman&lt;&#x2F;a&gt;?). For example, consider the following two simple C functions:&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4 &lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;bar&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;8 &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you run &lt;code&gt;gcc&lt;&#x2F;code&gt; with the &lt;code&gt;-S&lt;&#x2F;code&gt; command, it will also output the assembly it created alongside the program. I know assembly can be intimidating, but bear with me. Here are the (slightly cleaned up) resulting instructions:&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;asm&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-asm &quot;&gt;&lt;code class=&quot;language-asm&quot; data-lang=&quot;asm&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;foo:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt; pushq %&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rbp
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;movq &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rbp
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt; movl &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eax
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt; popq %&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rbp
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;ret
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;bar:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt; pushq %&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rbp
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;movq &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rbp
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt; movl &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eax
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt; popq %&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rbp
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;ret
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;ll spare you a detailed explanation of how assembly works, but the bits that you should pay attention to are &lt;code&gt;movl $0, %eax&lt;&#x2F;code&gt; and &lt;code&gt;movl $11, %eax&lt;&#x2F;code&gt;. These are basically assembly speak for &lt;code&gt;return 0&lt;&#x2F;code&gt; and &lt;code&gt;return 11&lt;&#x2F;code&gt; respectively. All the arithmetic and logic are gone, because the compiler figured out the answers will always be the same. This was a really simple example, but there are countless others like it. If you&#x27;re interested in what the C compiler is allowed to do and how that can go awry I suggest &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;research.swtch.com&#x2F;ub.pdf&quot;&gt;this excellent paper by Russ Cox on the subject&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Especially in performance, we already get a lot more &quot;for free&quot; than we realise. This means that when you want to optimise things, you need to know what&#x27;s going on under the hood. If you don&#x27;t, you might try to optimise something that the compiler will just throw out anyway. And these are just the bits I know about. Surely, there are countless others!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;it-s-a-trap&quot;&gt;it&#x27;s a trap&lt;&#x2F;h2&gt;
&lt;p&gt;Because performance is so hard to understand, it&#x27;s incredibly rare that significant and easy gains are just lying around. If they were, you&#x27;d probably have already done it. There is even a proverb about this: &quot;there is no such thing as a free lunch&quot;. It&#x27;s a way of saying that you can almost never get something that is simply better in every way. You&#x27;re always gonna end up paying in one way or another.&lt;&#x2F;p&gt;
&lt;p&gt;This can lead to a kind of learned helplessness. So many times when I advocate for working on performance, the conversation goes something like &quot;eh, it&#x27;s not great but it&#x27;s workable for now, we got other stuff to do&quot;. or &quot;well, users will just have to wait a little bit when using our system&quot;. That is fine until it isn&#x27;t anymore. This is how you get to dangerous situations. Such as your system is &quot;fine&quot; as long as you are developing it, but as soon as two people try to use it simultaneously, it brings down your entire production system (true story).&lt;&#x2F;p&gt;
&lt;p&gt;When something like that happens, you&#x27;re stuck. You&#x27;re now saddled with a system that&#x27;s not fit for purpose, and, as we concluded earlier, there is no easy way out. As much as people like to bemoan premature optimisation, if you wait for a really hard problem to become a blocker, you&#x27;re too late. Especially because performance is so complicated, I think you should invest in it in small increments over time. Again, I&#x27;m not advocating for trying to handcraft assembly to save every cycle we can. But even thinking about performance before it becomes unmanageable is likely to get labelled as a premature optimisation. That frustrates me hugely.&lt;&#x2F;p&gt;
&lt;p&gt;The problem with what I&#x27;m advocating for is that it&#x27;s a long-term strategy. It&#x27;s the exercise way to health care. It takes a long time to see the benefits. You don&#x27;t see how many problems you avoided because of proper exercise and nutrition, so it&#x27;s easy for people to go &quot;eh, well whatever, that doesn&#x27;t really do anything&quot;. But it does, just not immediately. Especially because performance is so complicated, it is imperative that you work on it in small increments.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-joys-of-performance&quot;&gt;The joys of performance&lt;&#x2F;h2&gt;
&lt;p&gt;One other bit that is also worth discussing is that I often see performance brought up in one and exactly one place: how long does the user have to wait? While I think this is important, I think this misses the boat regarding several things.&lt;&#x2F;p&gt;
&lt;p&gt;Performance isn&#x27;t just about users waiting, it&#x27;s also about computing power. And computing power means both money and emissions. Have you ever thought about how much energy it takes to run a program? In their &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;blogs&#x2F;opensource&#x2F;sustainability-with-rust&#x2F;&quot;&gt;open source blog on Cloud Sustainability&lt;&#x2F;a&gt; AWS they talk about the fact that data centres currently consume roughly 1% of all energy globally or approximately 200 terawatt hours per year. However, interestingly, what they find is that despite the cloud growing a lot in the past ten years, energy usage has stayed almost the same. You can see it on this IEA graph:&lt;&#x2F;p&gt;
&lt;div &gt;&lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;slowcoder.org&amp;#x2F;processed_images&amp;#x2F;global-data-centre-energy.19f3eb4a202ab8f6.webp&quot; alt=&quot;Global data centre energy demand by centre type, 2010-2022. It shows distributions changing but the total energy consumption is almost flat across the graph&quot; &#x2F;&gt;
    &lt;&#x2F;div&gt;
&lt;p&gt;This must have been, at least in part, because of the performance gains we&#x27;ve made. Whether you&#x27;re concerned about saving money or reducing emissions, it&#x27;s hard to overlook this phenomenon. They also cite an excellent study by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;greenlab.di.uminho.pt&#x2F;wp-content&#x2F;uploads&#x2F;2017&#x2F;10&#x2F;sleFinal.pdf&quot;&gt;Pereira et al.&lt;&#x2F;a&gt; about the energy usage of various programming languages. The authors of that paper produce the following tables:&lt;&#x2F;p&gt;
&lt;div &gt;&lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;slowcoder.org&amp;#x2F;processed_images&amp;#x2F;lang-energy-usage.b664c5d3ef0ecbb4.webp&quot; alt=&quot;three tables showing the relative resources used by langues in terms of energy, time, and Mb of memory used. C is top of the list in almost every category, while python is often near the bottom.&quot; &#x2F;&gt;
    &lt;&#x2F;div&gt;
&lt;p&gt;So using python requires more than 75x the amount of energy for the same task! That&#x27;s insane! Now to be fair much of serious Python is actually just C in a trench coat and the study seems to have used a native python solution, so the gains might not be that dramatic in a real scenario, but even so, that&#x27;s a heck of a chunk! You could decommission half your servers with that performance gain. I know this whole blog post is dedicated to arguing that performance isn&#x27;t just about rewriting in a faster language, so it might seem weird to bring this up. However, I&#x27;m not arguing for a rewrite. I&#x27;m just using rewriting as a metaphor for optimisation to show you what is possible.&lt;&#x2F;p&gt;
&lt;p&gt;There is one more aspect to it I have never seen being brought up before: developer joy. I know Developer experience has become a bit of a meaningless buzzword these days, but I still think that this is worth thinking about. Speed is a feature for your developers as well. Every second that developers don&#x27;t need to sit there waiting for the CIs to finish is something they could be doing something more productive. It&#x27;s another opportunity for them to get distracted or invited to another meeting. I&#x27;m speaking from personal experience on that last point.&lt;&#x2F;p&gt;
&lt;p&gt;I think having performant software and workflows also improves employee satisfaction. Though I don&#x27;t have hard data to back it up, check out this admittedly [very informal survey]. 77% of respondents would much rather use something fast than something they can contribute to. As Craig Mod puts it in his excellent blog point &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;craigmod.com&#x2F;essays&#x2F;fast_software&#x2F;&quot;&gt;Fast Software, the Best Software&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Software that&#x27;s speedy usually means it&#x27;s focused. Like a good tool, it often means that it&#x27;s simple, but that&#x27;s not necessarily true. Speed in software is probably the most valuable, least valued asset. To me, speedy software is the difference between an application smoothly integrating into your life, and one called upon with great reluctance. Fastness in software is like great margins in a book — makes you smile without necessarily knowing why.&lt;&#x2F;p&gt;
&lt;p&gt;— Craig Mod&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I find this to be equally true for users as for developers. As a developer, you&#x27;re running tests, debugging, performing maintenance and deploying all day long. Introducing even minor delays here can really suck the joy out of work. Perhaps I am alone in this, but I find few things as frustrating as having to sit there for a slow CI to finish when I just want to finish one tiny thing.&lt;&#x2F;p&gt;
&lt;p&gt;Working in Rust and Go has really reinforced this for me. Using the go compiler, formatter, and LSP is a joy. They are so fast that sometimes you make intentional mistakes to just verify they are still working. And this encourages writing better code, because the faster you can get feedback, the easier it is to improve on it. If you prefer something closer to home, the Ruff linter for python is like this, too.&lt;&#x2F;p&gt;
&lt;p&gt;It is a joy that I really miss when I don&#x27;t have it anymore. Working with a really fast application is a &lt;em&gt;rush&lt;&#x2F;em&gt;. It feels so good. It almost makes you feel like some kind of powerful wizard. I want more people to feel that feeling. We all deserve this, even if they don&#x27;t want to rewrite our entire application in Fortran (which is where the title of this piece comes from).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;okay-sam-but-what-do&quot;&gt;Okay Sam, but what do?&lt;&#x2F;h2&gt;
&lt;p&gt;Let me try to at least offer some alternative way out of this that I consider being a good middle ground. Because I&#x27;ve been kind of harsh on both sides of this debate. I don&#x27;t want to seem like neither of these sides has their merits. Sometimes, premature optimisation is a real problem. I know I have been particularly guilty of this over the years (Steve, if you&#x27;re reading this, stop laughing). Sometimes we have our darlings and we just can&#x27;t help but overcomplicate things, but that doesn&#x27;t mean that these issues aren&#x27;t worth discussing.&lt;&#x2F;p&gt;
&lt;p&gt;On the other hand, sometimes we really need to think of performance, and not just hide behind the fact that we are using python. There is a middle ground here. I know I spent a significant part of this blog post explaining why performance minded programming is hard, but it&#x27;s not impossible. There are a lot of easy first steps when it comes to performance. So here are my recommendations:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;You should always be measuring. Even if you do nothing with it, just like I believe every piece of software should have a test suite, every piece of software should have some basic bench marks. Sure, you&#x27;re very unlikely to get to a perfect solution, but something is better than nothing, and there are certain simple things to get you started. It is the same as testing, and we all do that, right? (RIGHT?) Even if you have to run the benchmarks manually, that is fine. I will admit here this is a place where I fall short. Performance is an area where I am trying to improve, and one aspect of that is going to be writing more bench marks for the software I write.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Learn the basics. What the basics mean will be up to you. I don&#x27;t know enough about performance yet to develop an informed curriculum. In fact, I&#x27;m still busy with this step myself. But I think it makes sense for more people to at least learn the basics of how we talk about performance, you know, the real simple stuff. Performance is hard, but it&#x27;s also not as mythologic as some people make it sound, and I think you&#x27;d be surprised how much you can pick up in an afternoon if you try. I&#x27;m hoping to do an &quot;intro to performance&quot; post here sometime, but no promises on when that will happen.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Start small and keep at it. Even if your optimisations don&#x27;t produce noticeable improvements, still make them. First, because it will give you the practice and experience you need to do the big optimisations. Second, those minor changes will accumulate over time. You don&#x27;t have to obsess over this, but try to keep it in mind and learn what you can.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;And that&#x27;s pretty much ya lot. I hope I&#x27;ve convinced you that the performance is at least somewhat worth thinking about. Stay safe, and stay fast, my friends!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>An honest talk about evangelism</title>
        <published>2024-02-03T00:00:00+00:00</published>
        <updated>2024-02-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/on-evangalism/"/>
        <id>https://slowcoder.org/blog/on-evangalism/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/on-evangalism/">&lt;p&gt;I want to have an honest conversation about evangelism. Here I mean evangelism not in the religious sense, but more in the sense of being an enthusiastic advocate. I have never considered myself as a particularly evangelical person. I like to let people make their own decisions and just try to make people aware of opportunities and pitfalls. However, I have to admit that in the past I have been evangelical.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s not to say that being evangelical is always bad. There are scores of things that deserve to be evangelised. Things such as gender equality, human rights, compassion, and a sense of urgency around not fucking up our planet, just to name a few. I engaged in some &lt;a href=&quot;https:&#x2F;&#x2F;slowcoder.org&#x2F;blog&#x2F;maybe-you-do-get-what-its-like&#x2F;&quot;&gt;portential evantaglism&lt;&#x2F;a&gt; the other day.&lt;&#x2F;p&gt;
&lt;p&gt;In non-religious contexts, the word evangelism is often used to refer to someone promoting things we dislike. This means that it can be very hard not to &quot;evangelise&quot; for things one believes in. This is especially true on an omni-directional medium like the public internet. Out here, I don&#x27;t have a say in whom I am addressing.&lt;&#x2F;p&gt;
&lt;p&gt;While I want to stay away from discussing religion in this blog post, there is one quote I want to share:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Sir,&quot; [he said,] addressing the preacher, &quot;if I believed what you and the church of God say that you believe, even if England were covered with broken glass from coast to coast, I would walk over it, if need be, on hands and knees and think it worthwhile living, just to save one soul from an eternal hell like that!&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Ravenhill, Leonard (1987). Why Revival Tarries. Bethany House Publisher. pp. 19.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I&#x27;ve thought a lot about that quote over the past few months. The things I&#x27;m about to discuss are not as grandiose as that, but it&#x27;s a very illuminating thought experiment. It exemplifies why I sometimes evangelise without meaning to: I believe in stuff I talk about, or, well, believed, but we&#x27;ll get to that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-i-evangelise&quot;&gt;Why I evangelise&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;m hoping for this blog post to be a two-way street. I am attempting to go through some honest introspection about my own tendencies, and I hope you will too, dear reader. By nature of this medium, it is impossible for me to address you in particular. However, there are patterns of behaviour I wish to address. So know that when in this blog post I address you, I am not speaking to you as a person but to a hypothetical person who exhibits these behaviours. I will leave it up to you to examine how these patterns may or may not apply to you.&lt;&#x2F;p&gt;
&lt;p&gt;We already started out by describing one reason for my evangelism: they are things I believe in and the recipient of my message may not. But there is another cause: someone antagonising me.&lt;&#x2F;p&gt;
&lt;p&gt;To explain, let me paint you a picture. You have a somewhat positive opinion of phenomenon A. Now you are talking with someone who is convinced that A is terrible. They claim it is the scourge of humanity, a blight upon the world, nay the potential end of civilisation itself!&lt;&#x2F;p&gt;
&lt;p&gt;Every time A is brought up, your interlocutor makes outlandish claims about the dangers of A, which you do not believe are true. So you push back against these claims. Your interlocutor, in turn, pushes back against you. Not wanting to let the false claims stand, you continue arguing. As the debate continues and you have to keep reaching for more positive aspects of A to avoid being steamrollered by this other person. After a long and intense debate, you realise that you&#x27;ve been passionately defending a position that you don&#x27;t even believe in!&lt;&#x2F;p&gt;
&lt;p&gt;I think this description is a big reason why I evangelise. It shows how the &quot;controversial&quot; topics I enjoy talking about become evangelism. Note the quotes round controversial, because sometimes these things shouldn&#x27;t be. This is why I sometimes try to avoid discussing my views on the medical establishment. The medical establishment is far from perfect. I&#x27;m not denying that. But trying to raise and examine the legitimate criticisms risks your being lumped in with the anti-vaxxers. There is a blog post about this subject in the works so I won&#x27;t talk about it too much here, but I hope you can see where I&#x27;m coming from. I know I am part of this dynamic, but it is enfuriating.&lt;&#x2F;p&gt;
&lt;p&gt;Before I wrap up my analysis on evangelism, I want to talk about two topics that have sparked this blog post: AI and Rust.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ai&quot;&gt;AI&lt;&#x2F;h3&gt;
&lt;p&gt;There was a time when I was genuinely excited about the possibilities of AI, even if I was apprehensive about it. I have always regarded AI, as overloaded as that term has become, as a scientific tool with enormous potential, akin to correlation. (In fact, AI is just a very complicated version of correlation, but I won&#x27;t take you down that rabbit hole today). While it can teach us incredible things, it has to be regarded with care and at least some scepticism, and has a tremendous potential for misdirection. Just as any respectable scientist must regard their results with suspicion and scrutiny, so too should we regard the insights that AI gives us. We must seek to verify its claims as rigorously as possible. This rigour has been, to this day, almost wholly absent in my experience.&lt;&#x2F;p&gt;
&lt;p&gt;So, ever since I&#x27;ve been part of AI, I&#x27;ve tried to pump the breaks on the AI hype train. I tried to be a voice of caution in the room. However, thinking of AI as another tool in a toolbox, one that we&#x27;ve been adding to over centuries, doesn&#x27;t get you the seed funding you need. I am sick of the dichotomy of having to make promises I&#x27;m sceptical about being able to make or risk having my opinion discarded.&lt;&#x2F;p&gt;
&lt;p&gt;I still maintain AI has a much greater potential than is being utilised right now. You might scoff at that given how pervasive it is. But the potential of this technology is being overlooked by many who are more interested in using it for advertising, enabling online scams and undermining democracy. Why they choose those goals instead of using AI for things that play into the strengths of AI is beyond me. Some AI proponents would prioritise creating an AI to replace human cleaners over an AI that can adjust medication regimens based on numerous comorbidities. That. is. insane.&lt;&#x2F;p&gt;
&lt;p&gt;Since ChatGPT has entered the fray, I more or less consider this a lost battle for the time being. The genie is out of the bottle; the ship has sailed, and it&#x27;s not coming back for quite a while. Hallucinations by ChatGPT can be so subtle even experts can read over them. This is just so dangerous, and I&#x27;m feeling like I&#x27;m shouting into the void about this. I&#x27;m sick of being painted as a doomsayer and a detractor. Fine, then, enjoy your scummy adds and your hallucinations.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rust&quot;&gt;Rust&lt;&#x2F;h3&gt;
&lt;p&gt;I have loved Rust for a while now. In some places, I&#x27;ve had a reputation as &quot;the person who likes Rust too much&quot;. Funnily enough, I care very little about some of Rust&#x27;s &quot;main selling points&quot;, like concurrency. The culture around how software in Rust is written differs from other languages. CLIs in Go, Python and Rust each have a unique feel to them, and I prefer the ergonomics of Rust based programs. Rust has a culture of very good and robust tooling and documentation that I&#x27;ve loved working in. Sure, it&#x27;s young and complex sometimes, but I&#x27;m fine with that.&lt;&#x2F;p&gt;
&lt;p&gt;However, this love and excitement has been dragged down by the haters trying to put words in my mouth about how production ready the ecosystem is. I&#x27;m tired of arguing about whether Rust is faster than Go or Python, or if the time otherwise spent debugging justifies the extra mental effort. It doesn&#x27;t matter to me anymore. It feels like every conversation I&#x27;ve had with a non-Rust user about Rust ended on some variation of &quot;borrow checker hard&quot;. I am done having that conversation.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, many promising aspects of Rust, such as scientific computing, have, thus far, failed to materialise. Perhaps it still may, and I still hope it does, but I find myself less and less enthusiastic about these possibilities.&lt;&#x2F;p&gt;
&lt;p&gt;People often joke about how Rust proponents suggest rewriting every application in Rust, but I also found the other side to be the same. I can barely mention that I like what Rust has to offer without detractors responding, &quot;oh, here comes the Rust Evangalism Strike Force again&quot;, instead of letting me explore some cool alternatives. Not all software has to be production ready or even &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ntietz.com&#x2F;blog&#x2F;write-more-useless-software&#x2F;&quot;&gt;useful&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Not only that, but one thing that always attracted me to Rust was the community. When I started getting into Rust, the community felt cosy and welcoming to me. Despite its complexity, I found Rust and people who use it to be warm, welcoming, and much more understanding of beginners than, for example, C developers.&lt;&#x2F;p&gt;
&lt;p&gt;However, feeling like I have to defend it every time I discuss it has led me to no longer discussing it. The problems and drama that have come out of the Rust foundation and other prominent members also don&#x27;t help maintain my enthusiasm for it. I remember being worried when the moderation team resigned. Worrying that might be a sign of things to come. So far, that has proven to be true, and I am very sad about that.&lt;&#x2F;p&gt;
&lt;p&gt;The allegations of systemic racism in the Rust community have also exhausted me. To be clear, I am not in any way bemoaning the people who speak up about this; I have not witnessed it myself, but that does not by any means mean it is not there, and I will always support people speaking up about experiences like this. That doesn&#x27;t detract from the fact that it is very draining to have to engage with it (yeah I know white tears, this is my blog, gimme a break). I don&#x27;t know what to do about this, and it just makes me sad.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bringing-it-all-together&quot;&gt;Bringing it all together&lt;&#x2F;h2&gt;
&lt;p&gt;So, when reflecting on my approach to evangelism, I believe it is only fair to consider the situations in which I am evangelised as well. Because look, I get it. It fucking sucks being evangelised to. Folks who know me will be familiar with my rant about anyone who suggests meditation or yoga in response to my disabilities or mental health issues. And that&#x27;s putting aside being evangelised to about the &quot;delusions&quot; I have for being queer or a socialist.&lt;&#x2F;p&gt;
&lt;p&gt;I think the frustrations with this evangelism come from a couple of places. First, if the suggestion is fairly obvious, it was likely the first or second idea I came to, but discarded down the line. Even if it is meant in supportive ways, this feels very demeaning. It feels a bit like suggesting to &quot;take a deep breath of air&quot; to someone who is drowning.&lt;&#x2F;p&gt;
&lt;p&gt;That last metaphor also surmises the second reason being evangelised to is so damn infuriating. It&#x27;s the feeling that suggestions like that trivialise the problem. Your life would be so much easier if you just… Just believed in God. Just had some confidence. Just maintained a healthy sleep schedule. Just ate healthier. Just got enough exercise. Just eliminated distractions. Just, just, just… The same answer always comes up with me in these situations. &quot;Do you really think that I wouldn&#x27;t have done that already if it were that easy?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;I think the heart of this evangelism debate lies in this last idea. The feeling that being evangelised to trivialises the problem and, in fact, may exacerbate it. Because now, besides dealing with whatever problem you have, you now also have to spend time and energy having the same damn conversations over and over again about why the proposed situation doesn&#x27;t work for your case.&lt;&#x2F;p&gt;
&lt;p&gt;But here&#x27;s the kicker. Having a healthy sleep schedule, eating nutritious food, getting enough exercise and meditating? They have all worked. Not as much as some have claimed but they have worked. They have all been instrumental in getting both my disabilities and mental health under control. But that is the last idea I wanted to entertain while I was in the middle of it. Even though they were all true, I didn&#x27;t want to believe them.&lt;&#x2F;p&gt;
&lt;p&gt;This brings up another point that is important to consider when thinking of evangelism: timing. To illustrate what I mean, let me tell you two anecdotes. The first is a very unfunny joke:&lt;&#x2F;p&gt;
&lt;p&gt;Q: &quot;How do you know if someone is a vegan?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;A: &quot;Oh don&#x27;t worry, &lt;em&gt;they&#x27;ll tell you&lt;&#x2F;em&gt;&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Now I don&#x27;t know about you, but I&#x27;ve never met a vegan like this (and yes, I have met plenty of vegans, they&#x27;re lovely people). The humour lies in the stereotype that vegans will bring up their veganism and try to convert you, even in wildly inappropriate situations.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the other anecdote. A while back my city painted a park bench in the pride colours. I think that&#x27;s neat, but don&#x27;t care all that much. However, some time after the bench had been painted, someone had scribbled &quot;God loves us all&quot; or something to that effect in chalk on the ground around the bench. Now it&#x27;s possible that this was meant as an encouraging sentence meaning &quot;god loves us all, no matter our creed or sexuality&quot;. However, I hope you can see, given the history of how that sentence and sentiment has been used against us, how that did not sit well with me. It is acceptable to proclaim that your god supports the queers, but if you want to do it, consider how, when and where your message of support might land.&lt;&#x2F;p&gt;
&lt;p&gt;So, I think that the solution to this conundrum lies with both the evangeliser and the evangelisee. Honestly, this advice is going to come down to act in good faith, and expect the other to do the same. Inspect the things you want to advocate for, how they might be received, and whether this is an appropriate time to do so. If someone is trying to convince you of something, consider giving them a chance and assuming they have the best intentions. (if you can, always safety first)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;some-final-housekeeping&quot;&gt;Some final housekeeping&lt;&#x2F;h2&gt;
&lt;p&gt;Perhaps you&#x27;ve been able to tell from the paragraphs above, but I&#x27;m a little burnt out on these subjects. There is just too much bad faith going around on whatever side you fall for me to keep enjoying discussions about them. Since I started my new job at Deltares, I&#x27;ve been in a much less charged environment and I think that has improved my well being. So I&#x27;m taking a step back from AI, data science, Rust and (hopefully) evangelism. As I&#x27;ve outlined above, it&#x27;s a little more tricky than just saying &quot;I won&#x27;t evangelise anymore&quot;, but I&#x27;m going to try. That doesn&#x27;t mean I&#x27;m promising to cut ties with them completely or never mention them again, but I&#x27;ll be prioritising other things for now. I just don&#x27;t want them to be part of my identity anymore like they have been so far. I don&#x27;t know, maybe I&#x27;ll go do some front end stuff for a while where the stakes aren&#x27;t so high.&lt;&#x2F;p&gt;
&lt;p&gt;After this blog post goes up, I&#x27;ll be making updates to the website, starting with the name and URL. For posterity&#x27;s sake: this website used to be called &lt;code&gt;howtoai.fyi&lt;&#x2F;code&gt;. However, I want to take some time away from AI and the intense polarisation. So I&#x27;m rebranding (yes, again, I know). Originally I wanted to wait posting this article until all of the changes were done but that is proving to be a longer process than anticpiated, and I feel like I&#x27;ve been sitting on this topic for far too long already. So I&#x27;ll be rolling out the new things like names, logos possibly designs incrementally, though the old links should still continue to work. The new &quot;brand&quot;, so to speak, even though I hate using that term, will be called &lt;code&gt;slowcoder.org&lt;&#x2F;code&gt;. It is about focusing on a slower, more deliberate kind of software development. Hopefully, one with less blaming, flame wars or evangelism. Take care y&#x27;all.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Maybe you do get what it&#x27;s like</title>
        <published>2024-01-27T00:00:00+00:00</published>
        <updated>2024-01-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/maybe-you-do-get-what-its-like/"/>
        <id>https://slowcoder.org/blog/maybe-you-do-get-what-its-like/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/maybe-you-do-get-what-its-like/">&lt;p&gt;Whooooo boy, we&#x27;re really doing this, eh? In this post, I&#x27;ll be talking a lot about marginalisation. Some marginalisations I will be part of, some not. However, it is actually also the point of this essay to talk about marginalisations that are not your own. I will be speaking of my own experience, and I will most certainly try to not speak for others, or tell you what you should or shouldn&#x27;t do. This is a subject that is so intimately interwoven with the concept of trauma that there is barely any distinction. Trauma is intimate and personal. I&#x27;d never want to tell someone how to handle their trauma or what reactions are or are not appropriate (aside from some edge cases, of course). I will, however, make some, by lack of a better word, make some priestly invitations. By that I mean that this post is an invitation for you to think in a new way. You are not obligated to take any of it to heart, but I hope you do.&lt;&#x2F;p&gt;
&lt;p&gt;This post is also both for, and about people who are willing to talk in good faith. If you&#x27;re not on board with that for whatever reason, you can stop reading right now. What I am doing here is as much theory crafting as it is opining. I reserve the right to be mistaken and change my mind on the thing in this piece. So I hope you&#x27;ll give me the benefit of the doubt if I put my foot in my mouth.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cultural-snafu&quot;&gt;Cultural SNAFU&lt;&#x2F;h2&gt;
&lt;p&gt;There is a very common sentiment around marginalisation these days. That &quot;you don&#x27;t know that it&#x27;s like&quot; if you&#x27;re not part of the marginalised group you are talking about. For example, as a white person, I will never truly understand what experiencing racism feels like. I&#x27;ll call this the &quot;sit down and shut up&quot; (SDSU) mentality.&lt;&#x2F;p&gt;
&lt;p&gt;SDSU exists for a reason. Historically, being part of a minority has been taken as an excellent reason to dismiss people or tell them how they should feel. This also shows up around things like colonial occupation and is not exclusive to outgroup folk. Respectability politics is an example of this. People get ignored or their experiences dismissed to fit in with societal norms, even within their own communities.&lt;&#x2F;p&gt;
&lt;p&gt;In his excellent book &quot;The Body Keeps the Score&quot;, Bessel van der Kolk says that this is a very common response for traumatised individuals. He writes:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;[A group of former Marines in group therapy] insisted that I had to be part of their newfound unit and gave me a Marine captain&#x27;s uniform for my birthday. In retrospect, that gesture revealed part of the problem: You were either in or out—you either belonged to the unit or you were nobody. After trauma, the world becomes sharply divided between those who know and those who don&#x27;t. People who have not shared the traumatic experience cannot be trusted, because they can&#x27;t understand it. Sadly, this often includes spouses, children, and co-workers.&lt;&#x2F;p&gt;
&lt;p&gt;Later I led another group, this time for veterans of Patton&#x27;s army […] For Christmas they gave me a 1940s GI-issue wristwatch. As had been the case with my group of Marines, I could not be their doctor unless they made me one of them.&lt;&#x2F;p&gt;
&lt;p&gt;— The Body Keeps the Score, Bessel van der Kolk, p 29&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Sounds very familiar, doesn&#x27;t it?&lt;&#x2F;p&gt;
&lt;p&gt;Again, let&#x27;s be clear here. I&#x27;m not about to tell anyone that they can&#x27;t use the SDSU mentality at any point. Sometimes it is appropriate, sometimes it is your only option. However, I think that with this policy we might have thrown out the baby with the proverbial bathwater. We are missing a genuine opportunity for empathy and learning for those who will engage with it in good faith.&lt;&#x2F;p&gt;
&lt;p&gt;I couldn&#x27;t find the original source for the quote I&#x27;m about to share, so my apologies if I don&#x27;t get the wording or attribution correct. From what I could find, it might be attributed to Laverne Cox, but I couldn&#x27;t verify that. Here&#x27;s the quote:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Maybe not everyone understands what it is like to be trans, but everyone understands what it is to feel excluded, to be made to feel less than, to be in pain, to be misunderstood and to feel like you can not be yourself.&lt;&#x2F;p&gt;
&lt;p&gt;— Laverne Cox (unverified)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Through this blog, I want to make the case that those who haven&#x27;t faced marginalisation can understand our experiences better than we realise. I hope to inspire them to speak up on our and their behalf. To make this case, I will draw on my experience as both a white progressive and a trans and neurodiverse person. Let me show my thinking with two examples here.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-tale-of-brave-lady-emma&quot;&gt;The tale of brave lady Emma&lt;&#x2F;h2&gt;
&lt;p&gt;A dear friend, whom I will call Emma in this story (which is not her actual name), and I were sitting in a lovely cafe and having some lunch one day. We were talking, chatting and cackling like usual. We&#x27;ve been friends for well over a decade and she is, without a doubt, one of my favourite humans. At some point, the discussion about being trans arose. Emma, who is cis, repeated a variation of the SDSU mentality: &quot;well I guess I don&#x27;t know what it&#x27;s like, but that sounds incredibly heard&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;However, in response, I asked her if she remembered feeling insecure about any part of herself as a young girl. If she could remember feeling excluded or alienated. Emma thought about it briefly and said, &quot;damn, I think you&#x27;re on to something there. I&#x27;ve often been very self conscious about my height, and what that said about my femininity. That does make a lot of sense.&quot; This is a concern that many trans women share might I add. That turned out to be an incredible point of connection for us.&lt;&#x2F;p&gt;
&lt;p&gt;As a little girl, she has, of course, experienced the regular troubles of being a girl in a patriarchal society. A post she made on social media during the first #MeeToo wave will probably stay with me forever. She described how men would… ahem, do unmentionable acts in public in front of her as a way of sexual intimidation. So maybe she doesn&#x27;t know exactly what it means to be trans, but she sure as hell knows that it&#x27;s like to be intimidated or feel unsafe in public. She could, and has, drawn on her own emotional experience, and used that to fuel her vast empathy for experiences she didn&#x27;t technically share.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;is-this-what-it-s-like&quot;&gt;&quot;Is this what it&#x27;s like?&quot;&lt;&#x2F;h2&gt;
&lt;p&gt;I like to think that I&#x27;ve always been an empathic person. However, I must admit that I was not always a beacon of political correctness. During my undergrad I remember making some jokes and comments that I would never utter these days. Let&#x27;s just say that I still had a lot of growing to do back then.&lt;&#x2F;p&gt;
&lt;p&gt;But I remember early on when I was still grappling with my first wave of trans acceptance. I had to come to terms with just how demonised trans people are and the kinds of trouble I might get into if people find out. I felt constantly observed and scrutinised. The realisation of how many people like me are demonised and dehumanised in any form of media just for being themselves was crushing. During all of that, I do vividly remember at one point thinking &quot;omg, is this what it&#x27;s like for people of colour?&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Again, indeed I cannot know because of my whiteness, but from what I have understood, it is at least somewhat close. Since then I&#x27;ve taken a much more active interest in anti-racism, and taking more effort to learn about it. Realising my own trans identity is the thing I still consider that has brought me closest to truly understanding racism.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;brave-new-world-of-empathy&quot;&gt;Brave new world (of empathy)&lt;&#x2F;h2&gt;
&lt;p&gt;The point I&#x27;m trying to make here is that one hole in the SDSU mentality is that we deny people empathy. Of course, others don&#x27;t truly know what it is to have our marginalisation. So often it&#x27;s death by a thousand paper cuts, so even understanding one aspect of it is not enough to understand it as a whole. However, and this is a more practical point, we need allies. We all do. I believe real emancipation simply requires allies from outside the oppressed group. And I think that by othering ourselves by insisting others could not possibly ever understand what it&#x27;s like to be us, we&#x27;re not gaining more allies. In fact, we alienate ourselves from them and from ourselves. I think Van der Kolk puts it incredibly well:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Focusing on a shared history of trauma and victimisation alleviates their searing sense of isolation, but usually at the price of having to deny their individual differences: Members can belong only if they conform to the common code.&lt;&#x2F;p&gt;
&lt;p&gt;Isolating oneself into a narrowly defined victim group promotes a view of others as irrelevant at best and dangerous at worst, which eventually only leads to further alienation.&lt;&#x2F;p&gt;
&lt;p&gt;— The Body Keeps the Score, Bessel van der Kolk, p. 94&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I think we should encourage other people to feel our feelings. I want them to put themselves in our shoes by imagining the parts of their experience they have had that are close to us. Otherwise we deny them empathy and we deny ourselves a support network. I think it is time for white people to talk about racism; it is time for cis people to talk about transphobia and other experiences they might have with gender. It is time for the heteros to acknowledge homophobia.&lt;&#x2F;p&gt;
&lt;p&gt;But there is more to it than that even. I think it is important for white people to discuss &lt;em&gt;our&lt;&#x2F;em&gt; experience of racism, both the positive and negative. Here, I don&#x27;t mean positive as in that we like it, but more that it might be situations in which we were the benefactor. It fucking sucks to be told that you&#x27;re at the top of the pile and have things twice as easy as most and are still struggling like hell. I truly believe racism diminishes white folk as well.&lt;&#x2F;p&gt;
&lt;p&gt;I want hetero people to discuss their experience with homophobia. Homophobia has come so far that men are scared to touch each other. If that phrase made you snicker, that&#x27;s exactly what I mean. Some experts believe this is contributing to the exploding numbers of male suicide we have been seeing over the years (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.who.int&#x2F;data&#x2F;gho&#x2F;data&#x2F;themes&#x2F;mental-health&#x2F;suicide-rates&quot;&gt;WHO 2019&lt;&#x2F;a&gt;; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;journals.plos.org&#x2F;plosone&#x2F;article?id=10.1371&#x2F;journal.pone.0128180&quot;&gt;Player et. al. 2015&lt;&#x2F;a&gt;; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pubmed.ncbi.nlm.nih.gov&#x2F;33751613&#x2F;&quot;&gt;River &amp;amp; Flood 2021&lt;&#x2F;a&gt;). Homophobia is literally killing men. Don&#x27;t you think that&#x27;s worth talking about?&lt;&#x2F;p&gt;
&lt;p&gt;I want men to discuss their experience of misogyny. Of how they&#x27;re scared to give someone a genuine compliment for a look that they are just rocking, even if it&#x27;s totally benign. Or talk about their emotions and how sometimes women make that difficult for them. I think this passage from Brené Brown&#x27;s book &quot;Rising Strong&quot; illustrates this point best:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Last night, [Brené&#x27;s husband] had a dream that I had all five of the kids on the raft, and we were halfway across the cove when a speedboat came hauling towards us. I waved my hands in the air and they didn&#x27;t even slow down. I finally grabbed all five of the kids and went as deep as I could go. […] I held them down there and waited for the boat to pass over us. I knew if we surfaced, we&#x27;d be killed. But then I looked over at Charlie and saw he was out of breath. I knew he would drown if we stayed down there for one more minute. […]&lt;&#x2F;p&gt;
&lt;p&gt;&quot;I&#x27;m so glad you told me, Steve.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;He rolled his eyes. &quot;Bullshit,&quot; […] &quot;Look, don&#x27;t quote your research to me. Please. Don&#x27;t tell me what you think you&#x27;re supposed to say. I know what you want. You want the tough guy. You want the guy who can rescue the kids in the path of a speeding boat by throwing them to shore and swim so fast that he&#x27;s there to catch them before they land. The guy who then looks over at you across the cove and shouts, &#x27;Don&#x27;t worry, babe! I got this!&#x27;&quot;&lt;&#x2F;p&gt;
&lt;p&gt;— Brené Brown, Rising strong. p. 21-22&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Don&#x27;t you think men should be allowed to talk about something as scary as losing their children and not feeling they can do anything about it? I know plenty of men who are scared to just admit that they love their children and would be devastated if they lost them.&lt;&#x2F;p&gt;
&lt;p&gt;I want cisgender people to talk about how transphobia affects them. How their choices and behaviours need to be controlled to avoid negative perceptions. If you&#x27;re wondering what I mean, just have a look at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;AskReddit&#x2F;comments&#x2F;374cg7&#x2F;men_of_reddit_what_feminine_thing_do_you_wish_was&#x2F;&quot;&gt;this Reddit thread&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;AskReddit&#x2F;comments&#x2F;5rz08z&#x2F;men_of_reddit_what_is_something_feminine_that_you&#x2F;&quot;&gt;this one&lt;&#x2F;a&gt;. Men often feel restricted from doing simple things like sitting down to pee or taking care of their skin, and even from treating others with respect without being seen as weak.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;holding-mirrors&quot;&gt;Holding mirrors&lt;&#x2F;h2&gt;
&lt;p&gt;If we want people to talk about these things (and I do), that means we have to make it safe or at least possible for them to do so. This is going to require grace both from the people messing up and from the people doing the correcting. People who don&#x27;t know better are going to mess up. Guaranteed. By definition even. And when they do, it is on us to invite them back into the fold and on them to listen and try to leave their ego at the door. This is how people learn.&lt;&#x2F;p&gt;
&lt;p&gt;If we want to do this, we cannot start a crusade against anyone slipping up. We cannot teach people by simply repeatedly telling them they should already know something. This is HARD work, absolutely, and you&#x27;re not always going to be able or willing to do it. That&#x27;s okay. But I hope you will when you feel able to. Some absolutely amazing resources on how to do this is are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Loretta J Ross&#x27;s TED talk on the matter: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=xw_720iQDss&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=xw_720iQDss&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Brene Brown&#x27;s books &quot;Daring Greatly,&quot; and &quot;Rising strong.&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you belong to a marginalised group, you might feel frustrated about having to educate others in addition to dealing with everyday challenges. And you&#x27;re right, it is totally unfair. I hate it as much as anyone. But the truth of the matter is that this is not a question of fairness, but of tactics. If we want our movements to keep growing and achieving things, we need to pull people in, not push them out. And sometimes that means accepting unfairness.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not saying that it&#x27;s your responsibility as someone who is marginalised to listen to this. You are not obligated to do this work. Your priority should be to keep your own head above water. However, I hope that if you have that energy, you&#x27;ll allow people to come closer, or try to get closer to others. Marginalisation has a breath-taking depth and complexity to it, and we can learn from that whether we have that experience or not. Sometimes, all we have to do to benefit from it is allow it in, in whatever way we can.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Diving into something nu</title>
        <published>2023-12-10T00:00:00+00:00</published>
        <updated>2023-12-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/diving-into-something-nu/"/>
        <id>https://slowcoder.org/blog/diving-into-something-nu/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/diving-into-something-nu/">&lt;p&gt;Nushell is a cool new project that attempts to implement cool ideas. I was alerted to its existence by a colleague of mine, and I tried to daily drive it for a while. I have a lot of opinions about it so let&#x27;s talk about it!&lt;&#x2F;p&gt;
&lt;p&gt;First some context. Nushell is a new shell in the vein of bash and zsh written in Rust. To show my hand up front: I agree with the philosophy and design behind nushell, but the experience was just too painful for me to recommend it. I am going to say some negative things about the project, but I hope this will come across as constructive because that is how I mean it. It is a wonderful and ambitious project and I wish it the very best, and at the very least I&#x27;ll be monitoring this. Once the project matures and the developers have worked out some of the kinks I will mention in this article, I&#x27;ll be happy to give it another try.&lt;&#x2F;p&gt;
&lt;p&gt;Having got that out of the way, let&#x27;s start with the stakes. Who cares if nu may or may not be a better shell? Well, approximately 80% of how I interact with my computer is through a terminal, which means going through a shell, so a shell colours how I interact with everything. So, the stakes are quite high as far as choosing software goes. If it&#x27;s better, I stand to gain a lot of productivity, but if it isn&#x27;t, well... (this is what we in the biz call &quot;foreshadowing&quot;)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-obligatory-history-lesson&quot;&gt;The obligatory history lesson&lt;&#x2F;h2&gt;
&lt;p&gt;But, before we discuss nu, we first have to cover POSIX compliance. I know it&#x27;s a tedious detour, but stick with me because it&#x27;s going to be important for the discussions. Besides, because it&#x27;s so boring, few people (including me until I started writing this post) know what it means to be POSIX compliant. Because POSIX is much larger and more complicated than what we need here, I will not dive into POSIX itself, but I&#x27;m going to use an analogy. As always, purists can send their complaints to &lt;a href=&quot;mailto:screaming@intothevoid.parody&quot;&gt;screaming@intothevoid.parody&lt;&#x2F;a&gt; and my team and I will attempt to address your concern as soon as possible.&lt;&#x2F;p&gt;
&lt;p&gt;So here is my analogy: POSIX is similar to the USB standard. It&#x27;s a specification that tells applications what they minimally need to be able to do to work with other USB applications. USB application that one might work with might very well be able to do more than what the specification prescribes, but you can&#x27;t guarantee it. For POSIX, and specifically as it relates to shells, this includes, but is not limited to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Handling signals from the OS&lt;&#x2F;li&gt;
&lt;li&gt;How you&#x27;re supposed to interpret strings, quotes and escaping&lt;&#x2F;li&gt;
&lt;li&gt;How you can set environment variables&lt;&#x2F;li&gt;
&lt;li&gt;What keywords need to be language reserved&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So it defines both what a shell must be able to do at a minimum, but also tells applications developed for POSIX systems what they can expect and how. This is to ensure compatibility between systems. POSIX is perhaps less relevant now than it was at its inception, but that was the basic idea. And just as you can plug any USB device into any USB port and it isn&#x27;t guaranteed to work, but has a much better chance to, things that are developed for POSIX systems have a much higher chance of working on other systems. This is the reason things developed for, e.g. bash, might work on zsh if you&#x27;re lucky.&lt;&#x2F;p&gt;
&lt;p&gt;For this reason I&#x27;m just going to talk about bash, zsh and other POSIX compliant shells interchangeably for the rest of this blog post. We greatly appreciate your understanding and flexibility on this issue.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-m-not-like-other-shells&quot;&gt;I&#x27;m not like other shells&lt;&#x2F;h2&gt;
&lt;p&gt;So why are we talking about this? To answer that I&#x27;m going to quote from the Nushell website:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;non-goals&quot;&gt;Non-goals&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;[...]&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;POSIX-compliance&lt;&#x2F;em&gt;. Nu intentionally optimises for a pleasant experience over matching how commandline programs work in a POSIX-compliant way. It&#x27;s important to be able to interop between Nu commands and external commands, but maintaining strict compatibility is a non-goal.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Paradigm adherence&lt;&#x2F;em&gt;. Nu looks at the shell space flexibly, and borrows good ideas where possible from functional programming, systems programming, OOP, and more. Following any particular paradigm rigidly does not serve the goals of the Nu project.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I think the philosophy behind Nu is great, and the design is very well done. I also think that the decision to not be POSTIX compliant was one they took very deliberately, and I commend them for that bravery. However, I must also say that Nu pays a very hefty price for it.&lt;&#x2F;p&gt;
&lt;p&gt;As a prime example of this, it means that it cannot (or should not) be your login shell, as mentioned in their documentation (source):&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Warning:&lt;&#x2F;p&gt;
&lt;p&gt;Nu is still in development and is not intended to be POSIX compliant. Be aware that some programs on your system might assume that your login shell is POSIX compatible. Breaking that assumption can lead to unexpected issues.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This means that Bash has to remain your login shell and always call nushell as a form of bootstrapping. This may seem harmless but had quite a nasty implication for me. Because bash and not nu is your login shell, it means that subprocesses get spawned into a Bash shell. The process may thus latch onto any settings they can find there first, before they get to nu. So now you have to do double bookkeeping to keep bash and nu in sync. I hope I don&#x27;t have to explain how much of a drag that is.&lt;&#x2F;p&gt;
&lt;p&gt;Many applications that need to change your environment (which is a lot of them) will try to use your login to suggest the changes to make when you install them. This means that you then have to take all of those applications, which they developed for a POSIX environment, and figure out how to apply that to your new nushell environment. It&#x27;s not a showstopper most times but was also just too much effort in some cases and caused me to abandon some tools during the time I was using it. It was just another paper cut. I recognise that this is one that will hopefully become less relevant as the project grows and gains wider support, but it&#x27;s still important to mention. Because Nu is incompatible in some ways, I don&#x27;t see any remedy to this except for all the relevant projects to add support for it themselves.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily, a lot of rust projects that I already use as my daily driver already have support for nushell. This includes things like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ajeetdsouza&#x2F;zoxide&quot;&gt;zoxide&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;starship&#x2F;starship&quot;&gt;starship&lt;&#x2F;a&gt;, etc. etc. So those switch overs were relatively easy. This didn&#x27;t apply to all of them, though. For example, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;denisidoro&#x2F;navi&quot;&gt;navi&lt;&#x2F;a&gt;, which is a nice cheat sheet utility, does not yet (at the time of writing this) have support for this. I have looked into adding this functionality myself, though I&#x27;ll discuss my contributions to nushell later.&lt;&#x2F;p&gt;
&lt;p&gt;When I looked at it, there was a project underway to support the core util tools. However, that project had only just started during my time with it. Nu offers ways to deal with non-nu tools like the core utils (things like &lt;code&gt;cat&lt;&#x2F;code&gt; &lt;code&gt;sed&lt;&#x2F;code&gt; &lt;code&gt;cp&lt;&#x2F;code&gt; etc. etc.), but crossing the boundary is very awkward. And because of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Unix_philosophy&quot;&gt;unix philosophy&lt;&#x2F;a&gt; (programmes should do one thing, one thing only, do it well, and be composable), you&#x27;re gonna be crossing that boundary often.&lt;&#x2F;p&gt;
&lt;p&gt;For example, I went down several days&#x27; worth of rabbit holes to integrate the &lt;code&gt;wc&lt;&#x2F;code&gt; tool (a programme to determine word counts in a file) into nushell so I could use it. Now I enjoy contributing to projects, especially as a way of learning. I did not have to do it, so I don&#x27;t hold that against it, however the first interaction was quite painful. In bash on the other hand, I&#x27;m likely to just slice out the only bit of output I need and just work further on that. However, because nushell relies on structured data, I found it more necessary to parse outputs in their entirety and using regex a lot more than I otherwise would be likely to do. This slowed me down a lot, and was not a great experience, if I&#x27;m honest.&lt;&#x2F;p&gt;
&lt;p&gt;Another problem is that random other scripts you might find on the internet to do quite important things for you, such as the somewhat famous &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ThePrimeagen&#x2F;.dotfiles&#x2F;blob&#x2F;master&#x2F;bin&#x2F;.local&#x2F;scripts&#x2F;tmux-sessionizer&quot;&gt;&lt;code&gt;sessionizer&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; script written by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ThePrimeagen&quot;&gt;The Primeagen&lt;&#x2F;a&gt; no longer work. Sometimes this is not an enormous deal, but I consider it unfeasible to port something like the rustup install script to nushell.&lt;&#x2F;p&gt;
&lt;p&gt;This means that once you have to use one of these, you once again have to escape to bash. This is not only awkward but with installations, it is also a bit of a crap shoot whether nushell will find your installation once you go back to it. I&#x27;ve had more than a few problems with this while I was trying Nu. As with many a daring and uncharted greenfield project, you had better be ready to DIY a lot for what you need. I am fine with that, but I also cannot deny that it is a lot of work. So take this as a &quot;Caveat emptor&quot;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sorry-i-no-speak-english&quot;&gt;Sorry, I no speak English&lt;&#x2F;h2&gt;
&lt;p&gt;(just FYI, that title is supposed to be read in a very heavy Dutch accent. Thank you for your cooperation.)&lt;&#x2F;p&gt;
&lt;p&gt;One of Nu&#x27;s major philosophies is that everything is data (think data frames and structs), instead of text, as UNIX conceptualises it. Just like Rust, it also puts a lot of emphasis on error handling. An attitude that I can only applaud.&lt;&#x2F;p&gt;
&lt;p&gt;I like the paradigm nushell goes for a lot better than that of bash. However, nushell suffers from the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;helix-editor&#x2F;helix&quot;&gt;helix&lt;&#x2F;a&gt; problem. It is better, but because it departs from a very dominant and ubiquitous paradigm, it will also be fighting an uphill battle. Programming in nushell is hard, especially if you have any amount of pre-existing bash muscle memory.&lt;&#x2F;p&gt;
&lt;p&gt;For example, one of the most ubiquitous workflows in shell scripting, executing a script that doesn&#x27;t exist yet because you&#x27;re going to download it as part of the setup, is impossible. To quote the documentation:&lt;&#x2F;p&gt;
&lt;p&gt;Thinking in Nushell: Nushell is designed to use a single compile step for all the source you send it, and this is separate from evaluation. This will allow for strong IDE support, accurate error messages, an easier language for third-party tools to work with…&lt;&#x2F;p&gt;
&lt;p&gt;As with many of the things Nu does, I love this in a vacuum, but it causes paper cuts in day to day use. For example, this also means it&#x27;s impossible to do something like &lt;code&gt;eval &quot;$(zoxide init zsh)&quot;&lt;&#x2F;code&gt; to set up your environment. You have to put the output of that command into a file and then source that, so now you have an extra dotfile to manage. This on its own maybe isn&#x27;t that big of a deal, but what is a big deal is that a lot of other applications assume you can, like the aforementioned rustup installation script.&lt;&#x2F;p&gt;
&lt;p&gt;Over the years I have amassed a massive number of dotfiles, aliases, functions and other semi-ad hoc utilities I use all day, every day. Having to port over these tools to nushell was quite the task. Nu is quite a different beast to any shell language I&#x27;ve used before. This is one reason that I&#x27;ve looked at nu shell multiple times but never took the plunge into driving it daily. It was a good way to get familiar with the Nu language, but it was quite difficult to wrap my head around.&lt;&#x2F;p&gt;
&lt;p&gt;Programming in shell scripting languages like Bash is a craft of its own, as we would say in Dutch. It is heavy on string manipulation to produce the correct commands stuck together with duct tape and wishful thinking. This can lead to systems and tools that can be very brittle. There is a reason some people consider bash to be a write only language. Its syntax is dense and, because of some very weird quirks, it has a lot of gotchas. However, because it is the Lingua franca of Linux systems, I have learnt to wield it efficiently. Not only do I lack the efficiency with the Nu language, but sometimes it hurts me to have the bash way of thinking. Another paper cut. I don&#x27;t think there is any way to remedy this. It is simply a consequence of the current landscape we exist in and the design decisions the nu shell project made. It&#x27;s brave and innovative, but it still means you have to deal with the consequences.&lt;&#x2F;p&gt;
&lt;p&gt;As a data scientist I was also extremely excited to learn that Nu has built-in support for polars data frames. However, I&#x27;m sad to say that the syntax is much too awkward to use. I had some hope that I could leave python at the door for small workloads and just use my shell. Not having to manage python installations and environments is an amazing prospect, but as it stands, that will not happen. The difference between what is an expression, what is a lazy or an eager frame and the necessity to prefix everything with &lt;code&gt;dfr&lt;&#x2F;code&gt;, among others, makes this a no go. For context, I have a simple script that does some mild transformation on the csv of transactions my bank exports so I can import it in my finance tracking software. Trying to port this simple script over to nu, even though they both use polars, was frustrating and confusing to where I just gave up. I love this idea and I hope the team continues to develop it, but as it stands, for a data scientist, it is not usable at all.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;read-the-friendly-manual&quot;&gt;Read the friendly manual&lt;&#x2F;h2&gt;
&lt;p&gt;During the porting of my current environment, I had to visit the documentation of nushell often. This is not a problem on its own. However, nushell&#x27;s documentation was very immature when I used it. They generate the code in the same structure as the underlying code is structured, not according to how you might use it. This is not a cardinal sin or anything, but it is quite unintuitive if you&#x27;re new to the project.&lt;&#x2F;p&gt;
&lt;p&gt;Besides that, the documentation also lacks some very familiar QoL features, such as breadcrumb navigation or the ability to go up a level in the hierarchy. This made the documentation confusing to navigate through any other means than through the search bar. Even when you found something, it wasn&#x27;t clear in which section you found it, so you couldn&#x27;t make a mental note of where it was for next time. This is easy enough to fix by simply adding these elements, but they make quite a big difference.&lt;&#x2F;p&gt;
&lt;p&gt;The documentation (as opposed to the cookbook) was also very, very example focused with very little context around it. This is usually not too bad, but here, in the new paradigm, I found it very difficult to find and understand what I needed. A bit more context would have been nice, you know?&lt;&#x2F;p&gt;
&lt;p&gt;There were also several parts of the language that were just not in the documentation at all. I only found out about them by talking to a maintainer on discord. Again, I don&#x27;t mind this as it&#x27;s something you get used to when using open source software for a while, but it&#x27;s not very scalable if the project plans to keep growing. This is absolutely something that will mature along with the project, but if nu wants to improve on this, I would advise them to create a bit more flow in the documentation rather than letting it be just a collection of examples with no context.&lt;&#x2F;p&gt;
&lt;p&gt;Aside from the API documentation, there is also the cookbook, which is great for the bits that are there. However I found it is also missing a lot of material. Again, the documentation is quite terse there with little context or flow to it. So while I commend the work that has been done, I am afraid I cannot in good faith give nu&#x27;s documentation a passing grade for the experience I had with it.&lt;&#x2F;p&gt;
&lt;p&gt;Nushell also features a robust testing framework built in. This is one thing that I have found lacking in bash a few times, so I am thrilled to see this. However, because of the tricky nature of nu&#x27;s import system and the ad hoc nature of using a shell language, I found this very difficult to use to its full potential. When you do shell programming, I rarely have a neat project structure for functions and scripts that I&#x27;m working on, which makes the testing framework somewhat cumbersome to deal with, especially since you also have to deal with setup and teardown.&lt;&#x2F;p&gt;
&lt;p&gt;This one I&#x27;m not entirely sure how to remedy. It&#x27;s tricky, especially given the ad hoc nature of shell programming (at least for me), but I think it helps for tools you intend to have around for longer. Some more documentation around the import system might be nice too, as I remember being confused about that for some time (although I don&#x27;t remember what I was actually confused about, sorry). The foundation of the testing system, however, is solid and I hope to see it develop further.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;So, do I think nushell is better than bash or zsh? Yes. Will I be using it? Unfortunately, no. For me, nu is to bash as DVORAK is to QWERTY. I believe it is better, but because of the ubiquity of the latter I cannot in good conscience switch over to it. The muscle memory needed for either is incompatible with the other, and the former isn&#x27;t widespread enough for me to work in that system most of the time. Especially given the DevOps like nature of my current job, this is just a no go for me.&lt;&#x2F;p&gt;
&lt;p&gt;I am very sad so say that I have switched back to zsh since trying nushell. The team behind nushell deserves praise for all the amazing work and innovation they have done and continue to do. I will be cheering them on from the sideline, and I will happily try again sometime down the line, but for now, it is just too immature for me to justify using it as a daily driver.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Life skill: No False Options</title>
        <published>2023-12-03T00:00:00+00:00</published>
        <updated>2023-12-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/no-false-options/"/>
        <id>https://slowcoder.org/blog/no-false-options/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/no-false-options/">&lt;p&gt;Let me tell you a story. Sometimes, my mother will ask my father something like &quot;would you like a biscuit with your coffee?&quot; And sometimes, he will say, mostly without thinking, &quot;hmm, that might be nice, do you have?&quot; to which she will reply &quot;if I didn&#x27;t have, I wouldn&#x27;t have offered it.&quot; I&#x27;ve codified this into a rule of thumb for myself that I call &quot;No False Options&quot;. It says that you should only ever give people options you are okay with them choosing.&lt;&#x2F;p&gt;
&lt;p&gt;On the face, this seems deceptively obvious. However, it&#x27;s also something that is surprisingly easy to trip up on once you apply it to more complex situations. Not only is this something that has benefited my relationships, but it has also given me much clarity, as I&#x27;ll illustrate later. I&#x27;m hoping that with this article I can give you some inspiration to create honesty for yourself in your own relationships, whether they be to people, or concepts like your career. I really hope it will bring you as much as it has me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;anyone-else-hearing-the-jaws-theme-in-the-background&quot;&gt;Anyone else hearing the jaws theme in the background?&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s start off with some groundwork. Why should you not give people false options? Putting aside the moral implications of lying for a moment. A false option is neutral in the case you don&#x27;t know they&#x27;re there, but incredibly annoying at best and potentially devastating at worst when you find out.&lt;&#x2F;p&gt;
&lt;p&gt;When you give someone a false option, there is a tension to it. Will they choose the option you don&#x27;t want them to take? Will they &quot;call your bluff&quot;? Because giving someone a false option is gambling that someone will choose the way you think they will. Think of the classic movie ultimatum: &quot;it&#x27;s X, or it&#x27;s me&quot;. Nobody ever says that, thinking you&#x27;ll choose the option that is not them. But it is, however, still a gamble and that is where the tension comes from.&lt;&#x2F;p&gt;
&lt;p&gt;Because what you&#x27;re doing, in that situation, is trying to convince people to do something that is beneficial to you, all the while making them think they were actually the one to make that choice. This makes giving false options either lying, manipulating, or both, depending on your perspective.&lt;&#x2F;p&gt;
&lt;p&gt;I have found that this changes how I engage with people. Perhaps this also just is because I&#x27;m quite a risk-averse person, but I cannot stand the idea of giving people false ultimatums, both from a moral and tactical point of view. I realise that I&#x27;m subject to a very particular culture that values direct communication pretty highly and that this might not translate to other situations, but I&#x27;d much rather explain my reasoning for not giving someone an option. I&#x27;m not saying that there is no situation in which you can&#x27;t give ultimatums, but trying to be mindful of that dynamic has helped me a lot.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;whatever-nerd-what-s-in-it-for-me&quot;&gt;Whatever nerd, what&#x27;s in it for me?&lt;&#x2F;h2&gt;
&lt;p&gt;Luckily, the flip side is also true. Offering no false options does not mean that you cannot hope for them to make a particular choice, but it is important that you can accept any choice they make. This gives people much more confidence in making choices they get from you. It means they are truly free to consider the choice on their own terms. This was really liberating for me, even from the perspective of the one who offers the choices.  &lt;&#x2F;p&gt;
&lt;p&gt;Another point that comes hand in hand with this rule is that once you give someone an option and they choose it, you have to accept it. This again can be harder than you&#x27;d think.&lt;&#x2F;p&gt;
&lt;p&gt;Consider for example, the question &quot;do you need help in the kitchen?&quot; In a lot of situations, there is an implicit assumption that if people say no, they are lying for the sake of politeness. However, part of &quot;no false options&quot; is that you have to respect people&#x27;s choices. Most times, I think that means taking their choices at face value. If they say they don&#x27;t need help, I will do nothing. This can take some getting used to in your relationships, especially if you&#x27;re used to a lot of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;research.vu.nl&#x2F;en&#x2F;publications&#x2F;implicit-communication-in-organisations-the-impact-of-culture-str&quot;&gt;implicit communication&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Impact_of_culture_on_aviation_safety&quot;&gt;like aviation pilots&lt;&#x2F;a&gt; as described in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;3228917-outliers&quot;&gt;Malcolm Gladwell&#x27;s Outliers&lt;&#x2F;a&gt;. I think, however, it&#x27;s a worthwhile skill training. It helps people gain trust in you, even if it&#x27;s sometimes uncomfortable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;okay-sure-sounds-cool-how-though&quot;&gt;Okay, sure, sounds cool. How though?&lt;&#x2F;h2&gt;
&lt;p&gt;Here are the more tricky bits. If you want to commit to &quot;no false options&quot;, how can you do this? Well, let me go over some key components that will hopefully save you some pitfalls.&lt;&#x2F;p&gt;
&lt;p&gt;It is important that you know what all the options are. Sometimes you think you&#x27;re okay with an option, but you later discover you&#x27;re not. At that point you should at least make a mental note not to offer that option in the future.&lt;&#x2F;p&gt;
&lt;p&gt;For example: In my eyes, responsibility and autonomy come hand in hand. If you give someone no autonomy, that also means that they have no responsibility. This point comes up during my work remarkably often. I used to think to myself that &quot;I&#x27;m fine with either option, you give me autonomy and let me take responsibility for things or, you micro manage me and don&#x27;t hold me responsible for what are now your decisions.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;However, after some careful consideration, I&#x27;ve discovered that I&#x27;m not okay with the latter option. I just don&#x27;t have it in me to follow people blindly. I can do it for a while, especially if it&#x27;s keeping the peace, but as I&#x27;ve progressed in my career, I&#x27;ve realised that I can only do that for very limited periods of time. It just eats away at me when I have to do things I don&#x27;t agree with or I think are likely to give bad outcomes. I like to be proud of the work that I do, and if I can&#x27;t work in a manner that I think I can be proud of, I will become very unhappy and unmotivated. So I&#x27;ve stopped giving people that option.&lt;&#x2F;p&gt;
&lt;p&gt;Which leads me into the next topic: what if &quot;no false options&quot; means giving them no option at all? For example, take the ultimatum of &quot;it&#x27;s either X, or me&quot; I gave earlier. If you truly cannot live with X, should you make them stop? Should you make them go away? What about their agency in this situation?&lt;&#x2F;p&gt;
&lt;p&gt;Well, as I said, I&#x27;m not trying to say that giving ultimatums is out of the question. But one of the harder parts of &quot;no false options&quot; is how to do it and still leave the other party with agency, especially in situations where there isn&#x27;t a lot of agency to go around.&lt;&#x2F;p&gt;
&lt;p&gt;Here, there are several important but subtle distinctions. First, &quot;no false options&quot;, is not about not giving options that are impossible, but also about not giving options which may be possible but not acceptable to you. In the ultimatum example, the other party can hypothetically leave. What makes it a false option or not is whether you are willing to accept that. This means that it is very hard to say anything specific about false options because they are entirely subjective.&lt;&#x2F;p&gt;
&lt;p&gt;The other distinction I want to make is about delivery. Saying &quot;It&#x27;s X or me&quot; when you are gambling on things going your way is manipulative. Saying &quot;Sorry but I cannot live with this, but if you wish to choose your life this way, I wish you the best&quot; is very different. Few things feel as bad to me as an interaction that goes like so: &quot;Do you want A or B?&quot; &quot;I want B&quot; &quot;Well I want A, so you&#x27;re gonna do A&quot;. I realise that this is preference but in that situation I&#x27;d much rather be told that &quot;You have to do A, that&#x27;s just the only viable option.&quot; I&#x27;ve found that, if delivered correctly, most people respond best to that, even if they haven&#x27;t told me that&#x27;s what they prefer.&lt;&#x2F;p&gt;
&lt;p&gt;And in true meta fashion, I believe that &quot;no false options&quot; is an option for anyone. It will require a deft touch to master and a lot of trials and error to see how you can apply this correctly to your own life, but as I am offering this option to you now, it is to the best of my knowledge, not a false one. Good luck.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I accidentally did NaNoWriMo</title>
        <published>2023-11-26T00:00:00+00:00</published>
        <updated>2023-11-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/accidentally-did-nanowrimo/"/>
        <id>https://slowcoder.org/blog/accidentally-did-nanowrimo/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/accidentally-did-nanowrimo/">&lt;p&gt;For the uninitiated: National Novel Writing Month, (NaNoWriMo for short, and nano for even shorter) is an annual event where thousands if not millions of writers around the globe come together in November to write a novel of 50k words, in one month. It&#x27;s a massive event. If you know where to look, you&#x27;ll find comradery, commiseration, complaining, excellent memes, and of course, lots and lots of writing.&lt;&#x2F;p&gt;
&lt;p&gt;50_000 words in a month averages out to more or less 1666 words a day. That might sound doable, but I have always struggled with consistency. Nano is both famous and infamous. Despite having written since my early teenage years, I have never considered taking part in Nano. I&#x27;ve had the dream for a long time to write a book, but I never thought of it as something that I could see myself doing. It just sounded like too big of a task.&lt;&#x2F;p&gt;
&lt;p&gt;However, recently I thought &quot;I have this cool blog I haven&#x27;t touched for way too long&quot;. My WIP folder has been growing for a while and I&#x27;ve never been able to make a good dent in it. So I wanted to piggyback off the energy that others are putting into this and finish a few drafts for the blog this November. I didn&#x27;t set a goal for myself, but I wanted to finish as many drafts as I could and see where I&#x27;d end up. Cool idea right?&lt;&#x2F;p&gt;
&lt;p&gt;Well uh, yeah, check the title of the blog post. I completed nano in just over 20 days. I didn&#x27;t write a novel per se, which is a requirement, but I wrote over 50.000 words in November. And you&#x27;re looking at part of it. I wrote a bunch of blog posts and short stories, including this one, and I&#x27;m proud of it!&lt;&#x2F;p&gt;
&lt;p&gt;Mind you, the spirit of NaNoWriMo is that you just write. You don&#x27;t reread, you don&#x27;t edit, you just keep writing. It&#x27;s a hefty word count. To achieve that word count, people usually encourage each other to get it all out there as fast as they can. You shouldn&#x27;t worry about how good your writing is. If you do that, the writer&#x27;s block might set in again. And we don&#x27;t like writer&#x27;s block, do we?&lt;&#x2F;p&gt;
&lt;p&gt;I have made a lot of good raw material this Novemver. However, it still has a very long way to go. I have to edit, rework, cut, proofread, and correct all of it. So while it will be a while before you see all of it, I thought it was a very cool experience, and I wanted to talk about it here.&lt;&#x2F;p&gt;
&lt;p&gt;One reason I hit the word count is that I found a wonderful website to motivate me to do all that writing alongside the encouragement I got from my friends. The website is called 4thewords.com, and it&#x27;s a wonderful website for gamifying your writing. It&#x27;s like an RPG where you have to battle monsters to power up, get cool stuff, and it just scratches an itch in my brain. A small team in Costa Rica makes the website and I like it very much.&lt;&#x2F;p&gt;
&lt;p&gt;Gamification can be very hit or miss for me, but this one clicked. There are ways you can spend money on it but I feel like the team handled it very well. It&#x27;s very non-intrusive and not too expensive. I&#x27;ve never felt like the monetisation has impacted the experience. This is not in any way sponsored by them. No money is involved, but if you&#x27;re interested, use this referral code (WDKYF65640) to get in-game goodies for both of us. #NotSponsoredJustAFan&lt;&#x2F;p&gt;
&lt;p&gt;The gamification helped me get my words in, even though I was not very consistent in my output, as you can see in this graph of my daily word count:&lt;&#x2F;p&gt;
&lt;div &gt;&lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;slowcoder.org&amp;#x2F;processed_images&amp;#x2F;word-counts.4b55e41f356390dc.webp&quot; alt=&quot;A bar graph of the word counts from 4th to 26th of November. The average is 2580 words per day, but there are two bars in the middle of approximately 8k and 11k words.&quot; &#x2F;&gt;
    &lt;&#x2F;div&gt;
&lt;p&gt;Yeah, I know, that big spike in the middle surprised even me. It surprised me how easy it was to get in all those words.&lt;&#x2F;p&gt;
&lt;p&gt;I had outlines for the blog posts in my WIP folder. I write those when planning a post to avoid forgetting my ideas. In the lingo of Nano, that makes me a plantser (&quot;plantser&quot; is a conjunction of planner and pantser). The planner-pantser spectrum refers to how much you plan out the writing you&#x27;re gonna do. Planners are self-explanatory, but &quot;pantser&quot; is lingo for someone who just likes to Yolo the whole thing. A plantser is someone in the middle of that spectrum. I discovered in this Nano that I enjoy using a basic outline for writing. A nice thing to have learnt about myself, I&#x27;d say.&lt;&#x2F;p&gt;
&lt;p&gt;Another observation worth mentioning is how easy it went. I know I might jinx myself by saying that, but it is true. I don&#x27;t mean it was something that required no effort. It required effort, especially on days where I only got the minimum number of words in. However, it was a lot more manageable than I had expected it to be.&lt;&#x2F;p&gt;
&lt;p&gt;I used to think Nano was only for incredibly dedicated individuals, that they needed months of planning or an iron will or a super well oiled writing workflow, or perhaps both.&lt;&#x2F;p&gt;
&lt;p&gt;Well, now, I&#x27;m here to tell you that this is not the case. It can be about as stressful and momentous as you make it yourself. It can be a lot of fun. I had a blast with it. It feels very good to break through the writer&#x27;s block for once. So don&#x27;t be afraid to try it for yourself.&lt;&#x2F;p&gt;
&lt;p&gt;This work echoes my previous sentiments on &lt;a href=&quot;https:&#x2F;&#x2F;slowcoder.org&#x2F;blog&#x2F;originality-not-required&#x2F;&quot;&gt;unnecessary originality&lt;&#x2F;a&gt;. You can try it without consequences if it doesn’t work out. You don’t need to share if it feels overwhelming.&lt;&#x2F;p&gt;
&lt;p&gt;It was liberating to not worry about your performance and simply put your thoughts on paper. It&#x27;s a quite refreshing palette cleanser, especially if you&#x27;ve been in writer&#x27;s block town for a while.&lt;&#x2F;p&gt;
&lt;p&gt;I would wholeheartedly recommend doing nano. I think I will try it again next year with more preparation and try to write an actual novel. To conclude: don&#x27;t be afraid, trust the process, and go for it. We&#x27;ll all be waiting on the other side, cheering you on.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What women REALLY want</title>
        <published>2023-04-01T00:00:00+00:00</published>
        <updated>2023-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/what-women-really-want/"/>
        <id>https://slowcoder.org/blog/what-women-really-want/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/what-women-really-want/">&lt;p&gt;I don&#x27;t know, why don&#x27;t you go and ask them?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Thoughts from a Rustacean learning React</title>
        <published>2023-01-02T00:00:00+00:00</published>
        <updated>2023-01-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/thoughts-from-a-rustacean-learning-react/"/>
        <id>https://slowcoder.org/blog/thoughts-from-a-rustacean-learning-react/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/thoughts-from-a-rustacean-learning-react/">&lt;p&gt;At &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;source.ag&#x2F;&quot;&gt;Source.ag&lt;&#x2F;a&gt; we have something called Personal Exploration Time (or PET days for short). The idea is that you get some time, usually one day, to explore a topic that you find interesting which may or may not be useful for Source.ag in the long run. The idea is to give new and innovative ideas a bit of room to breathe before they have to prove themselves. It&#x27;s explicitly part of the concept that it&#x27;s okay for them to fail, or conclude that it&#x27;s not that useful. I love these days, because not only can (and have) they lead to new innovative technologies and ideas being used by the company, but they are also great for my motivation. They help break up slumps when I feel stuck, give me time to investigate technologies I&#x27;m really excited about, and just generally let me engage with the creative side of my job.&lt;&#x2F;p&gt;
&lt;p&gt;Just to give you an idea, here are some projects I&#x27;ve done in the past:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Checking out a new data frame library&lt;&#x2F;li&gt;
&lt;li&gt;Checking out a new property-based testing framework&lt;&#x2F;li&gt;
&lt;li&gt;Informally indexing the company&#x27;s yearly CO2e emissions&lt;&#x2F;li&gt;
&lt;li&gt;Making a Python &amp;amp; Rust MVP setup&lt;&#x2F;li&gt;
&lt;li&gt;Optimising some decision rules in our pipeline with bayesian reasoning.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Because so many people took time off over Christmas and we were still busy finalising the roadmap for Q1, rather than have us start on something and put it down immediately again for the holidays, management decided to give the entire cultivate team an extravagant 3-day long stretch of PET at the end of 2022. This did amazing things for the team&#x27;s motivation (or at least for mine), but that&#x27;s not what I&#x27;m here to talk about today. I wanna talk about what I did for those 3 days: Learning React.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-react&quot;&gt;Why React?&lt;&#x2F;h2&gt;
&lt;p&gt;Web and front-end work are subjects I&#x27;ve danced around for a long time. I&#x27;ve always gravitated towards backend and analysis work. On the front end side of things, I don&#x27;t know much beyond the HTML and CSS I needed to make the website you&#x27;re looking at right now. I&#x27;ve tried to learn javascript and its myriad of frameworks before but somehow they never really clicked for me. In addition, design is not something I feel comfortable with either. In code, I don&#x27;t usually suffer from blank-page-paralysis, but in design and UI work it feels very overwhelming for me to even get started.&lt;&#x2F;p&gt;
&lt;p&gt;However, I&#x27;ve felt held back by my inability to make simple UIs for the projects and prototypes that I&#x27;ve made. I can make a CLI with no problem, but those have two very major drawbacks.&lt;&#x2F;p&gt;
&lt;p&gt;First of all, they are just not well suited to every program. I think that CLIs work well if you keep them somewhat contained, but some programs need to facilitate so many different interactions that it&#x27;s not really feasible to do it all ergonomically.&lt;&#x2F;p&gt;
&lt;p&gt;Secondly, when you&#x27;re trying to demo a prototype I think it&#x27;s hard to overstate the value of a good visual component (pun intended). Even from my own experience, it&#x27;s very hard to get a sense of how nice a CLI is without actually using it. For GUIs, however, it&#x27;s different. Even if it&#x27;s not the same as direct experience, with a GUI you can at least get across a decent idea by video, and I&#x27;ve found that to be an incredible tool when I&#x27;m trying to show off an idea to someone.&lt;&#x2F;p&gt;
&lt;p&gt;Not being able to make a UI makes iterating on the (technical) design a lot harder at times. I like to work iteratively, holistically if at all possible, and to do that you need something that will at least resemble what it will look like to the end user. This is why I think it&#x27;s really important to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wiktionary.org&#x2F;wiki&#x2F;dogfood&quot;&gt;dogfood&lt;&#x2F;a&gt; what you build. Backend systems should be in service of the UX, and all too often it&#x27;s the other way around in my opinion. Even CLIs have a UX even though we don&#x27;t usually think of it as being such (and that&#x27;s a problem). This is often why I dislike the old &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;List_of_Unix_commands&quot;&gt;UNIX tools&lt;&#x2F;a&gt; like &lt;code&gt;cat&lt;&#x2F;code&gt;, &lt;code&gt;awk&lt;&#x2F;code&gt;, &lt;code&gt;find&lt;&#x2F;code&gt; and &lt;code&gt;sed&lt;&#x2F;code&gt; even though they work fine and prefer to use modern CLI tools written in Rust whenever possible; their CLIs are just so much more ergonomic in my opinion.&lt;&#x2F;p&gt;
&lt;p&gt;So those are some of the reasons I wanted to get some basic proficiency in building GUIs. But why React specifically? Two reasons. First of all, it&#x27;s one of the more foundational architectures for UIs as far as I can tell.  Almost every new UI library I see these days touts being &quot;like react&quot;, as well as being the topic du jour on the internet when the front end is mentioned. So I figured that even if I didn&#x27;t end up liking React itself enough to use, getting a basic understanding of how React works would help me get familiar with other UI frameworks. Secondly, and perhaps even more importantly, it&#x27;s what Source.ag and by extension my colleagues use, so I knew I&#x27;d have people to go to for help if I needed it. And boy did I end up needing that.&lt;&#x2F;p&gt;
&lt;p&gt;The project I did was a joint one with my wonderful colleague &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nehalicious&quot;&gt;Neha Kalia&lt;&#x2F;a&gt;. We both wanted to learn a new technology so we decided to team up and build a joke app together. She would take care of the backend with Golang, and I&#x27;d get a front end working with React. The extra bonus for me was that Neha also works on our front end and thus is already familiar with React so I could come crying to her whenever things went pear-shaped. And let me just say she was an invaluable resource and an incredible mentor for an FE newbie like myself. Seriously Neha, thanks, you were a lifesaver.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-project-pitch&quot;&gt;The project pitch&lt;&#x2F;h2&gt;
&lt;p&gt;What app did we make, you ask? Well, we built a revolutionary system called &quot;What would my Project Manager say?&quot;. I think I&#x27;ll let it speak for itself:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Is your project manager too busy to talk to you right now? Do you have a burning question about what you&#x27;re supposed to be doing? Then look no further! What would my PM say? (WWMPS) is a state-of-the-art AI system that has learnt from 1000s of project managers throughout time and across the globe. It has distilled and refined all this knowledge and is ready to dispense these life-changing and invaluable insights to you, yes you, at a moment&#x27;s notice.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;At the risk of ruining it by over-explaining: this is a joke. WWMPS is basically a glorified magic 8 ball that will respond to any question you ask it with vaguely PM-sounding snippets like &quot;Have you made a ticket for that?&quot; or &quot;How does this impact the customer?&quot;. And before you ask, yes, I did show it to my actual PM, and she was a real champ about it (Paula, if you&#x27;re reading this, thanks for taking the joke so well, you&#x27;re amazing &amp;lt;3).&lt;&#x2F;p&gt;
&lt;p&gt;If you want to check out the final product yourself you can find the code &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;savente93&#x2F;what-would-my-pm-say&quot;&gt;here&lt;&#x2F;a&gt;. At the time of writing it doesn&#x27;t work because the backend doesn&#x27;t come packaged with it, but I&#x27;ll try and make a dummy version available that actually does something.&lt;&#x2F;p&gt;
&lt;p&gt;This was a really fun project, and as always, I have thoughts and opinions. Lots of them. So I thought it would be fun to talk about some thoughts I had while learning JS and React. The timeline of the project looked vaguely like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Day 1: Learn the basics of React by following a tutorial&lt;&#x2F;li&gt;
&lt;li&gt;Day 2: get some interactions working with dummy data&lt;&#x2F;li&gt;
&lt;li&gt;Day 3: integrate with Neha&#x27;s backend&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;One final disclaimer before we get into it properly: as the title says, these are my thoughts and opinions. This post is not at all meant to be factual or objective. To quote the wonderful YouTuber:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;throughout the course of this [blog] I&#x27;m going to say some mean things. I&#x27;m going to say some nice things! but most importantly I&#x27;m going to be saying some mean things. sorry I mean fair, I&#x27;m going to be fair.&lt;&#x2F;p&gt;
&lt;p&gt;- &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=4hZxo96x48A&quot;&gt;Tentacrul&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So I will be saying mean things throughout this blog but I don&#x27;t want you to come away thinking that I didn&#x27;t like JS or that I think JS should become more like Rust. I actually liked it much more than I expected to but some things that just boggle my mind and I do think they are worth pointing out. I tend to be harshest on things I actually like because I want them to be the best they could be! If I didn&#x27;t like the experience, I wouldn&#x27;t be writing this post. With that out of the way, let&#x27;s get started!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;initial-overall-thoughts&quot;&gt;Initial overall thoughts&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ll be honest, I enjoyed it way more than I had expected. Because I&#x27;d tried JS and React a couple of times before and just bounced straight off I was actually a little nervous before starting. Luckily, I started having a lot of fun with it quite quickly. After it all started to click for me after a few hours, I found the (for me) novel structure and idioms much more refreshing than confusing or frustrating, as I had expected. It also helped that Neha and I had a similar style of humour so I could put lots of stupid jokes in there, which was also super motivating for me.&lt;&#x2F;p&gt;
&lt;p&gt;Another advantage I had was that Neha was building a backend alongside me. Having a backend to integrate with made me get familiar with some problems that I otherwise would not have stumbled over like CORS issues and POST requests. (I&#x27;m a web newbie okay, cut me some slack.)&lt;&#x2F;p&gt;
&lt;p&gt;It also gave me a better understanding of what the FE collaboration workflow looks like, and how dependent FE folks are on backend stuff. If stuff doesn&#x27;t work you sometimes have to sit there twiddling your thumbs for a while, and I think it&#x27;s good to have been on the other end of that for once. There was also some nice back and forth between Neha and me, and I think this ultimately led to nicer designs for both the front end and the back end. Overall, if you ever do a project like this, and you don&#x27;t necessarily need to learn about backend technologies, I&#x27;d still recommend adding a backend to it. It will make the learning experience much more complete and useful even if it&#x27;s technically less focused.&lt;&#x2F;p&gt;
&lt;p&gt;So overall: both the project and React get a thumbs up from me 👍&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-out-of-the-box-experience&quot;&gt;The out-of-the-box experience&lt;&#x2F;h2&gt;
&lt;p&gt;One thing that I actually didn&#x27;t like about React was &lt;code&gt;npm&lt;&#x2F;code&gt;. Coming from Rust, there were definitely a few things that stood out to me.&lt;&#x2F;p&gt;
&lt;p&gt;The first thing is that &lt;code&gt;npm&lt;&#x2F;code&gt;, or at least &lt;code&gt;create-react-app&lt;&#x2F;code&gt; (CRA) actively teaches you not to read its output. Any time you run something like &lt;code&gt;npx create-react-app&lt;&#x2F;code&gt; or &lt;code&gt;npm install&lt;&#x2F;code&gt; it produces one line of text that it continually overwrites, making it impossible to read. This might seem inconsequential but it&#x27;s quite frustrating if something goes wrong because now you have no record of what it was actually doing that led to the problem.&lt;&#x2F;p&gt;
&lt;p&gt;Secondly, when I ran CRA for the first time it immediately slapped me around the head with this warning:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;npm WARN deprecated tar@2.2.2: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;.... Uhm..... am I supposed to do something with that? After a  few minutes of running we also get:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt; added 1397 packages in 1m
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;214 packages are looking for funding
&lt;&#x2F;span&gt;&lt;span&gt;  run `npm fund` for details
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ah, so I&#x27;ve not even done anything and you&#x27;ve already downloaded half the internet on my laptop and are also asking for money? Gotcha. This is a nitpick for sure since other package managers do mostly the same, they just don&#x27;t tell you about it. I also don&#x27;t mind when people ask for money so it&#x27;s not that this is inherently bad, but it is a little weird to do on first contact. At least buy me a drink first, okay?&lt;&#x2F;p&gt;
&lt;p&gt;After some more waiting we get this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;10 high severity vulnerabilities
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;To address all issues (including breaking changes), run:
&lt;&#x2F;span&gt;&lt;span&gt;  npm audit fix --force
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Run `npm audit` for details.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That sounds serious. Did I do something wrong? I only followed the standard instructions so I guess not. I wanna be a good little developer though, so I better try to fix that. Okay, let&#x27;s check what this audit thing has to say.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;nth-check  &amp;lt;2.0.1
&lt;&#x2F;span&gt;&lt;span&gt;Severity: high
&lt;&#x2F;span&gt;&lt;span&gt;Inefficient Regular Expression Complexity in nth-check - https:&#x2F;&#x2F;github.com&#x2F;advisories&#x2F;GHSA-rp65-9cf3-cjxr
&lt;&#x2F;span&gt;&lt;span&gt;fix available via `npm audit fix --force`
&lt;&#x2F;span&gt;&lt;span&gt;Will install react-scripts@4.0.3, which is a breaking change
&lt;&#x2F;span&gt;&lt;span&gt;node_modules&#x2F;svgo&#x2F;node_modules&#x2F;nth-check
&lt;&#x2F;span&gt;&lt;span&gt;  css-select  &amp;lt;=3.1.0
&lt;&#x2F;span&gt;&lt;span&gt;  Depends on vulnerable versions of nth-check
&lt;&#x2F;span&gt;&lt;span&gt;  node_modules&#x2F;svgo&#x2F;node_modules&#x2F;css-select
&lt;&#x2F;span&gt;&lt;span&gt;    svgo  1.0.0 - 1.3.2
&lt;&#x2F;span&gt;&lt;span&gt;    Depends on vulnerable versions of css-select
&lt;&#x2F;span&gt;&lt;span&gt;    node_modules&#x2F;svgo
&lt;&#x2F;span&gt;&lt;span&gt;      @svgr&#x2F;plugin-svgo  &amp;lt;=5.5.0
&lt;&#x2F;span&gt;&lt;span&gt;      Depends on vulnerable versions of svgo
&lt;&#x2F;span&gt;&lt;span&gt;      node_modules&#x2F;@svgr&#x2F;plugin-svgo
&lt;&#x2F;span&gt;&lt;span&gt;        @svgr&#x2F;webpack  4.0.0 - 5.5.0
&lt;&#x2F;span&gt;&lt;span&gt;        Depends on vulnerable versions of @svgr&#x2F;plugin-svgo
&lt;&#x2F;span&gt;&lt;span&gt;        node_modules&#x2F;@svgr&#x2F;webpack
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Uhmmm, what does that even mean? This gives me no useful information. Okay, let&#x27;s try applying the fixes. &lt;code&gt;npm audit fix&lt;&#x2F;code&gt; didn&#x27;t seem to do anything though... Okay well, I guess I&#x27;ll try the &lt;code&gt;--force&lt;&#x2F;code&gt; option then? No idea what&#x27;s gonna happen but we&#x27;ll give it a shot and see where we land.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;npx audit fix --force
&lt;&#x2F;span&gt;&lt;span&gt;  npm WARN using --force Recommended protections disabled.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Huh?! I thought you told me to do this?! What the heck is going on here?! And to top it all off we end with this message:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;39 vulnerabilities (2 moderate, 29 high, 8 critical)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What?! So in addition to making me stressed and confused you also only made the issue worse?! This is something I&#x27;d expect from a personal project, not industry-standard software. Some googling later I found out the solution is &quot;don&#x27;t even worry about it, it&#x27;s fine, trust me.&quot; Okay. sure. got it. Delete the now broken project and start from scratch. This time I&#x27;m just gonna skip over all the warnings. My conclusion: don&#x27;t listen to &lt;code&gt;npm&lt;&#x2F;code&gt;, it only makes things worse. I don&#x27;t understand why this is considered an okay state of affairs. It&#x27;s not a good look fam.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-dev-experience&quot;&gt;The dev experience&lt;&#x2F;h2&gt;
&lt;p&gt;After the tussle with npm and finally getting the project set up, it was time to get started. What I usually do is get the bare minimum information about how the language works and then just dive into a project, researching relevant topics as they come up. This is what I originally did way back when I tried to learn React for the first time and.... it did not work, but let me get back to that later.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily this time around I had Neha to help me. She provided me with a really good tutorial. It took me through all the required steps and major mechanics that I initially just typed along with. It took me through all the major mechanics and idioms I&#x27;d need to get up and running. Neha also provided me with moral support and helped me get to grips with the counterintuitive stuff when I was stuck.&lt;&#x2F;p&gt;
&lt;p&gt;I must say, by the end of this, I actually feel somewhat competent with React. At least enough to understand basic React code and build basic interfaces for my prototypes, so in that regard, task accomplished! While the &lt;code&gt;npm&lt;&#x2F;code&gt; bit was not great, I must say that React itself is actually fairly beginner friendly once you get over the initial hump of understanding things like &lt;code&gt;useState&lt;&#x2F;code&gt; and &lt;code&gt;useEffect&lt;&#x2F;code&gt;. Credit where credit is due.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s come back to how I learn languages for a minute. The bit that I now realise this process relies on is for the language and the tools to actually tell you where you did something wrong and what you need to research to fix it. Sadly... this does not work in JS. The reason for this is basically exemplified by one of my favourite ancient memes: &lt;div &gt;&lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;slowcoder.org&amp;#x2F;processed_images&amp;#x2F;js.a83a36a9d74d4ac7.webp&quot; alt=&quot;Caption reads &amp;#x27;when you mistype x=obj.field instead of x= obj.field&amp;#x27; C++ at compile time: &amp;#x27;wrong, wrong! stop everything&amp;#x27;. Python at compile time: &amp;#x27;hmm maybe that&amp;#x27;s right?&amp;#x27; Python at Runtime: &amp;#x27;no wait, that&amp;#x27;s wrong!&amp;#x27;. Javascript at compile time: *shrug emoji*. Javascript at runtime: *shrug emoji*&quot; &#x2F;&gt;
    &lt;&#x2F;div&gt;
When you make a mistake JS is very happy to just keep going even if it makes no sense to do so. This means that I have to figure out on my own what I even need to research to figure out what I did wrong.&lt;&#x2F;p&gt;
&lt;p&gt;This also brings me to the next point: debugging. it&#x27;s terrible. At least in my opinion. For example, just to see if I understood how things worked, I wanted to make a button that would only show questions with an even number of upvotes. So I started out with the following code (only the relevant bits):&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;js&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;evenUpvotePostsOnly&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;setEvenUpvotePostsOnly&lt;&#x2F;span&gt;&lt;span&gt;] = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;useState&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;toggleEvenUpvotePostsOnly &lt;&#x2F;span&gt;&lt;span&gt;= () &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;=&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;setEvenUpvotePostsOnly&lt;&#x2F;span&gt;&lt;span&gt;(!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;evenUpvotePostsOnly&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;historicalQuestions&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;filter&lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;resp&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;toggleEvenUpvotePostsOnly &lt;&#x2F;span&gt;&lt;span&gt;=== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;resp&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;votes &lt;&#x2F;span&gt;&lt;span&gt;% &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;=== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; })
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Can you spot the mistake? I tried to assert whether the &lt;em&gt;function&lt;&#x2F;em&gt; was equal to &lt;code&gt;true&lt;&#x2F;code&gt; not the &lt;em&gt;variable&lt;&#x2F;em&gt;. My understanding was that this was exactly what the &lt;code&gt;===&lt;&#x2F;code&gt;  as opposed to &lt;code&gt;==&lt;&#x2F;code&gt; was for because the former wouldn&#x27;t do type conversion for you, but it was very happy to carry on with this code which then always returned true without any warning. This took me an hour and two trips to Neha to figure out. This was a bad experience for me.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been told that this is partially what TypeScript was invented to solve, but still. If TS is anything like MyPy it does help, but doesn&#x27;t solve the issue in my opinion. I find issues like these are incredibly frustrating. The fact that nothing told me that anything could even be wrong made it so much harder for me to even figure out where I needed to search for a fault. This was about the moment that I started to understand that I really couldn&#x27;t just rely on compilers or runtimes to help me figure these things out and I needed to rely much more on forums, blog posts and tutorials. In hindsight, this seems obvious but it still made me a little sad. The help you get from the compiler and other tools is actually what draws me to Rust in the first place, so losing that felt quite significant to me.&lt;&#x2F;p&gt;
&lt;p&gt;Another thing that didn&#x27;t help was that the control flow in React is very non-obvious to me in the beginning. After having worked with it a bit more the &lt;code&gt;useState&lt;&#x2F;code&gt; and &lt;code&gt;useEffect&lt;&#x2F;code&gt; control flow is a bit more intuitive to me now but it took quite a while to figure out and didn&#x27;t help when trying to debug. This meant that debugging a fairly straight-forward piece of code felt like print line debugging a huge mess of spaghetti code to me, which as you might imagine, is not a very nice experience.&lt;&#x2F;p&gt;
&lt;p&gt;It wasn&#x27;t all bad though. One thing I liked a lot more than I expected in React is the hot reloading. While the installing etc from &lt;code&gt;npm&lt;&#x2F;code&gt; feels much slower than it does in Rust, the edit-compile-test loop is &lt;em&gt;much&lt;&#x2F;em&gt; faster, due in part to the hot reload. It even maintains state between hot reloads!&lt;&#x2F;p&gt;
&lt;p&gt;This does occasionally lead to your application getting into a state you&#x27;ve just made unreachable due to a code change, which it can&#x27;t handle very well. This can be a bit of a brain bender, but on the whole, it made for a very fluid feeling workflow. While I don&#x27;t think it&#x27;s something I&#x27;ll miss in Rust, I was surprised by how much I liked it here, especially for something so visual and interactive.&lt;&#x2F;p&gt;
&lt;p&gt;As a brief aside, I&#x27;ve been trying to decide on a front end to add to the tech stack for a personal project that I&#x27;m planning. Initially, my stance has always been &quot;I don&#x27;t want to learn &amp;lt;insert whatever is hot now&amp;gt; I want to write Rust, that&#x27;s what works well for me and where I want to build my proficiency&quot;. I think that this was partially because I&#x27;ve never liked working with FFIs if at all possible. They have just never been a smooth experience for me, so I wanted to see if I could keep my potential project monolingual.&lt;&#x2F;p&gt;
&lt;p&gt;However, after this project, I no longer believe this is the correct way to go. I&#x27;ve followed the GUI development progression of Rust for a few years now and while I&#x27;m impressed with what they managed to get done, I think JS simply just does this better and probably will for the foreseeable future. Especially separating them by a CRUD web API makes the experience much smoother than I expected. Something I did not expect to come away with.  Another point in React&#x27;s favour.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;information-availability-legacy-software&quot;&gt;Information availability &amp;amp; legacy software&lt;&#x2F;h2&gt;
&lt;p&gt;This is one of the biggest surprises to me. If you&#x27;re like me, you probably had quite a visceral reaction to reading the words &quot;legacy software&quot;. In the mind of most devs legacy software is something terrible. I think this meme sums it up pretty nicely:
&lt;div &gt;&lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;slowcoder.org&amp;#x2F;processed_images&amp;#x2F;legacy.282f0f8365d4bafc.webp&quot; alt=&quot;Picture of an empty car spot between two parked trucks labelled &amp;#x27;brand new work project&amp;#x27;, then a second picture showing there is a mini parked there after all labelled with &amp;#x27;compatibility with legacy software&amp;#x27; followed by the line &amp;#x27;One can dream....&amp;#x27;&quot; &#x2F;&gt;
    &lt;&#x2F;div&gt;&lt;&#x2F;p&gt;
&lt;p&gt;However during this project literally the last thing I ever expected happened: I gained some understanding and empathy for the existence of legacy software (or at least backwards compatible software). Not all legacy software mind you, (looking at you, government) but some of it at least. Before this project my opinion on software sounded something like &quot;come on, people should just stay up to date with stuff. Don&#x27;t you want your stuff to work properly?&quot; I always bemoaned the need for backwards compatibility and openly wondered why people just refused to upgrade and maintain their stack.&lt;&#x2F;p&gt;
&lt;p&gt;This project, however, has made me realise that the breakneck speed with which this JS is evolving and new frameworks are popping up makes the field incredibly confusing for newcomers. What&#x27;s the difference between Vanilla JS, TS and JSX? What&#x27;s the difference between React and Angular? Is Vanilla JS even useful to learn at this point? What&#x27;s ES6? Is that a library or a linter? What&#x27;s webpack, What&#x27;s Babel? Why is the answer to every question &quot;who cares, just use the default&quot;. This &quot;every decision up front&quot; mentality you get confronted with is one of the things that made me bounce off JS the first couple of times. It&#x27;s incredibly paralysing if you&#x27;re on your own and don&#x27;t know that half the choices you&#x27;re presented with aren&#x27;t actual choices.&lt;&#x2F;p&gt;
&lt;p&gt;Secondly, it&#x27;s incredibly frustrating to find help with things when things become obsolete this fast. Anything to do with React that&#x27;s older than 2 years is basically worthless at this point, which let me tell you, is most of the stuff out there. React now looks very different syntactically to React a couple of years ago even if they largely do the same. This is incredibly confusing when you&#x27;re trying to cross-reference things as a beginner. Did this not work because I did something wrong? or did the standard change in the meantime? This StackOverflow question is exactly what I needed, but it&#x27;s from 2019, is it still valid? Even if the documentations are still correct, having those additional questions associated with everything makes it effectively worthless to a beginner. Thankfully I had Neha to bail me out when I needed it, but without her, I&#x27;m not sure I&#x27;d have made it to the end of this project.&lt;&#x2F;p&gt;
&lt;p&gt;Now I don&#x27;t mean to imply that it&#x27;s that binary. While writing this I am also reminded of the Python 2 debacle and the very &quot;maybe kind of sometimes ever consider please thinking about upgrading some day maybe please?&quot; approach that the python team took. Of course, it&#x27;s easy to commentate from the sideline, but I can&#x27;t help but think that if they had been willing to force a clean break a bit harder the segmentation might have been less egregious.&lt;&#x2F;p&gt;
&lt;p&gt;So it&#x27;s definitely not as easy as &quot;backwards compatible is always better&quot;. Sometimes earlier designs can really hamper you in what you can achieve, and I am incredibly impressed with how innovative and backwards-compatible Rust manages to be to this day. I guess there is no easy answer here as there never is. I&#x27;ve just gained a bit more of an understanding of the other side.&lt;&#x2F;p&gt;
&lt;p&gt;Being able to use existing knowledge and interface with existing infrastructure and tools is such a productivity life saver it&#x27;s not even funny, because you&#x27;re not just learning them in isolation but also in how they relate to the other bits you&#x27;re using. Being able to take that more &quot;one step at a time&quot; like you can do if things are more backwards compatible is much more valuable than I first realised. An unexpected, but very useful lesson.&lt;&#x2F;p&gt;
&lt;p&gt;I am definitely going to try and keep my JS skills a bit up to date and also explore other frameworks again to see how the experience compares. Next port of call is probably &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;svelte.dev&#x2F;&quot;&gt;Svelte&lt;&#x2F;a&gt; but we&#x27;ll have to see when I have time and energy to dive into something new. Hopefully that will be before the 2023 PET extravaganza.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Wanted: Creative work. Originality not required, inquire within.</title>
        <published>2022-12-03T00:00:00+00:00</published>
        <updated>2022-12-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/originality-not-required/"/>
        <id>https://slowcoder.org/blog/originality-not-required/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/originality-not-required/">&lt;p&gt;Stop me if this sounds familiar to you. You&#x27;re in a conversation with someone about a topic
that you know quite a lot about. Perhaps you&#x27;re a hobbyist, maybe it&#x27;s part of your profession,
or you just like watching a really specific type of youtube show about this topic because you
find them soothing and vaguely interesting for some reason. In any case, this is your jam, you
love talking about this stuff! However, after a while, your conversation partner says something
along the lines of &quot;wow, you know so much about this, you should write about it.&quot; This kinda
takes you by surprise. Sure, you know a bit about this, but no way you could write something
serious about it right? After thinking it over for a split second you respond with &quot;Oh, that&#x27;s
really sweet of you but I don&#x27;t think I have anything &lt;em&gt;new&lt;&#x2F;em&gt; to say about it.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;This happens to me all the time. I do like to try and involve people in projects I&#x27;m working on
or have an interest in but whenever I ask someone to talk about something they know a lot about
there&#x27;s at least a 50&#x2F;50 chance they will try to dismiss themselves like in the previous paragraph.&lt;&#x2F;p&gt;
&lt;p&gt;I have two things I want to say in response to that:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;That&#x27;s almost certainly not true&lt;&#x2F;li&gt;
&lt;li&gt;Who cares?!&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Having something new to say is incredibly overrated, and in this blog post, I hope to convince
you of this, so that next time you have this conversation I might be able to convince you to
take a leap into a cool new project.&lt;&#x2F;p&gt;
&lt;p&gt;Before I get into this point properly, let me get a disclaimer out of the way. It&#x27;s entirely
possible that when people say this, it&#x27;s more of a polite dismissal rather than something
they actually believe. If that&#x27;s the case, then that&#x27;s fine. If you don&#x27;t want to do the work
for whatever reason, you don&#x27;t have to, as long as you realise that&#x27;s the decision you&#x27;re
making. However, I think there are a decent number of people that actually do believe they
don&#x27;t have enough to say about a topic they are passionate about. I am writing this for them
and because of that, I&#x27;m going to take the statement &quot;I don&#x27;t have anything new to say about X&quot;
at face value. Let&#x27;s get started!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;you-re-wrong&quot;&gt;You&#x27;re wrong&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s start with the easy reasons. People don&#x27;t ask just anyone their opinion on specific
topics. Even in instances in which it seems like you&#x27;re asking complete randos about things like
on forums, you usually go to one specific to your topic, where there is a good chance people
will know about the things you&#x27;re asking. So if someone asks you specifically about something,
that&#x27;s already a good indication that you have more to say about something than you might realise.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s a fallacy to say that you even need to know about something to be able to say something
new about it. I very often run ideas and projects by people who know nothing about them. For
example, my mother knows very little about the maths and programming I do, but she proofreads
nearly anything I write (thanks mum &amp;lt;3). Sometimes the questions she asks have been incredibly
illuminating and have led to me taking a very different angle of approach to something.&lt;&#x2F;p&gt;
&lt;p&gt;The curse of expertise (yes that&#x27;s an actual thing) can create real blind spots that take an
outside perspective to illuminate. For example, I think it&#x27;s very appropriate to ask recent
immigrants about Dutch immigration policy, specifically because they don&#x27;t know all the ins
and outs of it, but have to deal with it anyway. So even if it is true you don&#x27;t know anything
about the subject that still makes your perspective interesting!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-does-new-even-mean&quot;&gt;What does new even mean?&lt;&#x2F;h3&gt;
&lt;p&gt;I think that the question of &quot;is something new&quot;, is an incomplete one. A better version of the
question is &quot;is X new to Y?&quot; The sentiment that you always need to be saying something novel,
assumes a sort of all-knowing audience that is aware of everything being said at all times. This
is clearly not true in every conceivable way. People (including me) sometimes talk about how
certain children&#x27;s shows like Pokemon (that&#x27;s still what kids these days like right?) can be so
repetitive, but this starts to make a lot more sense once you consider that the audience for such
a kids show is continually renewing itself as people grow in and out of the relevant demographic.&lt;&#x2F;p&gt;
&lt;p&gt;A somewhat funny illustration of this happened to me when I was a teaching assistant (TA) for
an introductory course for first-year maths students. Understandably a lot of them make very
similar mistakes, meaning that as a TA you&#x27;re writing the same feedback over and over again. I
remember thinking after grading the first batch of homework, &quot;gee, I&#x27;ve written this feedback
so many times now, surely they&#x27;ll remember now!&quot; In retrospect, this seems hilariously wrong
to think, because no matter how many times I write it down, they only read it once. I wouldn&#x27;t
have been a good TA if I told the second student to make the same mistake &quot;oh I don&#x27;t know if
I have anything new to say about this.&quot;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;once-you-read-the-dictionary-everything-is-a-remix&quot;&gt;Once you read the dictionary, everything is a remix&lt;&#x2F;h3&gt;
&lt;p&gt;The title of this subsection is a bit facetious, but I still think it illustrates my point rather
well.  There is tremendous value in aggregating, summarising, rehashing and reformulating. If
there was no value in repeating content, there would only be one tutorial on youtube for any
given topic, but still, new versions of the topic du jour pop up every day. You only have to
look at the rise of &quot;edutainment&quot; on places like Youtube across the past decade or so to realise
that even if you can say the same thing in new ways that&#x27;s immensely valuable.&lt;&#x2F;p&gt;
&lt;p&gt;This is also (at least partially) why reviewers, influencers and recommendation systems have
exploded in numbers over the past few decades. The amount of content people are exposed to has
grown so large, that people need reputable sources to help them separate the wheat from the
chaff. Perhaps it helps to have a new way of communicating to engage that audience, but for
the most part, these people are not saying anything &quot;new&quot;, they&#x27;re reporting on things that
are already out there.&lt;&#x2F;p&gt;
&lt;p&gt;Even if you were to change nothing about the information you&#x27;re presenting, realising which
information is relevant and fits together with which other bits of information, is hugely
valuable. That is literally the job of journalists (and if you&#x27;re one of those types that think
journalists are just leeches or &quot;sewage rats&quot; then get the hell off my website).&lt;&#x2F;p&gt;
&lt;p&gt;There is also tremendous value in remixing and introducing audiences to parts of a genre they
might not have been familiar with. Twilight was horror + YA Romance, and regardless of your
opinion on it, I think it&#x27;s hard to argue it didn&#x27;t make a splash. Game of Thrones is Tolkien +
dark gritty reboot (or Tolkien + porn if you&#x27;re feeling less charitable). Newton was Euclid +
limits. Bitcoin is cryptography + the Nigerian prince email scam. I&#x27;m being facetious here,
but you get what I mean. Saying &quot;What if X but Y&quot; is a perfectly valid creative strategy.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;who-cares&quot;&gt;Who cares?&lt;&#x2F;h2&gt;
&lt;p&gt;So far I&#x27;ve mostly talked about why you have a lot more &quot;new&quot; things to say than you realise,
but there is another side to this. The idea that everything has to be novel in some way is
just bullshit. I&#x27;ve already talked about ways in which presenting &quot;old&quot; information again can
be valuable and in this section, I want to take that to its logical conclusion: the wholesale
dismissal of the necessity of originality.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sometimes-you-want-consistency-not-novelty&quot;&gt;Sometimes you want consistency, not novelty&lt;&#x2F;h3&gt;
&lt;p&gt;If you&#x27;ve ever had an insecure friend or partner you know what I&#x27;m talking about. It takes a
lot of constant encouragement to convince someone of their own value sometimes. If every time
your friend needed some encouragement you&#x27;d respond with &quot;eh, I&#x27;m just not sure what I have
to say that others haven&#x27;t already said,&quot; I doubt that would be good for your relationship. I
also think we can all agree that &quot;they&#x27;ve been saying that for years&quot; is not a good reason to
dismiss the idea that smoking is bad for you.&lt;&#x2F;p&gt;
&lt;p&gt;Advertisers know this. It&#x27;s often the consistency and ubiquity of a message that determines
its persuasiveness, not necessarily the contents or the quality. Sure it can help, but it&#x27;s not
required. That&#x27;s why brand consistency is tyrant these days.  If you ask me it would be naive
to think that people would have gotten on board with climate change earlier if the climate
activists had had a new talking point every week.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sometimes-messages-are-for-the-sender-not-the-receiver&quot;&gt;Sometimes messages are for the sender, not the receiver&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve mentioned before that this blog is a good way for me to structure my thoughts. Communicating
an idea or feeling can help you structure, conceptualise or process topics or events.  That&#x27;s why
therapy is a thing.&lt;&#x2F;p&gt;
&lt;p&gt;There is also an artistic angle to this topic. Much art, (although I would argue much less than
we colloquially think) is made simply to express something, regardless of audience. Saying that
those pieces need something unique in them is both disingenuous and missing the point.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-all-copying-is-plagiarism&quot;&gt;Not all copying is plagiarism&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s a well-known advice to aspiring creatives to simply copy styles they like from veterans to
get them started alongside practising the basics. To get started in painting you might practice
basic shapes and try an early Van Gogh-style painting. If you&#x27;re learning an instrument,
you practice with tone progressions and popular pop songs you like. If you&#x27;re looking to get
into chess, you start out with well-known strategies rather than just flailing around on the
board. These are just examples but my point is that there is real value in emulation.&lt;&#x2F;p&gt;
&lt;p&gt;Even though it is a bit long I think it is germane to share one of my favourite quotes here:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;All of us who do creative work, we get into it because we have good taste. But it&#x27;s like
there is this gap. For the first couple years that you&#x27;re making stuff, what you&#x27;re making
isn&#x27;t so good. It’s not that great. It’s trying to be good, it has ambition to be good,
but it’s not that good.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;But your taste, the thing that got you into the game, is still killer. And your taste is
good enough that you can tell that what you&#x27;re making is kind of a disappointment to you. A
lot of people never get past that phase. They quit.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Everybody I know who does interesting, creative work they went through years where they had
really good taste and they could tell that what they were making wasn&#x27;t as good as they wanted
it to be. They knew it fell short. Everybody goes through that.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;And if you are just starting out or if you are still in this phase, you gotta know its normal
and the most important thing you can do is do a lot of work. Do a huge volume of work. Put
yourself on a deadline so that every week or every month you know you&#x27;re going to finish one
story. It is only by going through a volume of work that you&#x27;re going to catch up and close
that gap. And the work you&#x27;re making will be as good as your ambitions.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;I took longer to figure out how to do this than anyone I’ve ever met. It takes awhile. It’s
gonna take you a while. It’s normal to take a while. You just have to fight your way through
that.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;—Ira Glass&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;And this applies to much more than just creative work. I believe that maths, coding, academic
writing, basically anything follows this trend. I think that a unique style is not something
you should strive for, it&#x27;s something that happens organically as you produce a body of work.&lt;&#x2F;p&gt;
&lt;p&gt;Take for example my work. This very blog is very heavily modelled
on blogs like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;joelonsoftware.com&quot;&gt;joelonsoftware.com&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.codinghorror.com&quot;&gt;codinghorror.com&lt;&#x2F;a&gt;. Even though I don&#x27;t actually like them
that much anymore and very heavily disagree with them on many topics these days, it
would be disingenuous to say they haven&#x27;t influenced my style. When I was a wee kid, I
wrote fan fiction of my favourite games with me in it classic mary-sue-isekai style. My
style of poetry has been very much influenced by Pablo Neruda. I very deliberately
model the endings of all of my significant work after the way Ian Danskin ends his &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=4xGawJIseNY&amp;amp;list=PLJA_jUddXvY7v0VkYRbANnTnzkA_HMFtQ&amp;amp;ab_channel=InnuendoStudios&quot;&gt;Alt-right
playbook&lt;&#x2F;a&gt;
videos. If I had been hell-bent on having my own style immediately after I started writing I&#x27;d
never have gotten anywhere because I&#x27;d still be busy reinventing the wheel.&lt;&#x2F;p&gt;
&lt;p&gt;This of course does not mean that you should plagiarise, or not put effort into your work. There
is a very important distinction between plagiarism and emulation. While simply copying someone&#x27;s
style can help you figure out whether it works for you or not and what makes it good, it will
not help you to just churn out pure copies of other people&#x27;s work. This might seem contradictory
to what I&#x27;ve been saying for this entire post, but I don&#x27;t think it is and I hope you&#x27;ll get
the difference.&lt;&#x2F;p&gt;
&lt;p&gt;I am also not trying to tell you have you have to do all this work. Any kind of creative work,
whether you mean one specific project or whether you want to do the work of developing your
own style, it can all be major time investments. You are not obligated to do any of this if
you don&#x27;t want to, but I hope you understand that that is the conversation you should be having
with yourself, not one about originality.&lt;&#x2F;p&gt;
&lt;p&gt;You also don&#x27;t have to publish everything you make, or that you have to finish everything you
start. Motivation is a fickle thing, and you have to decide for yourself whether there is any
value in starting or finishing something. But please, for the love of all that is creative,
don&#x27;t throw away your gems because &quot;they have nothing new to say.&quot; What you have to say
matters. Originality is nice if you can get it, but in the end, it will always be optional.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What devs and doctors wish you knew about writing bug reports</title>
        <published>2022-10-16T00:00:00+00:00</published>
        <updated>2022-10-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/how-to-bug-report/"/>
        <id>https://slowcoder.org/blog/how-to-bug-report/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/how-to-bug-report/">&lt;p&gt;Recently I gave a presentation at work about writing good bug reports and I&#x27;ve gotten quite
positive responses from it so I figured I&#x27;d put it in writing here as well for anyone who would
find it useful. Enjoy!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-should-i-care-about-bug-reports&quot;&gt;Why should I care about bug reports?&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ll start off with the carrot: you should care about writing good bug reports because it will
help your problems get solved much faster. And I&#x27;m not just talking about actual software bugs
but problems in general. A bug report is simply something that will help someone diagnose a
problem you&#x27;re having. And let me tell you, dear reader, if you make it easier for someone
to understand and thus solve your problem, it is much more likely to happen. People who solve
problems are busy, and when they have to inevitably start prioritising, you want to make it as
easy possible for them to pay attention your problem.&lt;&#x2F;p&gt;
&lt;p&gt;The broadness of my definition is intentional. In my opinion, describing your symptoms to
a doctor is fundamentally the same process as opening an issue on GitHub is, they just use
different lingo. I&#x27;ll illustrate this with an example later.&lt;&#x2F;p&gt;
&lt;p&gt;It should be noted that writing good bug reports is hard, very hard. It takes practice, and
this post is not giving you any hard and fast rules, just some rules of thumb to use and adapt
as fits you.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rule-1-be-to-the-point&quot;&gt;Rule 1: Be to the point&lt;&#x2F;h2&gt;
&lt;p&gt;The two most common types of error messages are:  &quot;Oops, something went wrong!&quot; or&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-java &quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span&gt;javax.servlet.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletException&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Something&lt;&#x2F;span&gt;&lt;span&gt; bad happened
&lt;&#x2F;span&gt;&lt;span&gt;    at com.example.myproject.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;OpenSessionInViewFilter&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;doFilter&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;OpenSessionInViewFilter&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;60&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.servlet.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHandler$CachedChain&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;doFilter&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHandler&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1157&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at com.example.myproject.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ExceptionHandlerFilter&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;doFilter&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ExceptionHandlerFilter&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.servlet.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHandler$CachedChain&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;doFilter&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHandler&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1157&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at com.example.myproject.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;OutputBufferFilter&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;doFilter&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;OutputBufferFilter&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.servlet.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHandler$CachedChain&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;doFilter&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHandler&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1157&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.servlet.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHandler&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHandler&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;388&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.security.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;SecurityHandler&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;SecurityHandler&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;216&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.servlet.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;SessionHandler&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;SessionHandler&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;182&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.handler.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ContextHandler&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ContextHandler&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;765&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.webapp.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;WebAppContext&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;WebAppContext&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;418&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.handler.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HandlerWrapper&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HandlerWrapper&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;152&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Server&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Server&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;326&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpConnection&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handleRequest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpConnection&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;542&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpConnection$RequestHandler&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;content&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpConnection&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;943&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpParser&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;parseNext&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpParser&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;756&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpParser&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;parseAvailable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpParser&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;218&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpConnection&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpConnection&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;404&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.bio.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;SocketConnector$Connection&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;SocketConnector&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;228&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.thread.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;QueuedThreadPool$PoolThread&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;QueuedThreadPool&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;582&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Caused&lt;&#x2F;span&gt;&lt;span&gt; by: com.example.myproject.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;MyProjectServletException
&lt;&#x2F;span&gt;&lt;span&gt;    at com.example.myproject.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;MyServlet&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;doPost&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;MyServlet&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;169&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at javax.servlet.http.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpServlet&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;service&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpServlet&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;727&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at javax.servlet.http.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpServlet&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;service&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;HttpServlet&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;820&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.servlet.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHolder&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHolder&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;511&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at org.mortbay.jetty.servlet.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHandler$CachedChain&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;doFilter&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;ServletHandler&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1166&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    at com.example.myproject.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;OpenSessionInViewFilter&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;doFilter&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;OpenSessionInViewFilter&lt;&#x2F;span&gt;&lt;span&gt;.java:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    ... &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span&gt; more
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I cut out most of that java error message but you get the point. The problems with these is
that they don&#x27;t give you the right amount of information about exactly what went wrong. The
first gives you no information at all, and the second one technically does, but it burries it
in so much unhelpful bullshit that it&#x27;s almost impossible to find. The amount of information
to include has a sweet spot, and where that spot is, can vary wildely on a case by case basis&lt;&#x2F;p&gt;
&lt;p&gt;In case you still find that a little vague, let me illustrate a bit more concretely with a
fictional example:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-case-of-jan-klaas-klompenmaker&quot;&gt;The case of Jan-Klaas Klompenmaker&lt;&#x2F;h3&gt;
&lt;p&gt;Imagine you&#x27;re a tech support for a company that has a webapp and you get the following email:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello,&lt;&#x2F;p&gt;
&lt;p&gt;I hope this email finds you well. My name is Jan-Klaas Klompenmaker. I was recently using your
website but it doesn’t work for me. I am 87 years old so perhaps I am simply not understanding
how it is meant to work, sorry if this is the case. Normally I would ask my daughter to help
with this but she is currently on holiday in Cyprus so I cannot ask her for help you see. I am on
Apple, if you could help me I’d really appreciate it. Thank you and enjoy the rest of your day.&lt;&#x2F;p&gt;
&lt;p&gt;Best wishes,
Jan-Klaas Klompenmaker&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Setting aside the politeness, the email contains only three bits of &quot;relevant&quot; information:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;I was recently using your website&lt;&#x2F;li&gt;
&lt;li&gt;It doesn&#x27;t work for me&lt;&#x2F;li&gt;
&lt;li&gt;I am on Apple&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This is why I dislike people trying to be overly polite when reporting issues. I appreciate
the sentiment, but it distracts from the task at hand. I&#x27;ll be less annoyed if I can do my job
efficinetly and finish early than I am if someone doesn&#x27;t ask me how my day is going.&lt;&#x2F;p&gt;
&lt;p&gt;Okay so that&#x27;s on not including irrelevant information, but what about the info that is
there? I think you&#x27;ll agree that while my summary is more to the point, it&#x27;s not that much more
informative. With the power of fictional hindsight I can show you a better version:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello,&lt;&#x2F;p&gt;
&lt;p&gt;I was using your website on 2022-10-16 at 3:24 AM (when there was a scheduled maintenance
outage). When I submitted my form I got sent to a 404 page, I was visiting your website on an
iPhone with the oldest OS still supported.&lt;&#x2F;p&gt;
&lt;p&gt;Thank you&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Much better isn&#x27;t it? The fictional person of course wouldn&#x27;t know about the outage so you
would have to piece together yourself but the leap from my revised version to the answer is a
lot more managible. In short: I&#x27;m here to help you, so let me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rule-2-come-to-me-with-a-problem-not-a-solution&quot;&gt;Rule 2: Come to me with a problem, not a solution&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes people will try to be helpful and do some of the diagnosis and problem solving for
me. Sometimes because the answer seems much more straightforward than it actually is, sometimes
because they genuinely have made some useful inferences already. That&#x27;s all fine, even if it&#x27;s
a little grating when they turn out to be wrong.&lt;&#x2F;p&gt;
&lt;p&gt;The actual mistake they almost always make in that situation is only telling you the solution
but not the original problem statement or how they arrived at that answer. The problem with
this is that it does not give me what I need to assess the solution the way I would with any
other solution: Does it actually solve the problem? Is it compatible with other parts of the
system? Does it follow the necessary standards? so on and so forth.&lt;&#x2F;p&gt;
&lt;p&gt;In my professional experience it is also the case that the solution people come to you with
rarely actually solves the issue they have. Therefore whenever a user or client comes to me
with a solution instead of a problem description it&#x27;s a red flag to me. I almost never take
something like that at face value. Not because I think they are stupid, but because this is
how you end up with solutions without problems. More often than not, there is an underlying
problem they have not discussed, knowingly or not. If this is perhaps still a little vague to
you, consider the following example:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-case-of-the-red-button&quot;&gt;The case of the red button&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello,&lt;&#x2F;p&gt;
&lt;p&gt;The button on your contact form should be blue [instead of the red it is now].&lt;&#x2F;p&gt;
&lt;p&gt;Thank you&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Again setting aside the possible rudeness of a message like this, it doesn&#x27;t give me the
information I need to assess whether this is a good idea. Do they prefer blue to red? Does the
shade we have now make some kind of colour theoretic faux pas? How will other users of my system
see that change?&lt;&#x2F;p&gt;
&lt;p&gt;Again, with the benefit of fictional insight I&#x27;ll show you what they actually meant:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello,&lt;&#x2F;p&gt;
&lt;p&gt;I have Protanopia [red-green colourblindness] and so I can’t find the button on your
contact form or read the text on it properly.&lt;&#x2F;p&gt;
&lt;p&gt;Thank you&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Aaaahhhh, okay. Aside from being a more legitimate reason to ask for the change than simple
preference, it opens up a lot of different options that won&#x27;t require a potential overhaul of
the entire colour palette of the website, such as having a higher contrast between text and
background. In short: if you want me to solve your problem, give me what I need to do that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rule-3-be-clear-in-your-expectations&quot;&gt;Rule 3: Be clear in your expectations&lt;&#x2F;h2&gt;
&lt;p&gt;The final bit to consider in a good bug report is what you consider a solution to look like. Often,
when someone has done a good job on the previous two points this one is fairly easy to infer,
but not always. This step is especially critical if the solution you want is different from
the first thing that people think of when you describe the problem, which could be the case for
example when you communicate across cultures, or disciplines or with someone that doesn&#x27;t have
your disability or experience.&lt;&#x2F;p&gt;
&lt;p&gt;If you go back and read the previous examples carefully you&#x27;ll notice that they don&#x27;t actually
state what the solution should be, but this can be quite easily inferred. In the first example,
the website should have accepted the submission and possibly given confirmation that it was
successful. In the second example it is the button being clearly legible to the user. However
this is not always the case. Consider the following (admittedly somewhat contrived) example:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello,&lt;&#x2F;p&gt;
&lt;p&gt;When the users try to look at the flash animation on my website, they cannot do so anymore
because Adobe deprecated flash. It is an important part of my portfolio, can you bring it back
online somehow?&lt;&#x2F;p&gt;
&lt;p&gt;Thanks for your help.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This follows the previous two points but leaves out a crucial bit: what requirements do the
solutions have to satisfy? Is its being flash a hard requirement? Is a recording of the animation
an acceptable substitution? Do we have copyright or licensing requirements?&lt;&#x2F;p&gt;
&lt;p&gt;If the point is only that the animation be shown because it&#x27;s part of a portfolio, an embedded
YouTube player showing the animation could very well suffice. Otherwise more complex considerations
should be made. The client can usually not assess these things accurately so in any bug report
it is important that you specify what completion means to you. In short: be clear on when I
can give my solution back to you.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;putting-it-all-together&quot;&gt;Putting it all together&lt;&#x2F;h2&gt;
&lt;p&gt;Until now I&#x27;ve only described common mistakes that people make when writing bug reports, but
in order for this to be actually useful, I ought to show you how to do it properly instead. In
summary the best practices are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Describe what has happened&lt;&#x2F;li&gt;
&lt;li&gt;Describe what should have happened&lt;&#x2F;li&gt;
&lt;li&gt;Describe what an acceptable solution looks like to you&lt;&#x2F;li&gt;
&lt;li&gt;Describe any relevant context and no more&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;That last bit is usually a tricky one, since, especially if you are a lay person, you cannot
always accurately judge what constitutes as &quot;relevant&quot; context. This is where personal judgement
and practice come in. Basically the rule of them here is that you want to describe anything
necessary for another person to recreate the incident.&lt;&#x2F;p&gt;
&lt;p&gt;For a final demonstration I&#x27;ll write a bug report in what I consider to be a very good manner. To
also drive home the broadness of this subject I&#x27;m going to do it with a slightly unconventional
subject.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;showcase-a-medical-diagnosis&quot;&gt;Showcase: A medical diagnosis&lt;&#x2F;h3&gt;
&lt;p&gt;Consider the following email:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dear dr. Whitecoat,&lt;&#x2F;p&gt;
&lt;p&gt;I’ve been running long distances (5km+) for over a few years now which has always gone
well. However for the past few months my performance has gone down steadily seemingly out of
nowhere. I also get shortness of breath when I work out which I didn’t have before, and I have
moments where out of nowhere my heart starts racing like crazy and I feel very nauseous. On hot
days I also have chest pain. Any idea what could be wrong and what I can do to get back to running?&lt;&#x2F;p&gt;
&lt;p&gt;Thanks!&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Hopefully you can see that very few words in the letter above are not spent talking about one
of the three cases I outlined in the section. For reference we have:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Problem statement: &quot;However for the past few months my performance has gone down steadily
seemingly out of nowhere. I also get shortness of breath when I work out which I didn’t have
before, and I have moments where out of nowhere my heart starts racing like crazy and I feel
very nauseous. On hot days I also have chest pain.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Expectation: &quot;Any idea what could be wrong and what I can do to get back to running?&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Context: I’ve been running long distances (5km+) for over a few years now which has always
gone well.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Of course this is not an exact taxonomy so there is a fair bit of overlap between the intent
of these sentences, but hopefully you see what I&#x27;m getting at.&lt;&#x2F;p&gt;
&lt;p&gt;As a final remark I&#x27;d also like to note the following. The other person has responsibility
here as well. As I already said, it&#x27;s very likely that you don&#x27;t have the full context needed
to include all of the &quot;relevant&quot; information. These are just tools to help you do the best you
can. After that it&#x27;s on the other person to help you get them what they need, so they can help
you, get what you need.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why you cannot interact with me on this website</title>
        <published>2022-06-06T00:00:00+00:00</published>
        <updated>2022-06-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/why-no-interactions/"/>
        <id>https://slowcoder.org/blog/why-no-interactions/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/why-no-interactions/">&lt;p&gt;In some ways, my blog is unique: it&#x27;s a one-way street.  No likes, no comments, no analytics;
I don&#x27;t even log traffic at the time of writing. That might seem weird to some in this day and
age but it&#x27;s a very intentional choice. Here are some of the main reasons I made that decision.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;privacy-complexity&quot;&gt;Privacy &amp;amp; complexity&lt;&#x2F;h2&gt;
&lt;p&gt;The fact of the matter is that most platforms that facilitate interactions
in one way or another are bad for privacy. For example, one platform I
might have considered using is  &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;disqus.com&#x2F;&quot;&gt;Disqus&lt;&#x2F;a&gt;. It takes
approximately .3 ms of googling to find out that Disqus has some &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;techcrunch.com&#x2F;2021&#x2F;05&#x2F;05&#x2F;disqus-facing-3m-fine-in-norway-for-tracking-users-without-consent&quot;&gt;problematic
behaviour&lt;&#x2F;a&gt;
when it comes to privacy. Another dead giveaway is the 4 main phrases they use to promote
themselves: &quot;Engage your audience&quot;, &quot;Understand your success&quot;, &quot;Retain your readers&quot;, and
&quot;Monetize engagement&quot; (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;disqus.com&#x2F;features&#x2F;&quot;&gt;source&lt;&#x2F;a&gt;). This reflects a worldview that I
do not ascribe to. Namely that privacy is a resource to be used, that violating privacy is simply
&quot;the cost of doing business&quot;. Not only that, but it is also just not how I want to run this blog.&lt;&#x2F;p&gt;
&lt;p&gt;I think this way of viewing privacy as a resource is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=ZeecOKBus3Q&quot;&gt;convergent
behaviour&lt;&#x2F;a&gt;. Doing interactive stuff is hard and
in a lot of cases both expensive and potentially lucrative. We often don&#x27;t think of it as being
expensive because it is everywhere these days, but it really is. That&#x27;s why there is a market for
ready-made solutions that focus on converting privacy into currency. There are, of course, ways
to do it privacy-friendly, but those are less effective or more meantenence heavy and thus do not
attract investors or users in the same way that something that is promising to make you money does.&lt;&#x2F;p&gt;
&lt;p&gt;Another part of this is that once you start storing what you need to interact with people you
have to be &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gdpr-info.eu&#x2F;&quot;&gt;GDPR compliant&lt;&#x2F;a&gt;. This adds even more complexity. So far I&#x27;ve
mostly talked about off-the-shelf solutions, but GDPR compliance on its own is complex enough
to make homebrewing a solution not a good idea in my opinion.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ambitions&quot;&gt;Ambitions&lt;&#x2F;h2&gt;
&lt;p&gt;I think a part of this overall point I&#x27;m trying to make stems down to the ambition I have for this
blog. Here I use the word ambition to mean &quot;intention&quot;, rather than a hard to achieve goal. In
fact, my intentions for this blog are deliberately low. They say that &quot;if you do what you love
for a living you&#x27;ll never work a day in your life,&quot; but the past decade has taught me that if you
make your hobby your job you&#x27;ll never have a moment to rest for the rest of your existence. This
a sentiment that has been echoed by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=oUPRwfb37sM&quot;&gt;youtubers&lt;&#x2F;a&gt;
as well as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=o_4EX4dPppA&quot;&gt;FOSS contributors&lt;&#x2F;a&gt;, to name just a
few groups that I&#x27;m familiar with.&lt;&#x2F;p&gt;
&lt;p&gt;This is why I&#x27;m okay with the upload frequency of this blog (if you can even call it that) being
so inconsistent. This is a hobby, not a side hustle. That means that I work on it when I have
the time and energy for it and I have no intention of turning this blog into a content farm. If
anything, it&#x27;s mostly a place for me to practice my writing, experiment with aesthetics, structure
my thoughts, and occasionally serve as a resume with a more permissive format. I don&#x27;t intend
to make money on this blog, at least for the foreseeable future (but never say never I guess).&lt;&#x2F;p&gt;
&lt;p&gt;A huge inspiration for me in this regard is the writer &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;victoriacorva.xyz&quot;&gt;Veo Corva&lt;&#x2F;a&gt;. Not
only are they an absolutely wonderful writer (and you should definitely check out &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;veocorva.xyz&#x2F;books&#x2F;books-and-bone-by-Veo-Corva&#x2F;&quot;&gt;their
books&lt;&#x2F;a&gt;), they stream quite
regularly on twitch in a way that I admire immensely. They stream twice a week, for 1.5h with
a fairly strict limit. They&#x27;ve refused Twitch partnership meaning they don&#x27;t directly earn
money on their streams, and both the chat and other community places they host are small and
cosy. They are open to newcomers but not growth-oriented. This is not an anti-capitalist comment
about them selling out or not, it is admiration about how they work to keep a hobby a hobby in
a world where there are incredibly strong incentives to turn everything into a revenue stream.
If I ever do something that requires community management I hope to be able to do it in the
same way they do it now.&lt;&#x2F;p&gt;
&lt;p&gt;I strongly believe community management is an obligation that anyone who has an audience ought
to take seriously, and so I&#x27;m not going to put myself in a position where I might have to take
on that responsibility until I feel ready for it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sanity&quot;&gt;Sanity&lt;&#x2F;h2&gt;
&lt;p&gt;That last point about non-growth centred community leads nicely into my final and perhaps most
important point. I want to protect myself in several ways.  One thing I know about myself
is that I&#x27;m quite an obsessive and neurotic person. That&#x27;s not me being self-deprecating,
that&#x27;s just an observation. I tend to worry about numbers and whether they are high enough
once they enter my life in one way or another. This is of course highly encouraged by all of
the platforms out there since that is their business model. Platforms like Google and Twitch
are the creative landlords of our era and I do not want to be beholden to them. That is why
this website is self-hosted instead of on some platform like Medium.&lt;&#x2F;p&gt;
&lt;p&gt;However, you might argue that, so far, I&#x27;ve made a case against analytics, not interactions. I
think this misses my point, but it does have a grain of truth to it. For me, it&#x27;s not just
about protecting myself from myself, but also protecting myself from other people. Anyone who
has used the internet for more than checking the weather forecast in the past decade or so
knows what a hellhole it can be. Discourse on the internet is terrible, and everybody knows it.&lt;&#x2F;p&gt;
&lt;p&gt;If being in academia &amp;amp; government for nearly a decade has taught me anything it&#x27;s that you have
to be very selective in how, when, and from who you solicit feedback. Not all feedback is created
equal. Contrary to what people seem to believe, feedback is not relationship-independent. However
good the feedback, it simply makes a difference in who is saying it, whether for better or for
worse (insert discussion about &quot;white saviour complex&quot; here).&lt;&#x2F;p&gt;
&lt;p&gt;This doesn&#x27;t mean that people you don&#x27;t agree with can&#x27;t give you good feedback, but it does
rely on whoever is giving the feedback to be able to communicate with you effectively. So it&#x27;s
not that I&#x27;m not open to criticism of any kind, just that I&#x27;m not open to it being hurled at
me from a firehose.  If you know me, or can get into contact me I&#x27;d love to hear what you
think. Having a bit of confidence that the other party realises there&#x27;s an actual bonified
human behind the keyboard typing this goes a long way to foster proper discussions from all
parties involved in my experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-you-can-interact-with-me-or-this-website&quot;&gt;How you can interact with me or this website&lt;&#x2F;h2&gt;
&lt;p&gt;Even though I&#x27;ve just explained why there are little to no interactive parts to this website
and why that will stay like that for the foreseeable future, there are ways you can keep up to
date with this blog if you so wish.&lt;&#x2F;p&gt;
&lt;p&gt;This website has something called an Atom feed (which you can find
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;slowcoder.org&#x2F;atom.xml&quot;&gt;here&lt;&#x2F;a&gt;). Often they are also called RSS feeds but for all intents
and purposes those are interchangeable these days. Applications that can read one should also
be able to read the other. This is a part of the website that presents most of the content of
this website in a machine readable, rather than a human readable way so that apps can keep track
of things like updates more easily. Many apps can read a feed like that and will allow you to
either read the content there in the app if you so choose or just let you know when there is a
new post. This is a really old-school way to do it, but it is by far the most privacy-friendly
one I know of apart from by smoke signal.&lt;&#x2F;p&gt;
&lt;p&gt;As for interacting with me? Well if you know me, I&#x27;d love to hear what you think. Despite the
number of words I&#x27;ve spent on why I don&#x27;t like to interact with people on this website, I do
actually appreciate getting other people&#x27;s perspectives on what I put out. It&#x27;s just that I
like to have a bit more control over how and when I have those conversations. I am curious to
hear what you think, just not here.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How being queer will occasionally make me racist</title>
        <published>2022-05-29T00:00:00+00:00</published>
        <updated>2022-05-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/being-queer-and-racist/"/>
        <id>https://slowcoder.org/blog/being-queer-and-racist/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/being-queer-and-racist/">&lt;p&gt;Depending on your view I&#x27;ve either chosen a deliberately inflammatory title or a completely
descriptive one. I prefer to think of it as the latter. Despite how I&#x27;ve chosen to phrase the
title, I really strongly believe in Ibram Kendi when he writes&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Racist&quot; is not – as Richard Spencer argues – a pejorative. [...]. It is descriptive,
and the only way to undo racism is to constantly identify and describe it – and then dismantle
it. The attempt to turn this usefully descriptive term into an almost unusable slur is, of
course, designed to do the opposite: to freeze us into inaction.
— How to be Anti-Racist, Ibram X. X. Kendi&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Or in other words &quot;Racism is not a thing you are, it is a thing you do&quot;. This is not a call-out
post. Of me, or anyone else. This is, again in the words of Kendi, &quot;Doing the basic work, of
defining the people we want to be [...]&quot;. This post is mostly by, for, and about me. Sometimes
writing for public consumption is one of the best ways for me to structure my thoughts. I have
written this also in the hope that I inspire other people to do some self-reflection in a similar
way, but I&#x27;m trying to keep my expectations realistic. That means that this post is meant mostly
for other white people. Of course, my siblings of colour are welcome to stay if they so choose,
but they know these tendencies better than I ever could, and I will not presume to tell them
anything they don&#x27;t already know.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-bit-of-context&quot;&gt;A bit of context&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes the way I find out if an idea is really good is just by procrastinating the shit out
of it and if it sticks around then I know it&#x27;s a good enough idea to try out. The bad ones I
either stumble on to reasons why it isn&#x27;t very good or just forget about. This blog post is
one of those ideas that has stuck around for years. I think the earliest inception of this idea
was back in 2018 when I first started my PhD.&lt;&#x2F;p&gt;
&lt;p&gt;In case you didn&#x27;t know this about me, I am non-binary. I don&#x27;t often dress very non-conforming
for a whole host of reasons, but what that means is that most people wouldn&#x27;t &quot;clock&quot; me as
they call it.&lt;&#x2F;p&gt;
&lt;p&gt;At the time when the story I&#x27;m about to tell you takes place, I had just moved to Wales. This
was about a year after I&#x27;d discovered I was trans, meaning that I was even less secure about it
and how to deal with it at that time than I am now (and that says something). It was, however,
another opportunity to reinvent myself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-to-my-actual-point&quot;&gt;Getting to my actual point&lt;&#x2F;h2&gt;
&lt;p&gt;On the first day, we had an introductory day to meet our department colleagues, our fellow PhD
students and their research topics. You know, the standard stuff.&lt;&#x2F;p&gt;
&lt;p&gt;During that meeting, at one point one of our colleagues told the group that he was from
Saudi Arabia. This set me into alarm mode pretty much immediately. As I&#x27;m sure you&#x27;re
well aware, Saudi Arabia is not.... a famously chill place for queer people. You know, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.amnesty.org&#x2F;en&#x2F;latest&#x2F;news&#x2F;2022&#x2F;03&#x2F;saudi-arabia-mass-execution-of-81-men-shows-urgent-need-to-abolish-the-death-penalty&#x2F;&quot;&gt;mass public
executions&lt;&#x2F;a&gt;,
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.amnesty.org&#x2F;en&#x2F;location&#x2F;middle-east-and-north-africa&#x2F;saudi-arabia&#x2F;report-saudi-arabia&#x2F;&quot;&gt;suppression of women
rights&lt;&#x2F;a&gt;,
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.hrw.org&#x2F;news&#x2F;2020&#x2F;07&#x2F;27&#x2F;saudi-arabia-yemeni-blogger-convicted-supporting-lgbt-rights&quot;&gt;persecution of gay
people&lt;&#x2F;a&gt;,
that kind of stuff.&lt;&#x2F;p&gt;
&lt;p&gt;My immediate instinct was that &quot;He&#x27;s probably very transphobic&quot;, and I was afraid that if
he found out, the working environment could get... unpleasant. Given that my queerness was
something very new to me I also did not have very much confidence in myself to know how to
handle such conflicts efficiently.&lt;&#x2F;p&gt;
&lt;p&gt;I also have quite the distrust of most institutions I am a part of. They have never really
managed to actually provide me with the guidance, support or protection that they claim to
extend to everyone. I blame primary school, but that&#x27;s a topic for another day. My point here
is that the onus has always been on me to come up with solutions for problems like these and
then convince higher-ups that those solutions were both correct and necessary. So I did not
count on the university of my supervisors to step in if I&#x27;d need help in a collegial conflict,
especially at the beginning. Looking back at how the rest of my PhD unfolded, I maintain that
this was the right decision.&lt;&#x2F;p&gt;
&lt;p&gt;Now, I did not fear for my physical safety around him. Even then I knew that even if those
are the kinds of beliefs he held, he wouldn&#x27;t get away with that, but the fact that train of
thought went through my head is already not a good sign.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-post-mortem&quot;&gt;A post-mortem&lt;&#x2F;h2&gt;
&lt;p&gt;Now, let me be immediately clear here, this was racism or at least xenophobia. There was no
indication except prior stereotypes that he would have been transphobic or homophobic. Maybe
he was even gay himself. It&#x27;s possible that he had fled Saudi Arabia for that exact reason,
I don&#x27;t know. The point is that I didn&#x27;t give him a fair chance.&lt;&#x2F;p&gt;
&lt;p&gt;The point where this get&#x27;s more complicated in my opinion is the fact that at least in my
perception, my &quot;safety&quot; was at stake. Due to traumas in the past, I thought that I would be left
to fend for myself if any conflict had presented itself. Because of that, the mere presence of
someone who might be disposed to conflict with me was cause for distress. Not that I really did
anything or behaved inappropriately towards him (at least as far as I know), but these kinds
of internal reactions are the seeds of worse behaviour and therefore deserve introspection in
my opinion.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not trying to excuse my behaviour, simply to make observations about it. Mental
health is not an excuse to treat people poorly or unfairly, as they say. Being queer, or
having any other form of oppression for that matter, does not in any way make it okay to
participate in other kinds of prejudice such as racism. It can make it harder at times,
but that does not mean we do not have to do the work. Not the least of which in this
case because &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Marsha_P._Johnson&quot;&gt;queer history&lt;&#x2F;a&gt; is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.historyisgaypodcast.com&#x2F;notes&#x2F;tag&#x2F;Harlem+Renaissance&quot;&gt;black
history&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I like the theory of intersectionality and although I don&#x27;t know nearly enough about it,
it rings very true to me whenever I hear about what it preaches. However, I rarely hear
about this flipside of intersectionality. That might again be because I am not very learned
in this field. Still, I think it&#x27;s important to recognise that one kind of intersection
can make you predisposed to handle other intersections much worse, (see also: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.urbandictionary.com&#x2F;define.php?term=Pick%20me%20gay&quot;&gt;Pick me
gays&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;And that&#x27;s basically it, there is no real resolution to this story. There is no &quot;well luckily I
realised what was going on and now I&#x27;ve resolved to never do a racism again&quot;. These are tendencies
that we have to be aware of and work against. I think it is the same reaction I have when I
have to walk past a group of Maroccan (looking) people on the street. It&#x27;s an instinctive fear
that part of my brain tries to convince me is legitimate. It&#x27;s a tendency that I still have,
although I am trying to minimise it. In the end, this behaviour is about me and I &lt;em&gt;want&lt;&#x2F;em&gt; to do
the work of resolving these conflicting beliefs within me. I say want to as opposed to having
to although both are true. Hopefully in the process, I hope I&#x27;ve given you an avenue to work
on for yourself as well.&lt;&#x2F;p&gt;
&lt;p&gt;P.S. Thank you to the wonderful Silvia Reis for proof reading this piece,
her comments gave me the confidence I needed to finally publish this.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Web Proof Reader</title>
        <published>2021-04-15T00:00:00+00:00</published>
        <updated>2021-04-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/projects/web-proof-reader/"/>
        <id>https://slowcoder.org/projects/web-proof-reader/</id>
        
        <content type="html" xml:base="https://slowcoder.org/projects/web-proof-reader/">&lt;p&gt;The Web Proof Reader is a tool I made to help me automate some of the work necessary for updating
this website. Things such as proofreading, accessibility checking and metadata validation. These
are things that I want to be done but am too lazy actually to carry out myself. You can
find the project on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;savente93&#x2F;web-proof-reader&quot;&gt;my GitHub&lt;&#x2F;a&gt;
if you want to learn more about it or use it. I&#x27;ve also made it available as a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pre-commit.com&#x2F;&quot;&gt;pre-commit
hook&lt;&#x2F;a&gt;. At the moment, it&#x27;s limited in scope but has already proven
helpful to me. For the time being, it only checks HTML files according to the structure of this
website and does not provide any configuration, but it&#x27;s been a fun learning experience.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>RMS, the FSF and the myth of FOSS</title>
        <published>2021-03-30T00:00:00+00:00</published>
        <updated>2021-03-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/the-myths-of-foss/"/>
        <id>https://slowcoder.org/blog/the-myths-of-foss/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/the-myths-of-foss/">&lt;p&gt;If you&#x27;re not into extremely niche tech news, you might understandably have no idea what that title
or any of the acronyms mean. Don&#x27;t worry; I&#x27;ll give a brief overview of the situation for context.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acronyms&quot;&gt;Acronyms&lt;&#x2F;h2&gt;
&lt;p&gt;Before we start talking about this subject, let me admit to you that I know next to nothing
about RMS or the FSF. I&#x27;m doing what reading I can for writing this blog post, but there may
be some unintentional falsehoods. With that out of the way, here is the relevant situation.&lt;&#x2F;p&gt;
&lt;p&gt;For brevity&#x27;s sake, I&#x27;ll quote from the RMS Wikipedia page since they do a better job of it
than I could:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Richard Matthew Stallman&lt;&#x2F;strong&gt;[...], also known by his initials, &lt;strong&gt;RMS&lt;&#x2F;strong&gt; is an American free
software movement activist and programmer. He campaigns for software to be distributed so that
its users receive the freedoms to use, study, distribute, and modify that software. Software
that ensures these freedoms is termed free software. Stallman launched the GNU Project, founded
the Free Software Foundation [FSF], developed the GNU Compiler Collection and GNU Emacs,
and wrote the GNU General Public License [GPL]&lt;&#x2F;p&gt;
&lt;p&gt;-
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Richard_Stallman&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Richard_Stallman&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;While there may be some slight difference, free software is mainly used interchangeably with
FOSS or Free and Open Source Software. Foss means that not only is a piece of software legally
obtainable for free, but so is the software code that is used to make it, meaning that you can
recreate, modify and redistribute it yourself. To understand the distinction: Firefox is FOSS,
whereas Google Chrome is not. That&#x27;s because while Google is free to use, Google has not released
all of the code that makes Chrome. On the other hand, Firefox is not only free to use, but you
can actually also obtain the code, compile it, and even make changes to it &lt;em&gt;and then distribute
the changed version&lt;&#x2F;em&gt;. This process is usually referred to as &quot;forking&quot; some software. Basically,
a fork of something is the software equivalent of legally distributed fanfiction.&lt;&#x2F;p&gt;
&lt;p&gt;Another point that I want to reiterate that to be termed &quot;free&quot; in this specific way, software
must guarantee &lt;em&gt;all&lt;&#x2F;em&gt; of the freedoms mentioned in the blurb above. Google Chrome is actually
another good example here. Chromium is a Google sanctioned fork of Google Chrome. The two browsers
share the vast majority of their code, however, since Google Chrome includes some extra code
compared to Chromium that is not open to the public, Chromium is FOSS, and Google Chrome is not.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;controversy&quot;&gt;Controversy&lt;&#x2F;h2&gt;
&lt;p&gt;Without going into detail about all of RMS&#x27; controversies or making any kind of
statement about him, RMS has been a controversial person for many years. He has been
accused of being &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;geekfeminism.wikia.org&#x2F;wiki&#x2F;EMACS_virgins_joke&quot;&gt;sexist&lt;&#x2F;a&gt;,
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;stallman.org&#x2F;archives&#x2F;2006-mar-jun.html&quot;&gt;pro-pedophelia&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;stallman.org&#x2F;archives&#x2F;2012-jul-oct.html&quot;&gt;critical of
child pornography laws&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;stallman.org&#x2F;archives&#x2F;2003-may-aug.html&quot;&gt;as far back as
2003&lt;&#x2F;a&gt; (referencing the 25 May post) amongst
others.&lt;&#x2F;p&gt;
&lt;p&gt;In 2019 &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Richard_Stallman#Comments_about_Jeffrey_Epstein_scandal&quot;&gt;RMS resigned&lt;&#x2F;a&gt;
from his positions at both MIT and the Free Software Foundation (FSF), following controversy
about his comments about rape concerning the preceding debate over Jeffrey Epstein.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-backlash&quot;&gt;The backlash&lt;&#x2F;h2&gt;
&lt;p&gt;In March 2021, RMS announced that he would be returning to the FSF board of directors,
sparking wide-scale outrage among the FOSS community. Shortly after the announcement, an &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rms-open-letter.github.io&#x2F;&quot;&gt;open
letter&lt;&#x2F;a&gt; was posted calling for RMS&#x27;s immediate resignation
and along with the entire FSF board of directors for allowing him to return, which has been
signed over 2500 times at the time of writing.&lt;&#x2F;p&gt;
&lt;p&gt;This decision to let RMS back onto the FSF board of directors has been
decried and denounced by many organisations such as the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fsfe.org&#x2F;news&#x2F;2021&#x2F;news-20210324-01.en.html&quot;&gt;Free Software
Foundation Europe&lt;&#x2F;a&gt;,
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ev.kde.org&#x2F;2021&#x2F;03&#x2F;24&#x2F;2021-03-24-on-the-reappointment-of-rms-fsf&#x2F;&quot;&gt;KDE e.V.&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rms-open-letter.github.io&#x2F;&quot;&gt;Mozilla&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;disclaimer&quot;&gt;Disclaimer&lt;&#x2F;h2&gt;
&lt;p&gt;Before we go on, let me reiterate two essential points. Firstly, as with all internet controversy,
there is also a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rms-support-letter.github.io&#x2F;&quot;&gt;counter controversy&lt;&#x2F;a&gt;. Therefore, let
me be clear again: I have no interest in making any public comment on the validity of either of
these points of view, as I don&#x27;t have the time, energy or willingness to construct a well-founded
opinion on the matter.&lt;&#x2F;p&gt;
&lt;p&gt;Secondly, I am about to criticise people and organisations for the things they say. That is
not because I do not share their values, points of view, bear them any ill will or even because
I think they are responsible for the things I&#x27;m about to criticise. Especially in the case of
the FSFE, which I might appear to address more directly. I love FOSS, and I think organisations
such as FSFE do incredible work. We good? Okay!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-to-my-actual-point&quot;&gt;Getting to my actual point&lt;&#x2F;h2&gt;
&lt;p&gt;In their news item about RMS being reinstated, the FSFE says:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;In 2019, Richard Stallman resigned as president and board member of the Free Software
Foundation. On 21 March 2021, Stallman announced he is a member of the board again. The FSFE
only learnt about that fact through his public announcement.&lt;&#x2F;p&gt;
&lt;p&gt;We believe this step and how it was communicated harms the future of the Free Software
movement. The goal of the software freedom movement is to empower all people to control technology
and create a better society for everyone. Free Software is meant to serve everyone regardless
of their age, ability or disability, gender identity, sex, ethnicity, nationality, religion
or sexual orientation. This requires an inclusive and diverse environment that welcomes all
contributors equally. The FSFE realises that we ourselves and the Free Software movement still
have to work hard to be that place where everyone feels safe and respected to participate in
it in order to fulfil the movement&#x27;s mission.&lt;&#x2F;p&gt;
&lt;p&gt;-
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fsfe.org&#x2F;news&#x2F;2021&#x2F;news-20210324-01.en.html&quot;&gt;https:&#x2F;&#x2F;fsfe.org&#x2F;news&#x2F;2021&#x2F;news-20210324-01.en.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The bit I want to call attention to is this: &lt;em&gt;&quot;Free Software is meant to serve everyone regardless
of their age, ability or disability, gender identity, sex, ethnicity, nationality, religion
or sexual orientation. This requires an inclusive and diverse environment that welcomes all
contributors equally.&quot;&lt;&#x2F;em&gt; I hate to say this, but while I 100% agree with this goal, FOSS as a
movement has never been inclusive or open to most people. This is true both on the development
and the use side of it, and I&#x27;ll address them one at a time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;people-who-can-use-foss&quot;&gt;People who can use FOSS&lt;&#x2F;h2&gt;
&lt;p&gt;While the &lt;em&gt;goal&lt;&#x2F;em&gt; of FOSS is indeed to &quot;serve everyone&quot;, it does not do so currently at all. Using
FOSS has an incredibly high barrier to entry, not the least of which that you need to know what
it actually is. In the age of adverts, data mining, and free trials, the difference between
FOSS and software you don&#x27;t pay for has become a lot harder to tell for a layperson. This is
partly because of the rise of software popularity like Google Chrome, which has a largely FOSS
codebase with only a few proprietary bits sprinkled in.&lt;&#x2F;p&gt;
&lt;p&gt;This next bit might sound derogatory or demeaning, and I don&#x27;t mean it in that way in the
slightest. Still, it is effortless for people like myself to astronomically overestimate
people&#x27;s capabilities when it comes to tech. Living with my parents again for a year has
reminded me of that. It&#x27;s not just a generational thing, though. At work, I&#x27;m teaching Python
to a colleague of mine. So far, the most challenging thing for her has been installing the
damn thing. The difference between an editor, a language, a terminal, an interpreter and a
programme is overwhelming. That&#x27;s not because she is stupid; on the contrary, she&#x27;s brilliant,
but the learning curve is just incredibly steep when talking about things like that.&lt;&#x2F;p&gt;
&lt;p&gt;As much as Nerds myself like to joke and scoff that, &quot;HTML is not even a programming language,
it&#x27;s only markup&quot;, the vast majority of people would panic if they saw the HTML this page
consists of. Again, I don&#x27;t mean to talk down to them, but it is tough for me and people like
me to keep that perspective in mind.&lt;&#x2F;p&gt;
&lt;p&gt;This also brings me nicely to another point: often, the most challenging thing about using FOSS
is just installing the damn thing. Most people don&#x27;t even know the difference between 32-bit
and 64-bit software, let alone having them need to install GCC 5.3 for the compilation step
but 8.9+ for the linking, using old tools that still support the plugin required for a memory
hack to work, all the while using install scripts that they don&#x27;t know how to run which don&#x27;t
even work because the wrong version of a system interpreter is earlier in their PATH than the
one they just installed. If you use FOSS regularly, I dare you to look me in the eye and tell
me you haven&#x27;t been in a situation like that at least once.&lt;&#x2F;p&gt;
&lt;p&gt;And that&#x27;s not to even start about the time investment needed to use FOSS. Let&#x27;s be honest here,
what you don&#x27;t pay for in money you pay for in time and patience when using FOSS. That&#x27;s because
FOSS is primarily made by people like me, for people like me, or in most cases, people who &lt;em&gt;are&lt;&#x2F;em&gt;
me. The vast majority of FOSS that I use I have either worked on or started using because I&#x27;ve
worked on it. There is definitely an incredible pleasure in making things that exactly do what
you need them to; I&#x27;m not decrying that. But when that is your goal, you don&#x27;t tend to focus
on ergonomics or stability because that&#x27;s more work you don&#x27;t see the benefit of (in most
cases). Those things are critical for other people, especially for people with a lower skill level.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;people-who-can-make-foss&quot;&gt;People who can make FOSS&lt;&#x2F;h2&gt;
&lt;p&gt;I have often heard that you should try and contribute to open-source software to get into
programming as a hobby. I think this is a terrible idea that is much more likely to turn people
away from programming altogether rather than to pull them in. There are more reasons for this
than I have time to get into, but I&#x27;ll highlight those that stand out to me.&lt;&#x2F;p&gt;
&lt;p&gt;The first reason for this is that there is no clear entry point and an enormous learning
curve. Whenever you are talking about a piece of software that is large enough for mainstream
people to find, you will find it full of specific tooling, code standards, frameworks, idiomatic
documents and heavy competition. The work that will be available to you as a beginner is usually
also quite tedious and situational, like minor bug fixes, formatting issues or translating
documentation. Unless you&#x27;re very determined, people will just bounce off that instantly, and
rightfully so. If you&#x27;re going to work on a smaller project, then you actually need a lot of
expertise to tell whether a project is even still alive, much less worth working on.&lt;&#x2F;p&gt;
&lt;p&gt;Another of the reasons is that the term &quot;Open Source Community&quot; is a misnomer. There exists no
such thing as the open-source community. At best, it is a collection of people interested in
open-source software, which is definitely not the same as a community.  Any group of people I
have ever seen around FOSS is either totally decentralised with almost no direct interaction
or centred around a monolithic oligarchy with total control over anything and everything. The
actual &quot;community&quot; part of it is never addressed beyond &quot;Here is our discord&#x2F;forum link,&quot; which,
let&#x27;s be honest, is a laughable standard to count as community building.&lt;&#x2F;p&gt;
&lt;p&gt;Even if FOSS can constitute a community, it is an incredibly toxic one. Just go onto any software
forum and mention any of the words &quot;Rust&quot;, &quot;Haskell&quot;, &quot;Electron&quot;, or &quot;PHP&quot;, and you will have
flame war content for the years to come. Angry nerds will jump down your throat after even just
hearing that you deign to use something as &quot;outdated&quot; as PHP. (disclaimer: even I&#x27;m somewhat prone
to this) FOSS is not a community; it is a proving ground at best and a toxic circle jerk at worst.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, people are left to fend for themselves, often to a fault. As an example, this is a
fairly common sentiment within FOSS circles in my experience:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Classic Unix documentation is written to be telegraphic but complete… The style assumes
an active reader, one who is able to deduce obvious unsaid consequences of what is said and who
has the self-confidence to trust those deductions. Read every word carefully because you will
seldom be told anything twice.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;- Eric Raymond, The art of UNIX programming.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;That&#x27;s not terribly inviting now, is it? Especially considering that what counts as &quot;obvious&quot; in
that sentence is &lt;em&gt;very&lt;&#x2F;em&gt; subjective. And it goes much further than that. People have no patience
for beginners. I am willing to bet money that 80% of the questions on Stackoverflow.com are of
the format:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Question: How do I do Blorb?&lt;&#x2F;p&gt;
&lt;p&gt;Answer: Don&#x27;t do Blorb, blorb is terrible, and anyone who uses it is stupid. Instead do Zurgub&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;(Fill in values for Blorb and Zurgub as relevant). If you&#x27;re lucky, you might even get an
explanation about why Blorb is terrible. I&#x27;m not saying that having standards for contributions
of requests are unreasonable, or if someone is trying to do something that is a known bad idea,
you shouldn&#x27;t tell them, but it is done in a very demeaning way.&lt;&#x2F;p&gt;
&lt;p&gt;There are also very rigid standards that get enforced, and I don&#x27;t just mean programming best
practices. For example, if your English isn&#x27;t excellent, you stand little to no chance in
FOSS. People are hostile towards that, and you are very unlikely to get any interaction on
whatever you produce, even if it&#x27;s reasonable under the surface.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s assuming you even have access to computers and the time and energy to learn any
of this. That means no school computers, smart devices and in many cases no Windows,
which is a real obstacle for a staggeringly large part of the global population. No
wonder that researchers have found, for example, that only &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1007&#x2F;978-3-642-33442-9_6&quot;&gt;1.5% of FOSS contributors are
female&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;my-own-part-in-this&quot;&gt;My own part in this&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;d call myself a mild veteran of FOSS. I&#x27;ve
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;getzola&#x2F;zola&#x2F;pull&#x2F;1218&quot;&gt;contributed&lt;&#x2F;a&gt;
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;getzola&#x2F;zola&#x2F;pull&#x2F;1219&quot;&gt;to&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;getzola&#x2F;zola&#x2F;pull&#x2F;1147&quot;&gt;a
few&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;wannesm&#x2F;PySDD&#x2F;pull&#x2F;20&quot;&gt;FOSS&lt;&#x2F;a&gt;
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ML-KULeuven&#x2F;problog&#x2F;pull&#x2F;30&quot;&gt;projects&lt;&#x2F;a&gt;
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitbucket.org&#x2F;wmkoolen&#x2F;squint&#x2F;pull-requests&#x2F;1&quot;&gt;and even&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dvente&#x2F;pyneg&quot;&gt;made
some&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dvente&#x2F;exp&quot;&gt;of my own&lt;&#x2F;a&gt;. I&#x27;m not
a true veteran in that my time and contributions to FOSS are somewhat limited compared to
the full-time giants (which I think is an unreasonable standard, but that&#x27;s a discussion for
another time). So I will be talking about this using myself as a standard. Not because I think
I&#x27;m particularly great in the &quot;If I can&#x27;t do it, it&#x27;s impossible&quot; kind of way, but because I
think I&#x27;m a reasonable upper bound. I can do many things with tech that laypeople simply cannot,
so I think it&#x27;s a fair comparison.&lt;&#x2F;p&gt;
&lt;p&gt;I struggle with a lot of the things I mentioned in this post before, from installing things
to dense documentation to lack of time and energy to use or otherwise interact with a piece of
FOSS. Now, Let me be clear: I love FOSS. I think it is fantastic, and it has come an incredibly
long way, but as is, it is failing at most of the things in its mission statement.&lt;&#x2F;p&gt;
&lt;p&gt;In a lot of cases, the things I mention come as a result of being free. It&#x27;s hard to expect
people to really commit to community building, robust testing and documenting and explaining
things time and time again to beginners when you realise that they are doing all of it in their
free time. But the other side of that coin is that it can often encourage a resentful userbase,
both in terms of end-users and developers. Of the projects I&#x27;ve worked on, I&#x27;ve gotten often
gotten frustrated by the interactions I had around them. Pull requests can sometimes take weeks
or months to get reviewed, let alone be merged; the demanding tone that maintainers use when
telling me to make specific changes or the fact that nobody says thank you are all frustrating
things to work with. This is, again, all reasonable from their perspective but still detrimental
to a good community.&lt;&#x2F;p&gt;
&lt;p&gt;As someone who has often been on both sides of the equation I&#x27;m describing, I empathise with
both sides. The main point I&#x27;m trying to make here is not that people are terrible (although
they sometimes are) but that the system does not incentivise the things we would like to see
at all. That&#x27;s a problem worth addressing, in my opinion.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-fancy-words&quot;&gt;Using fancy words&lt;&#x2F;h2&gt;
&lt;p&gt;I think most of my points come down to the fact that FOSS is essentially about &lt;em&gt;negative&lt;&#x2F;em&gt; freedoms,
and I think it should be more about &lt;em&gt;positive&lt;&#x2F;em&gt; freedom. Negative freedom means that you are not
to be obstructed in doing something. An example of negative freedom would be to start your own
business. Nobody should prevent you from doing so, but it is not required to help you do it in
any way either. A different kind of freedom is the freedom to access public spaces. If space is
public, then the owner of that space must make reasonable efforts to make sure you can access
those spaces. Although this is not official terminology, I like to think of them as passive
and active freedoms. Negative freedoms are passive because people need nearly not actively work
against you, and positive freedoms are active because you actively have to work to guarantee them.&lt;&#x2F;p&gt;
&lt;p&gt;My guess is that almost all of the freedoms mentioned in FOSS definitions are meant to be
passive. You&#x27;re not to be obstructed by legal barriers from using, studying or modifying
software. But the abysmal state in which almost all the user experiences of FOSS find themselves
mean that FOSS has very little positive freedom.&lt;&#x2F;p&gt;
&lt;p&gt;This is probably a controversial opinion, but in that sense, I think something like Discord is
much more accessible and open than GCC. Regardless of how much some people like to rail against
Discord, the fact of the matter is:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You can get a hold of it.&lt;&#x2F;li&gt;
&lt;li&gt;You can probably use it.&lt;&#x2F;li&gt;
&lt;li&gt;You can customise it reasonably effectively.&lt;&#x2F;li&gt;
&lt;li&gt;With some tinkering, there is a lot that a layperson can get done in, for example, making a
discord bot to help with community management.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Despite the source code for Discord not being available to the public, in some
ways,  it is much more accessible than some of the software that &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gcc.gnu.org&#x2F;&quot;&gt;&quot; [...] was
developed to be 100% free software, free in the sense that it respects the
user&#x27;s freedom.&quot;&lt;&#x2F;a&gt; even if Discord has some &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;privacy&#x2F;comments&#x2F;eiicah&#x2F;trawling_through_my_discord_data_package_after_35&#x2F;&quot;&gt;bad privacy
policies&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And you know what? I get that. The trick with positive freedom is that it&#x27;s hard to take that
one step at a time because if you take that to a logical conclusion, that would mean you&#x27;d have
to solve things like racism and global poverty, which is obviously a bit outside the scope of a
static website generator or whatever. My point is not that FOSS or the people around it should
solve these problems. We inherit much trouble around it from the societies we live in. But
this is an angle that has been neglected for a long time. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;small-tech.org&#x2F;&quot;&gt;Small Tech&lt;&#x2F;a&gt;
is actually the first party in tech that I know of that has come even close to addressing this.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll be honest I have no idea how to solve any of the problems I&#x27;m railing against. It&#x27;s
all hard. These are all generational problems in every sense of that word. But I hope that
by addressing this part of the conversation, I can help make that happen. I find community
building fascinating. Ironically, it is one of the things humanity has been doing the longest,
while at the same time still being one of the hardest things you can do. There is a universality
to both its accessibility and its difficulty that is impressive in a weird way.  I just hope we
can find ways of making FOSS more community focused so we can deliver on more of its promises
and thus be more open in the positive sense.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My wish list for Rust 2021</title>
        <published>2020-09-14T00:00:00+00:00</published>
        <updated>2020-09-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/my-rust-2021-wishlist/"/>
        <id>https://slowcoder.org/blog/my-rust-2021-wishlist/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/my-rust-2021-wishlist/">&lt;h2 id=&quot;tl-dr&quot;&gt;TL;DR&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;As someone unfamiliar with the ecosystem I want a better way of assessing the maturity of a
library to make prototyping easier&lt;&#x2F;li&gt;
&lt;li&gt;As a pragmatic DIY programmer I want a better cross-platform GUI experience in pure Rust that
doesn&#x27;t require JavaScript or browsers so I can make tools for non-tech users without having
to use complex build environments&lt;&#x2F;li&gt;
&lt;li&gt;As a data scientist, I want more robust&#x2F;ergonomic numeric computation and data wrangling
libraries so I can take advantage of Rust&#x27;s performance and correctness guarantees to improve
my simulations and data manipulation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;STL; DR:&lt;&#x2F;strong&gt; higher-level ergonomic integration and entry points, please.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;Before I launch into a more detailed discussion of the points that I&#x27;d like to see from Rust, I
wanted to say that I know I&#x27;m asking for a lot here. These things I will mention here I consider
a wish list in the loosest way possible. I understand these are huge things I am asking for,
and I am not skilled enough in Rust or project&#x2F;community management to assess whether these
things are attainable. I present them as things that would make me very happy to see.&lt;&#x2F;p&gt;
&lt;p&gt;Secondly, I think it&#x27;s a good idea to give a little background about myself for the context of
this blog post. If that doesn&#x27;t interest you, you can safely skip to the next heading.&lt;&#x2F;p&gt;
&lt;p&gt;I am primarily a data engineer and data analyst, but I also love other forms of programming in
my spare time. Sadly I don&#x27;t get to use Rust at my day job, which already takes up a lot of my
creative energy. That means that the times I code outside of that, I want to keep pragmatic. I
don&#x27;t have time to develop large, robust codebases, actively maintain the things I build
for very long, or (and in my opinion most importantly), spend much time setting up complex
development environments that use multiple languages. That has already caused me to give up on
a few projects which I find a shame.&lt;&#x2F;p&gt;
&lt;p&gt;The next point somewhat ties into the last. While I love learning new concepts and improving my
craft, there are a few things I have very little interest in learning: system&#x27;s programming,
other languages like JavaScript and frameworks in different languages like Qt. That is not
because I see no value in them, but because I don&#x27;t have the time for it. I have little enough
time left for programming my projects and taking things like learning new frameworks in other
languages makes it all too complex to understand effectively. I want to focus on Rust, not on
other languages.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, I want to tell you a bit about my preferences. I come to Rust primarily for its
correctness guarantees and helpful error messages. The compiler in Rust is unlike anything I&#x27;ve
ever seen in other places and in my opinion that is what makes it great. Things like performance,
low run time overhead and low-level access when needed is nice and cool, but that&#x27;s not why
I&#x27;m here. I&#x27;m here because Rust helps me write better code from the get-go.&lt;&#x2F;p&gt;
&lt;p&gt;With that preamble out of the way, there are the three points I&#x27;d love to see addressed in
Rust most.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;native-guis&quot;&gt;Native GUIs&lt;&#x2F;h2&gt;
&lt;p&gt;I use Linux, and a lot of the things I make are used via the command line. Clap is excellent,
and the Rust support for making things programmatically available via the command line is
good. However, some tasks, such as things that require visualisation or image manipulations that
aren&#x27;t very well suited to command-line interactions. Not only that, but sometimes I want to make
tools for people that aren&#x27;t as technically inclined. More specifically, people for whom the idea
of using a command-line induces severe anxiety. Building tools for them that have simple GUIs just
rolled into a single binary that doesn&#x27;t require extra setup would be incredibly powerful to me.&lt;&#x2F;p&gt;
&lt;p&gt;Now I&#x27;m aware that bindings from Rust exist for a lot of the big GUI frameworks like Qt, but
this has a few dealbreakers for me. First of all, I don&#x27;t know them and spending time learning
them takes time away from learning Rust, which I don&#x27;t want for obvious reasons. Secondly, and
more important to me, installing, setting up and compiling of projects with multiple languages
is COMPLICATED. As good as Rust&#x27;s FFIs are, they are still complicated, and even if those are
perfect, I have to deal with the tools on the other side. I have tried and failed many times
to get a project with Qt or webview going. The setup and the amount of extra tooling necessary
for those kinds of projects make it not worth it for me to use them on projects at my (small)
scale. I love that Rust has such robust integration tools and good FFIs. The cost of this,
unfortunately, is that the native rust solutions have been neglected somewhat and as someone
who isn&#x27;t versed in the standard options like JavaScript and doesn&#x27;t want to spend the time to
learn that as well, there are few options.&lt;&#x2F;p&gt;
&lt;p&gt;Next to the bindings, there are also a handful of GUI libraries written in pure Rust. Such
as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;maps4print&#x2F;azul&quot;&gt;Azul&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;redox-os&#x2F;orbtk&quot;&gt;orb-tk&lt;&#x2F;a&gt;,
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;linebender&#x2F;druid&quot;&gt;druid&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pistondevelopers&#x2F;conrod&quot;&gt;conrod&lt;&#x2F;a&gt;
and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;hecrj&#x2F;iced&quot;&gt;iced&lt;&#x2F;a&gt; but these all have problems of their own. The main thing
is that none of these libraries gives the impression that they will keep developing. I don&#x27;t mind
unstable APIs very much, most of the tools I use myself install from some dev branch. However,
missing features that I consider essential and incomplete documentation are bigger problems
than that.&lt;&#x2F;p&gt;
&lt;p&gt;Another problem is that GUI libraries or frameworks, by their nature, tend to be very complex
due to a very circular flow of information. While learning complex libraries in and of itself is
not a problem for me, if it does the job properly, having to learn &lt;em&gt;several&lt;&#x2F;em&gt; complex libraries
to assess which one does the job well enough is.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;more-high-level-computation-and-data-wrangling&quot;&gt;More high-level computation and data wrangling&lt;&#x2F;h2&gt;
&lt;p&gt;A lot of data science involves a Jupyter notebook and some python libraries for good exploration
and prototyping. That is unlikely to change, just because of the nature of interpreted vs
compiled languages and I don&#x27;t think it has to change. However, I would like Rust to become a
more significant part of my data science toolkit for various reasons. Not because I want one
language for everything, but because I think Rust has some genuine strengths to offer.&lt;&#x2F;p&gt;
&lt;p&gt;It comes back again to correctness. Rust has good options for data wrangling that I would love
to use. Algebraic enums, pattern matching, more robust mechanisms like Option and Result would
significantly improve the quality of data wrangling. It would help flesh out different edge cases,
consider what things are in scope and what isn&#x27;t, and how to handle things when they go wrong,
just like in regular code. However to make these an option I think we&#x27;d need more high-level
file manipulation for various file types like CSV. I&#x27;d imagine a kind of syntax like&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; data_set =
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  wrangling::read_csv(&amp;amp;file_path, |&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rec&lt;&#x2F;span&gt;&lt;span&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;validate&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;rec))?
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;map_over_successes&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;valid_rec&lt;&#x2F;span&gt;&lt;span&gt;| valid_rec.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;preprocess&lt;&#x2F;span&gt;&lt;span&gt;())
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;map_over_errors&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;invalid_rec&lt;&#x2F;span&gt;&lt;span&gt;| log!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;invalid record: {}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;,&amp;amp;invalid_rec))
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;collect&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;m glossing over many details here, but I&#x27;m taking some inspiration from something like the
&lt;code&gt;hash_map&lt;&#x2F;code&gt; and &lt;code&gt;or_insert_with&lt;&#x2F;code&gt;. I hope the idea is clear: Read something from a file, check if
it&#x27;s valid according to your logic. If it is, pre-process it, if not do whatever error handling
is appropriate. This kind of defensive programming would be golden for data wrangling.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, I would love to do my simulations in Rust. One of the most frustrating things in
Python when I move from just prototyping to a more robust exploration or simulation is when
the program runs for a long time. Then I get an &lt;code&gt;AttributeError: &#x27;int&#x27; object has no attribute &#x27;append&#x27;&lt;&#x2F;code&gt;, which in Rust would have been solved by a quick &lt;code&gt;cargo check&lt;&#x2F;code&gt;. Some tools, like &lt;code&gt;MyPy&lt;&#x2F;code&gt;
help with that sort of thing. However, I feel like that&#x27;s a band-aid rather than a real solution.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, it is when running more extended simulations or analyses with large models taking up
much memory that I think Rust&#x27;s strengths start to show themselves. Rust helps me write my code,
so it uses less memory than it would in Python. Therefore I can run more elaborate simulations
on my machine compared to when I was using Python that is a huge win.&lt;&#x2F;p&gt;
&lt;p&gt;Sadly numerics in Rust are... let&#x27;s say, awkward. I think the lack of &lt;code&gt;const&lt;&#x2F;code&gt; generics has
been a significant barrier for bigger libraries being written. Writing optimised code for fast
Fourier transforms simply outside my ability, and having to find a new library for every new
such thing is a large barrier.&lt;&#x2F;p&gt;
&lt;p&gt;Now I don&#x27;t want this post to turn into the reveal for arewenumpyyet.com nor similar ones for
libraries pandas, scipy or sklearn. I&#x27;m not saying that I want something that emulates those
libraries. They have their flaws (&lt;em&gt;cough&lt;&#x2F;em&gt; panda&#x27;s naming scheme &lt;em&gt;cough&lt;&#x2F;em&gt;) and some of the ways
they are designed would map onto the Rust paradigm quite poorly. But they do represent a standard
robust (enough) toolset that I am currently missing in Rust. I think that solidifying a reliable
default option for this kind of work would be huge for a lot of data science in Rust.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;picking-libraries&quot;&gt;Picking libraries&lt;&#x2F;h2&gt;
&lt;p&gt;Let me first say I love crates.io and how cargo works with it. Especially compared to something
like C++, it&#x27;s great. Both in terms of discoverability and accessibility. Both from a consumer
and publisher standpoint crates.io is a good platform as far as I am considered.&lt;&#x2F;p&gt;
&lt;p&gt;However, I do miss some better curation tools occasionally. Often on crates.io, I have much
trouble telling the difference between an obscure library and an unmaintained one. Another
problem which irks me is that there is much name-squatting on crates.io. These are by no means
problems unique to Rust. I realise that a lot of what I&#x27;m about to talk about here is a &quot;problem&quot;
that stems from Rust being an open and somewhat young platform. That is not something I want
to change. Rust being accessible to everyone is a good thing. However, I would like some better
mechanisms to assess whether a library is still usable.&lt;&#x2F;p&gt;
&lt;p&gt;A big problem with this is my relative lack of skill with Rust. When I am looking for a new
library in Python, the well-maintained ones usually have enough documentation and are simple
enough that I can pick it up and take it for a spin for a few minutes. The complexity of using
Rust means that it&#x27;s much harder for me to assess whether a library does not fit my use case or
whether I am misusing it. That is something that will solve itself over time for me specifically,
but that is a problem for more newcomers to the language and ecosystem. Sadly I don&#x27;t have a
solution to this one, but I imagine it is something other people struggle with as, so I hope
that by bringing it to the attention of people smarter than me we can further this cause somewhat.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;If I had to summarise this post, it is &quot;I need more high-level libraries for the things I want
to do&quot;. I love Rust, but I don&#x27;t have the time or energy to become enough of an expert in all
the things I want to do to use the low-level libraries that are out there. I would say that
Rust at the moment, has a solid foundation, but it is time to start building something beautiful
upon that foundation.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A quick and dirty DIY rsync for S3 websites</title>
        <published>2020-08-24T00:00:00+00:00</published>
        <updated>2020-08-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/a-diy-rsync-for-s3/"/>
        <id>https://slowcoder.org/blog/a-diy-rsync-for-s3/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/a-diy-rsync-for-s3/">&lt;p&gt;As you might know, this website is served to you from an S3 bucket which is great because I
don&#x27;t have to pay for computation that I don&#x27;t use because all my content is static. That does
mean that every time I want to make a change because, for example, I made a new blog post,
I have to re-upload the relevant files. Now the crucial thing to know here is that uploads
are significantly more expensive than downloads. What that means is that getting traffic for
my website is pretty cheap, but if I upload a lot of changed files that gets expensive. To
get an idea of what I mean, in the AWS Free Usage Tier you get in your first year of use, you
get 20,000 free downloads but only 2,000 uploads, an order of magnitude less. Until now that
workflow has been somewhat inefficient, and today I made a quick and dirty solution for it. In
the spirit of keeping this blog alive and also defeating perfectionism, I wanted to show you
that solution and the journey that got me there.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;my-old-workflow&quot;&gt;My old workflow&lt;&#x2F;h2&gt;
&lt;p&gt;For those of you unfamiliar with static website generators what happens is that I have some
content and template files on my local machine, and every time I want to make a change to the
website, the &lt;em&gt;entire website&lt;&#x2F;em&gt; gets re-rendered. That is necessary because as a static webpage
re-rendering, the entire thing is the only way to make a change like update links in index
pages. That is an important detail because it means that even if I don&#x27;t change the content
on files, it still gets a new creation timestamp in the file system.&lt;&#x2F;p&gt;
&lt;p&gt;The way that I used to upload the files to my S3 bucket is using the &lt;code&gt;aws&lt;&#x2F;code&gt; CLI utility. That
has a lot more functionality, but the part of it that I would always use was &lt;code&gt;s3 sync&lt;&#x2F;code&gt;. That
takes as input an &lt;code&gt;S3URI&lt;&#x2F;code&gt; and a folder path, and it will synchronise the two directories. It
decides which files to update based on the file size and the timestamp that the file was last
modified. Now, usually, this is fine, however since my site generator regenerates my entire
website every time I make a change, file sizes and creation dates can still vary even if I
didn&#x27;t make significant changes. Sometimes it can be tough to properly control things like
white pace when you generate web pages from templates. That means that I have to use a lot
more uploads than necessary, and that annoys me. It also helps me save a little bit of money,
especially while I&#x27;m still on the free usage tier.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily because I use version control (as are you right?) and I try to make a commission
every time I upload a new version, I have a local copy of the version that is on the web at
all times. I figured that this setup and workflow would be universal for people using a static
website generator, especially since it does require some technical know-how. So my first instinct
was to bake it right into the website generator itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;over-engineering-a-solution&quot;&gt;Over-engineering a solution&lt;&#x2F;h2&gt;
&lt;p&gt;If you know me, you&#x27;ll know that over-engineering is my superpower. Seriously, I will spend weeks
programming to save myself minutes of work if I don&#x27;t keep myself in check. So I happily set out
to try and integrate this idea into the site generator. Trying this, I immediately ran into two
problems: &lt;code&gt;git&lt;&#x2F;code&gt; and &lt;code&gt;s3&lt;&#x2F;code&gt;. While Rust is an excellent programming language, it&#x27;s still relatively
new and as such misses mature tools for dealing with many things, &lt;code&gt;git&lt;&#x2F;code&gt; and &lt;code&gt;s3&lt;&#x2F;code&gt; included. There
are tools out there to work with those systems, but they are for the vast majority either very
immature and unstable or very poorly documented. I am honestly surprised how poorly the &lt;code&gt;aws&lt;&#x2F;code&gt;
CLI is written given the massive technical weight behind it. One of the biggest problems I had
with the documentation of both of these systems was telling whether any piece of documentation
I was looking at was still relevant or deprecated. I&#x27;ll spare you the details, but seriously,
it was such a pain.&lt;&#x2F;p&gt;
&lt;p&gt;My next go-to was Python. I had already used the Python SDK for AWS &lt;code&gt;boto3&lt;&#x2F;code&gt;, and while still
had some of the same problems there as I did in Rust, I was a little more comfortable with that
tool. However, I wasn&#x27;t happy with the tooling that Python had available for interacting with
&lt;code&gt;git&lt;&#x2F;code&gt;. I&#x27;m not saying the library itself was horrible, but both the installation process and the
documentation for it were pretty bad. At this point, I was already getting pretty frustrated,
so I quickly moved on from that solution as well. Eventually, I very grumpily reached for the
tool I ended up sticking with bash.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kiss-or-keep-it-simple-sweety&quot;&gt;KISS or &quot;Keep it, simple sweety.&quot;&lt;&#x2F;h2&gt;
&lt;p&gt;Originally I had hoped to make something that integrated nicely with other systems I used,
and that was robust enough that I could give it to other people. However, but this point it was
starting to dawn on me that that was probably out of reach. I had run across the acronym KISS
a couple of times, which stands for &quot;Keep is simple sweety&quot; (usually it&#x27;s actually &quot;stupid&quot;
instead of &quot;sweety&quot;, but I like this version better). If you are searching for programming
help on the internet, you will inevitably run into this phrase. It&#x27;s a philosophy that says
things work best when they are simple and focused instead of elaborated and complicated so I
decided to go for a quick and dirty solution that would work for me, so I decided to make a
bash function to do the job.&lt;&#x2F;p&gt;
&lt;p&gt;To me bash is the programming equivalent of duck tape and fishing line, it&#x27;s great for quick
and dirty work, but it&#x27;s as crude as it is simple and it breaks very quickly, so I try to go
for it only as a last resort. The upshot of using bash is that I can use many tools like &lt;code&gt;git&lt;&#x2F;code&gt;
and the &lt;code&gt;aws&lt;&#x2F;code&gt; CLI directly, instead of having to rely on some intermediate product.&lt;&#x2F;p&gt;
&lt;p&gt;My first idea was to use &lt;code&gt;rsync&lt;&#x2F;code&gt;. &lt;code&gt;rsync&lt;&#x2F;code&gt; is a very well used and well-regarded package commonly
used in GNU systems. It&#x27;s made for remote backups and has quite sophisticated ways of determining
which files need to be updated and avoid unnecessary uploads. Sadly, as far as I could tell,
it is not compatible with the &lt;code&gt;S3&lt;&#x2F;code&gt; protocol, so that would not work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-diy-rsync&quot;&gt;A DIY rsync&lt;&#x2F;h2&gt;
&lt;p&gt;While &lt;code&gt;rsync&lt;&#x2F;code&gt; itself wasn&#x27;t going to work, I did want to use the same kind of idea, so I decided
to make a straightforward DIY solution that acted kinda the same. Circling back to my previous
statement, I realised that I could use &lt;code&gt;git diff HEAD --name-status&lt;&#x2F;code&gt; to figure out which files
were modified and how. That would tell simultaneously tell me which files I&#x27;d have to process
and what I had to do with them (upload for created or modified files, delete for removed files).&lt;&#x2F;p&gt;
&lt;p&gt;Because at this point I was going for quick and dirty I decide to use AWK to process the output
from &lt;code&gt;git&lt;&#x2F;code&gt; since the output format suited that quite nicely. After some trail and error I
settled on this command:&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;awk&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-awk &quot;&gt;&lt;code class=&quot;language-awk&quot; data-lang=&quot;awk&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;BEGIN&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;FS&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot; &amp;quot;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;^[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;M|A&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;printf &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;aws s3 cp &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$2&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;gsub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;root&amp;#39;\&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;,&amp;quot;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$2&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; s3:&#x2F;&#x2F;&amp;#39;$bucket&amp;#39;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$2&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; --dryrun &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;^&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;D&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;gsub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;root&amp;#39;\&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;,&amp;quot;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$2&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;print &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;aws s3 rm s3:&#x2F;&#x2F;&amp;#39;$bucket&amp;#39;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$2&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; --dryrun &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(in this the &lt;code&gt;--dryrun&lt;&#x2F;code&gt; is just for testing).&lt;&#x2F;p&gt;
&lt;p&gt;In case you don&#x27;t know AWK, this is a little programme that outputs the &lt;code&gt;cp&lt;&#x2F;code&gt; command if the input
line starts with an &lt;code&gt;M&lt;&#x2F;code&gt; (for modified) or and &lt;code&gt;A&lt;&#x2F;code&gt; (for added) and outputs the &lt;code&gt;rm&lt;&#x2F;code&gt; command if it
starts with a &lt;code&gt;D&lt;&#x2F;code&gt; (for delete). The &lt;code&gt;gsub&lt;&#x2F;code&gt; is to replace the local directory name that I passed in
because if I want to sync the directory &lt;code&gt;website&lt;&#x2F;code&gt; and git tells me to sync &lt;code&gt;website&#x2F;index.html&lt;&#x2F;code&gt;
then I need to execute &lt;code&gt;aws s3 cp website&#x2F;index.html s3:&#x2F;&#x2F;&amp;lt;BUCKETNAME&amp;gt;&#x2F;index.html&lt;&#x2F;code&gt; so we need
to strip the directory name.&lt;&#x2F;p&gt;
&lt;p&gt;This is done for every line that&#x27;s output by the previous git command. At this point all that
is necessary is to pipe those commands back to bash itself so it can execute them. Finally I
also wrapped all of this in a function so I could take the website directory and bucket name
as an input and a &lt;code&gt;git commit&lt;&#x2F;code&gt; at the end so I won&#x27;t forget to actually commit the changes I
just uploaded. The final function looks like this:&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;s3-update&lt;&#x2F;span&gt;&lt;span&gt;(){
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bucket&lt;&#x2F;span&gt;&lt;span&gt;=$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;root&lt;&#x2F;span&gt;&lt;span&gt;=$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span&gt; add . \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;      &amp;amp;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span&gt; diff HEAD&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --name-status &lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;root &lt;&#x2F;span&gt;&lt;span&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;      | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;awk  &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;BEGIN{FS=&amp;quot; &amp;quot;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        &#x2F;^[M|A]&#x2F; { printf &amp;quot;aws s3 cp &amp;quot;$2; gsub(&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;root&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;\&#x2F;&#x2F;,&amp;quot;&amp;quot;,$2); print&amp;quot; s3:&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bucket&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;&amp;quot;$2}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        &#x2F;^D&#x2F; {gsub(&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;root&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;\&#x2F;&#x2F;,&amp;quot;&amp;quot;,$2); print &amp;quot;aws s3 rm s3:&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bucket&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;&amp;quot;$2}&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sh
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span&gt; commit;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;some-quick-testing-and-benchmarks&quot;&gt;Some quick testing and benchmarks&lt;&#x2F;h2&gt;
&lt;p&gt;To wrap it all up I wanted to make sure that it had any benefit. I tested the function on this
website using this very blog post as a test case. With &lt;code&gt;find public | wc -l&lt;&#x2F;code&gt; I found out that
the whole website contains 216 files at the time of writing (including directories). Using the
&lt;code&gt;aws&lt;&#x2F;code&gt; CLI like I normally would:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;aws&lt;&#x2F;span&gt;&lt;span&gt; s3 sync &amp;lt;DIRNAME&amp;gt; s3:&#x2F;&#x2F;&amp;lt;BUCKETNAME&amp;gt; --dryrun | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;wc -l
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;it had decided that it would re-upload 93 files. However, my little function agreed that I&#x27;d
only need to upload 11 files. That is almost an order of magnitude lower. I am not quite sure
why the &lt;code&gt;aws&lt;&#x2F;code&gt; CLI decided that those would need to be updated, but I did manually verify with
the use of &lt;code&gt;diff&lt;&#x2F;code&gt; that some of the ones that my function didn&#x27;t select were indeed identical
to the ones that were already in the air. All in all, not the most elegant or robust solution,
but pretty good for about an evening of work.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A response to the UNESCO call for an ethical AI framework</title>
        <published>2020-04-23T00:00:00+00:00</published>
        <updated>2020-04-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/a-response-to-unsecos-call-for-ethics/"/>
        <id>https://slowcoder.org/blog/a-response-to-unsecos-call-for-ethics/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/a-response-to-unsecos-call-for-ethics/">&lt;p&gt;I want to start this blog post with a disclaimer. This blog post will be a response to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.un.org&#x2F;en&#x2F;chronicle&#x2F;article&#x2F;towards-ethics-artificial-intelligence&quot;&gt;this UNESCO
article&lt;&#x2F;a&gt;. It
might seem in this post that I am criticising UNESCO directly. That is not my intention. UNESCO
is an excellent independent body doing meaningful work.
Additionally, I&#x27;m well aware that the post I will be talking about is not a whitepaper, so I
understand that the scope is entirely different. However, I do think there are several points of
information missing in the post I am about to discuss. I hope to expand and contribute to this
conversation, both by proposing more specific issues I think the position should have addressed,
and highlight points where I take umbrage with the picture it paints and why. I hope you will
see this post as an attempt to add to the conversation, not detract from it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-call-for-an-ethical-framework&quot;&gt;A call for an ethical framework&lt;&#x2F;h2&gt;
&lt;p&gt;First off, I will start with the generally positive notes. First off, I am glad that UNESCO is
making this call. One of the things that they mention is that AI lacks in a unified effort to
create an ethical framework and that more strict coordination is needed to make a reasonable
attempt. It writes:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Many actors—businesses, research centres, science academies, United Nations Member States,
international organisations and civil society associations—are calling for an ethical framework
for AI development. While there is a growing understanding of the issues, related initiatives
need more robust coordination. This issue is global, and reflection on it must take place at
the worldwide level to avoid a &#x27;pick-and-choose&#x27; approach to ethics. Furthermore, an inclusive,
international policy, with the participation of United Nations funds, agencies and programmes,
is required if we are to find ways of harnessing AI for sustainable development.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;That is, hopefully obviously, correct. These things are so desperate and its applications so
diverse that a united effort is required. As it also points out, I think that UNESCO is a very
well positioned body to play a central role in this as they highlight themselves:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;UNESCO will be a full and active participant in this global conversation. Our organisation
has many years of experience in the ethics of science and technology.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;More specifically, I am glad that an independent body that is specifically not a tech company or
body is making these moves. I think that UNESCO will be able to pay more attention to the more
human side of AI, a perspective which is sorely lacking in my opinion, but that is something
for another post.&lt;&#x2F;p&gt;
&lt;p&gt;Another point that I am pleased to see included the focus on demographics that are traditionally
excluded:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;UNESCO priorities must also guide our international action in this area. It is essential to
ensure that Africa fully participates in transformations related to AI, not only as a beneficiary
but also upstream, contributing directly to its development. In terms of gender equality, we
must fight against the biases in our societies to guarantee that they are not reproduced in
AI applications.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;At this point, the impact of AI systems on people of colour has been &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.nature.com&#x2F;articles&#x2F;d41586-019-03228-6&quot;&gt;well
documented&lt;&#x2F;a&gt;. I wholeheartedly believe the
only way to solve this (and we should if AI is to have any right to exist in our society) is
to include more of the people that are being excluded. That will be in no means sufficient,
but it will be necessary, so I am happy to see this clause.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;caveats&quot;&gt;Caveats&lt;&#x2F;h2&gt;
&lt;p&gt;As a young data scientist, I am equal parts excited and sceptical of AI. I think it has enormous
potential, but not in the way that it is commonly discussed. That is where I want to start to
highlight some of the places where I think the call could have gone further. Again, this is
not meant as an attack on UNESCO but an attempt to contribute.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;education&quot;&gt;Education&lt;&#x2F;h3&gt;
&lt;p&gt;My first point of criticism is that the UNESCO post has fallen a little bit prey to the technology
hype train without critical examination, in my opinion. For example:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Education is already being profoundly transformed by AI. Very soon, the tools of education—the
way we learn, access knowledge and train teachers—will no longer be the same.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;But will it? Because I don&#x27;t think that it will, or at the very least it shouldn&#x27;t. I am not an
educational scholar, but as far as I can see, the primary form of formal education has changed
remarkably little since the industrial revolution. Subjects, modes of communication and ideas
about education maybe have changed and will continue to change, but in a more abstract sense, it
is still remarkably similar. We still get presented with information about a wealth of subjects,
and then we are usually asked to reproduce the information or apply it in very controlled settings.&lt;&#x2F;p&gt;
&lt;p&gt;If we look at the last educational revolution that I am aware of, the internet, we can see
that indeed education has changed in its delivery somewhat. Classes are done more online,
information is more readily available, the scope of education has changed as a result of it,
and as a result, education is changed shape. But is it fundamentally different than what it
was before? I don&#x27;t think so.&lt;&#x2F;p&gt;
&lt;p&gt;The same is true for AI. it has great potential to change the scope and mode of communication
of education, but I do think it is dangerous to assume that once AI enters the picture, nothing
of what came before still applies. AI is not the messiah; it is merely another tool. If anything,
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bryanalexander.org&#x2F;education-and-technology&#x2F;flipping-the-higher-ed-new-normal-from-synchronous-to-asynchronous-education&#x2F;&quot;&gt;COVID-19&lt;&#x2F;a&gt;
has done more to change education than AI has. I know tech companies are all too happy to promise
golden mountains, but I hope that UNESCO can exercise a bit more caution in with claims like
these in the future.&lt;&#x2F;p&gt;
&lt;p&gt;Yes, AI has the potential to change the way education is applied
radically. Still, equally, it will not change its essence, and those at the vanguard of tech
have a well-documented history of having the arrogance to think they can revolutionise fields they understand poorly.&lt;&#x2F;p&gt;
&lt;p&gt;So too does UNESCO offer no specifics on how AI is set to change education fundamentally. Again,
I know this is not a whitepaper. Still, it is this sort of unexamined &quot;assumption of impact&quot;
that can lead people to try and reinvent the wheel, taking away vital resources that the current
system so desperately needs. That is something that I would love to avoid, which is why I think
we ought to be careful to use the kind of language UNESCO uses in their post.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lack-of-specifics&quot;&gt;Lack of specifics&lt;&#x2F;h3&gt;
&lt;p&gt;Ethics is complicated. While I am not an ethics scholar, I do carry significant interest in
it. From my perspective, one of the most significant sources of difficulty is the dissonance
between the general and the specific. Do you do what is good because it is right regardless
of outcomes, or do the ends justify the means? You can find unintended consequences in almost
any ethical framework. All of this is to say, that doing ethics comes down to specifics. For
example, consider the trolley problem, an old thought experiment that has entered the mainstream
consciousness now that self-driving technology is coming closer than ever to the consumer. The
trolley problem is basically &lt;em&gt;entirely&lt;&#x2F;em&gt; comprised of specifics.&lt;&#x2F;p&gt;
&lt;p&gt;That is where I wish that the article had been a little bit more specific. I understand that
you can&#x27;t make specific promises in articles like these, but some ways aren&#x27;t much harder to
get into texts like these without going into a ton of detail. For example, when they write:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is essential to ensure that Africa fully participates in transformations related to AI,
not only as a beneficiary but also upstream, contributing directly to its development.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;While this is true, this gives no further information. For example, at which level should we
work to include Africa? Do we incentivise states, academic institutions, private corporations
or even individuals to contribute to AI? Should Africa be more involved with all AI endeavours
or just ones that directly affect it?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;it-s-a-start-but-one-that-has-been-made-before&quot;&gt;It&#x27;s a start, but one that has been made before&lt;&#x2F;h3&gt;
&lt;p&gt;These are questions that probably didn&#x27;t have hope of being addressed in this article, but
I think it would have been good to mention them. I believe that even if the answers to these
questions would be as vague as &quot;all&quot; or &quot;yes&quot;, I think it helps to mention that explicitly.&lt;&#x2F;p&gt;
&lt;p&gt;I think it is essential to address these things more explicitly because a lot of the problems
mentioned have solutions that will include far more than AI. For example:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Can freedom of action be guaranteed when our desires are anticipated and guided? How can we
ensure that social and cultural stereotypes are not replicated in AI programming, notably when
it comes to gender discrimination? Can these circuits be duplicated? Can values be programmed,
and by whom? How can we ensure accountability when decisions and actions are fully automated?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;To address any of these questions, much more will have to be addressed than just the
AI applications themselves. It will involve cultivating a more nuanced understanding of
discrimination in AI developers, changes to education, law and cultural experience.&lt;&#x2F;p&gt;
&lt;p&gt;While UNESCO is an excellent form to house the primary debates, these issues are too diverse
and far-reaching to be decided in those debates alone. Therefore I think it is critical to give
as much factual information to the people this article is addressing as possible. The fact is
that an article like this represents an implicit invitation to contribute to the discourse and
as such, I think it is essential too, in some way, address which issues are going to be addressed.&lt;&#x2F;p&gt;
&lt;p&gt;It is true that at the time of writing the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.unesco.org&#x2F;news&#x2F;unesco-appoints-international-expert-group-draft-global-recommendation-ethics-ai&quot;&gt;UNESCO think-tank is set to finish their first meeting
tomorrow&lt;&#x2F;a&gt;
so I expect that the discussion will continue. UNESCO will soon come
with more specifics on the issues that should be addressed and proposals
for potential solutions, but until then, this call for an ethical framework is just
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jef.eu&#x2F;jefnews&#x2F;calling-for-an-ethical-and-efficient-eu-policy-framework-on-artificial-intellige&#x2F;&quot;&gt;one&lt;&#x2F;a&gt;
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.bbc.com&#x2F;news&#x2F;technology-51673296&quot;&gt;more&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1903.03425.pdf&quot;&gt;among&lt;&#x2F;a&gt;
droves
of other calls.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Stop using those daft WiFi capture portals</title>
        <published>2020-04-08T00:00:00+00:00</published>
        <updated>2020-04-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/blog/stop-using-wifi-portals/"/>
        <id>https://slowcoder.org/blog/stop-using-wifi-portals/</id>
        
        <content type="html" xml:base="https://slowcoder.org/blog/stop-using-wifi-portals/">&lt;p&gt;Let&#x27;s talk about public WiFi, shall we? It&#x27;s been a while since having a WiFi network in a
public place has become somewhat standard in the places I&#x27;ve lived, especially if the site is
in the hospitality business like a cafe. Sometimes you&#x27;re lucky, and the network has a password
that the staff will tell you. However, more often than not these days, the WiFi will be an open,
unencrypted one and when you connect to it a browser with a login portal opens up. It&#x27;s become
common enough that nobody will bat an eye at it. This. Needs. To. Stop. And in this blog post,
I&#x27;m going to explain to you why.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;it-s-bad-for-security&quot;&gt;It&#x27;s bad for security&lt;&#x2F;h3&gt;
&lt;p&gt;First things first, these portals are &lt;em&gt;very&lt;&#x2F;em&gt; bad for security. First of all, because, at every
step of the authentication process, the WiFi is public, passwordless, and unencrypted, the
users of that network are entirely unprotected.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re not in CyberSec, I don&#x27;t think you grasp how easy it is to hack people
without proper protection. If your WiFi network is unencrypted, I can just come
in, set up a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;shop.hak5.org&#x2F;products&#x2F;wifi-pineapple&quot;&gt;WiFi Pineapple&lt;&#x2F;a&gt; and
listen in on &lt;em&gt;everyone&#x27;s&lt;&#x2F;em&gt; traffic. Some applications have proper &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Man-in-the-middle_attack&quot;&gt;man-in-the-middle
attack&lt;&#x2F;a&gt; protection, but by no means,
enough of them do not have to worry about this. This vulnerability is why people tell you to
&lt;em&gt;never-ever-ever-ever-ever&lt;&#x2F;em&gt; do essential tasks that require authentication over a public
unprotected WiFi network.&lt;&#x2F;p&gt;
&lt;p&gt;Even if you only use public WiFi for trivial matters, using unencrypted networks can still
be problematic. With the networking gear that comes with almost any Linux distribution and a
little bit of know-how, I can find out a surprising amount about everyone in who&#x27;s on that
network. One time I was helping a friend, who shall remain anonymous for obvious reasons,
with their WiFi at their office. I tried to log into their router to configure some things,
only to discover that I&#x27;d accidentally found and entered their NAS without them having told me
the password! I had access to all of their client data! (don&#x27;t worry I&#x27;ve made sure that hole
has been thoroughly plugged since.) If your security isn&#x27;t top-notch and you use unencrypted
networks, you&#x27;re at significant risk, even if you don&#x27;t do anything significant on it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;inviting-hackers&quot;&gt;Inviting hackers&lt;&#x2F;h3&gt;
&lt;p&gt;Very often those networks are called something along the lines of &lt;code&gt;BTHub-Tj5Qr_&lt;&#x2F;code&gt; or
&lt;code&gt;KPN-39AVD&lt;&#x2F;code&gt; or whatever naming scheme your default provider has. First of all, this is
just a bad look; it looks unprofessional. But second of all, it makes you a prime target
for hackers. Nothing screams &#x27;password to the admin account is probably &lt;code&gt;admin&lt;&#x2F;code&gt;&#x27; like
a WiFi network with the default network name. Let me tell you friend, 50% of hacking is
knowing how to pick your target, and that unaltered WiFi name is an advertisement to come
and try the first three things that come to mind if you&#x27;re a hacker. If it didn&#x27;t have
a decent chance of landing me in hot legal water, I probably would have tried some basic
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.cloudflare.com&#x2F;learning&#x2F;security&#x2F;glossary&#x2F;what-is-penetration-testing&#x2F;&quot;&gt;penetration-testing&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;it-teaches-actively-bad-security-practices&quot;&gt;It teaches actively bad security practices&lt;&#x2F;h3&gt;
&lt;p&gt;The use of these portals actively tampers with adequate security and teaches users lousy security
practices. Things like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kb.iu.edu&#x2F;d&#x2F;anjv&quot;&gt;SSL and TSL&lt;&#x2F;a&gt;, which are security protocols
your devices use to secure your traffic behind a password, are designed to be tamper-proof,
i.e. prevent all of the stuff I mentioned above. They detect when someone in the middle modifies
the data you&#x27;re sending and flashes big bright red warning signs if they do and with good
reason! So every time you go to a website that uses HTTPS, which is thankfully increasingly
common thanks to things such as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;letsencrypt.org&#x2F;&quot;&gt;Let&#x27;s Encrypt&lt;&#x2F;a&gt;, the router and your
device will both throw a hissy-fit because their intentions are misaligned.&lt;&#x2F;p&gt;
&lt;p&gt;However, that is precisely what these portals do. They capture your traffic, alter the connection
and address that gets returned and ask you to provide copious amounts of information (we&#x27;ll
get back to the information bit in a second). The point is that this is probably exactly what
a hacker would do, so you are training people to do exactly all the things you don&#x27;t want them
to do and also ignore every possible warning sign!&lt;&#x2F;p&gt;
&lt;p&gt;Incidentally, if you struggle with this, some charming internet folks taught
me that you could pretty reliably find the portal by going to one of these
websites: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;example.org&quot;&gt;example.org&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;calmuniqueserenepeace.neverssl.com&#x2F;online&#x2F;&quot;&gt;neverssl.com&lt;&#x2F;a&gt;,
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;detectportal.firefox.com&#x2F;&quot;&gt;detectportal.firefox.com&lt;&#x2F;a&gt;. Since those websites will never
use HTTPS, they will redirect you to the correct page without throwing up warning signs; it&#x27;s
worked so far in my experience.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;it-disrupts-applications-that-don-t-have-an-entire-browser-attached&quot;&gt;It disrupts applications that don&#x27;t have an entire browser attached&lt;&#x2F;h3&gt;
&lt;p&gt;Additionally, it provides a problem for applications that don&#x27;t have their browser
inbuild. Applications like that are much more common than you would think, even on
laptops. For example, if I am working on some code and not using the web for anything
else, many applications still have to access the internet for brief periods. For example,
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;cargo&#x2F;&quot;&gt;Cargo&lt;&#x2F;a&gt;, Rust&#x27;s package and compiler manager, pulls a dependency
tree from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;&quot;&gt;Crates.io&lt;&#x2F;a&gt; every time I compile something. Neither Cargo nor the
router that&#x27;s making the login portal was designed to handle this case. And it is surprisingly
difficult to find the damn portal if it doesn&#x27;t redirect you properly.&lt;&#x2F;p&gt;
&lt;p&gt;One of those things that don&#x27;t work correctly with those portals are &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.privateinternetaccess.com&#x2F;pages&#x2F;buy-a-vpn&#x2F;1218buyavpn?invite=U2FsdGVkX19vWIhXW3sc7IB9jVtkOngxXMnW3cEsXws%2Cxy1bTELLYl8ywVSikyHQM3XYBJE&quot;&gt;Virtual Private Networks
(VPN)&lt;&#x2F;a&gt;.
These are things that you can use to both encrypt and anonymise your internet traffic, as I
do whenever I&#x27;m out and about. However, as previously mentioned, the WiFi portal acts just
like a hacker would, so obviously, my VPN doesn&#x27;t like that. However, the router won&#x27;t let me
do anything else. So if you encounter one of these while the VPN is on, then you enter a state
where they both continuously try to redirect you to their sources making the internet virtually
unusable until you resolve the situation. I don&#x27;t think that I have to explain how having to
turn off a security feature to use some infrastructure is a bad thing.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;it-s-terrible-for-privacy&quot;&gt;It&#x27;s terrible for privacy&lt;&#x2F;h3&gt;
&lt;p&gt;The login portals that I have seen come in three main varieties:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The tracker&lt;&#x2F;li&gt;
&lt;li&gt;The collector&lt;&#x2F;li&gt;
&lt;li&gt;The completely redundant one&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I&#x27;ll address them in reverse order.&lt;&#x2F;p&gt;
&lt;p&gt;The first issue is the completely redundant one. These portals do nothing except make you tick a
box that essentially says &quot;I won&#x27;t do anything illegal&quot;. While I am in no way a legal expert,
I think that there must be a clause in the law stating that you can&#x27;t be held responsible
if someone does something illegal with your infrastructure without your knowledge. OR, it is
something that isn&#x27;t dismissed with such an easy-to-fool measure. Just stop it.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;who-cares-it-s-just-a-date-of-birth&quot;&gt;Who cares? It&#x27;s just a date of birth&lt;&#x2F;h4&gt;
&lt;p&gt;Secondly, there is a collector. This one collects some basic info about you like name, date of
birth, gender and email. I will momentarily take off my CyberSec hat and put on both my data
science engineer hat and my privacy advocacy hat, to tell you that &lt;em&gt;this is dangerous&lt;&#x2F;em&gt;. You
might think that&#x27;s over the top of me to say but stick with me for a moment.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t think many people realise how incredibly sensitive something like your date of birth
is. First of all, which should be fairly obvious, is that it&#x27;s non-renewable. You can&#x27;t get
a new one if it gets compromised. But you might say &quot;who cares if someone knows my date of
birth?&quot;. If that is you, I have one thing to say to you: That&#x27;s where you&#x27;re wrong kiddo!&lt;&#x2F;p&gt;
&lt;p&gt;I can do an enormous amount with your date of birth. Here&#x27;s the thing, maybe on its own it&#x27;s
not that useful, but it&#x27;s a critical piece of connecting information. The reason they tell you
never to reuse passwords is that if some website that has lousy security gets compromised,
&lt;em&gt;everything&lt;&#x2F;em&gt; gets compromised. The first thing hackers do when they find your password is
to go and try it on pretty much any service they can find you. This process works similarly
with data, except that you &lt;em&gt;can&#x27;t&lt;&#x2F;em&gt; renew your data. Imagine two data breaches have separate
information. I can use your date of birth, together with some other statistics that are &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;scikit-learn.org&#x2F;stable&#x2F;index.html&quot;&gt;very
widely available&lt;&#x2F;a&gt;, to link that data together,
and the more information I have, the easier it gets to guess more data correctly.&lt;&#x2F;p&gt;
&lt;p&gt;To give you an idea of how easy this would be to do, I was assessing a company where I wanted
to work as a data scientist a couple of months ago. The company shall remain unnamed, but
the assessment was &quot;here are some fairly mundane data about a bunch of people, &lt;em&gt;build a model
that identifies this person&lt;&#x2F;em&gt;&quot;. I had a week to do this. So, yes, your date of birth getting
compromised is a big deal.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;and-for-what&quot;&gt;And for what?&lt;&#x2F;h4&gt;
&lt;p&gt;So here&#x27;s the thing about all of this data. First of all, I&#x27;m 90% sure that 80% of the places
that ask you for this kind of information to use their WiFi don&#x27;t have proper security in place
to be handling data like this. I am not a legal expert so I don&#x27;t know how the GDPR deals with
this, but I smell more non-compliance than you&#x27;d think.&lt;&#x2F;p&gt;
&lt;p&gt;Second of all, they don&#x27;t need it. They plainly don&#x27;t need it. There is no good reason for
them to have to know your date of birth, your gender, your name or anything to give you WiFi
access. I&#x27;ll get to the ones that use it to track you next, but suffice it to say that WiFi
worked just five before these portals became standard. Having functioning WiFi is (or should be)
and expected part of doing business these days. If you offer a service in your place of business,
I am allowed to expect that it adheres to proper safety standards, just like hygiene.&lt;&#x2F;p&gt;
&lt;p&gt;Some people might say, &quot;well they use it for marketing&quot;, to which my answer is &quot;no, they don&#x27;t&quot;. If
these places can&#x27;t be bothered to rename their WiFi network, I&#x27;m almost sure that they don&#x27;t
have the proper infrastructure or know how to set up a half-decent marketing campaign. One
other option for them would be to sell the data at which point I&#x27;d like to refer you back to
the date-of-birth argument above.&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, I don&#x27;t want to turn this into a gender&#x2F;race discussion necessarily. Still, I do think
it is worth to point out that this puts up unnecessary barriers to people who have conditions
including but not limited to:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Being non-binary&lt;&#x2F;li&gt;
&lt;li&gt;Preferring a different name or pronouns&lt;&#x2F;li&gt;
&lt;li&gt;Having a name you can&#x27;t spell with ASCII encoding (having proper UTF-8 handling is shockingly
rare)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Finally, there is the last kind of portal, which is the tracker. This one goes through some
effort to identify you, usually by asking for a valid email, social media account or even in
some cases, a phone number. These are the only ones that give me some kind of assurance that
they know what they are doing. I still think they have no darn business snooping around in
my life just so I can check my email, but at least they seem to show they have some security
savviness. Very often these are big chains like Costa, or O2 which brings with it it&#x27;s own host
of privacy concerns. Have I talked to you yet about dates of birth and how big a deal they are?&lt;&#x2F;p&gt;
&lt;p&gt;At this point for me, usually, one of two scenarios plays out. First of all, if the network
allows identification through email, I fat-finger everything. Very often they&#x27;ll try and force
you to link a social media account but if you look around there usually is an email option. I
can&#x27;t tell you how many times I&#x27;ve been &lt;code&gt;Ms alvnq;&#x2F;aef20 fjoiv2&lt;&#x2F;code&gt; born 01-01-1904 with email
&lt;a href=&quot;mailto:none-of-your-damn-business@temp-mail.org&quot;&gt;none-of-your-damn-business@temp-mail.org&lt;&#x2F;a&gt;. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;temp-mail.org&#x2F;en&#x2F;&quot;&gt;Disposable email services&lt;&#x2F;a&gt;
are surprisingly easy to use once you know about them, and there&#x27;s not a good way around
them for the portals since those serviced do accept email properly. If that&#x27;s not an option,
I usually leave. I like working in cafes, but not enough to put up with that kind of invasiveness.&lt;&#x2F;p&gt;
&lt;p&gt;Now, after reading all this, you might say &quot;But Sam! they are just serving coffee, they can&#x27;t
be expected to know all this!&quot; to which is say &quot;yes, you&#x27;re right!&quot;. I don&#x27;t expect baristas
or even business holders to be security experts or be able to hire one just to set up shop. But
there is a straightforward way to solve this, which is to follow these three simple steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Rename your WiFi network&lt;&#x2F;li&gt;
&lt;li&gt;Use a WPA2 password&lt;&#x2F;li&gt;
&lt;li&gt;Stop using those daft WiFi capture portals&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>PyNeg</title>
        <published>2020-04-02T00:00:00+00:00</published>
        <updated>2020-04-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/projects/pyneg/"/>
        <id>https://slowcoder.org/projects/pyneg/</id>
        
        <content type="html" xml:base="https://slowcoder.org/projects/pyneg/">&lt;p&gt;A Python library for simulating automated negotiations. If you wanna jump in straight, it is available on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;savente93&#x2F;pyneg&quot;&gt;Github&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pypi.org&#x2F;project&#x2F;pyneg&#x2F;&quot;&gt;&lt;code&gt;pip&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;r&#x2F;savente&#x2F;pyneg&quot;&gt;DockerHub&lt;&#x2F;a&gt;. The Docker image comes with all optional requirements installed, but the &lt;code&gt;pip&lt;&#x2F;code&gt; version requires some extra installation steps to use the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;wannesm&#x2F;PySDD&quot;&gt;PySDD&lt;&#x2F;a&gt; dependency.&lt;&#x2F;p&gt;
&lt;p&gt;PyNeg was developed during the writing of my &lt;a href=&quot;https:&#x2F;&#x2F;slowcoder.org&#x2F;projects&#x2F;pyneg&#x2F;publications&#x2F;acop&#x2F;index.md&quot;&gt;ACOP&lt;&#x2F;a&gt; paper. The only other known library for simulating automated negotiation was &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;ii.tudelft.nl&#x2F;genius&#x2F;&quot;&gt;Genius&lt;&#x2F;a&gt;. This library was quite mature as it was used in all of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;ii.tudelft.nl&#x2F;nego&#x2F;node&#x2F;7&quot;&gt;Automated Negotiating Agents Competition (ANAC)&lt;&#x2F;a&gt;. However, it did also have some drawbacks, namely that it was in Java instead of Python. While I am proficient in Java, it does lack a lot of the analyses tools I use and inter-language communication is always something that I try to avoid whenever possible. Additionally, I knew that down the line I wanted to incorporate &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;dtai.cs.kuleuven.be&#x2F;problog&#x2F;&quot;&gt;Problog&lt;&#x2F;a&gt; into it, which is considerably more comfortable with Python given that there is already a ProbLog package on PyPi. Another reason was that Genius included many infrastructures that made it difficult for me to set up the kinds of scenarios that I wanted. All of these things taken together led me to decide to write my library in Python, the only one at the time of writing as far as I am aware. That also helped me understand the actual mechanics of automated negotiation a lot better. Below I&#x27;ll talk a bit about some extra perks I managed to get out of writing a library from scratch.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;design-philosophy&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#design-philosophy&quot;
   aria-label=&quot;Anchor link for: design-philosophy&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Design philosophy&lt;&#x2F;h3&gt;
&lt;p&gt;A native Pythonista will probably look at the code of PyNeg and give me some side-eye afterwards. I will admit it&#x27;s not written in very idiomatic Python, that is partly deliberately.  I started my programming career in C++ and used that for the majority of my formative programming years, after which I switched to Java before I got into Python. So even though Python is my primary language, for now, there are some concepts that I&#x27;ve never really been able to let go of, most notably static typing, and object orientation. While Python doesn&#x27;t natively support type annotations, there is an excellent library that does an excellent job of that: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;mypy-lang.org&#x2F;&quot;&gt;MyPy&lt;&#x2F;a&gt;, which I have used to annotate the entire library. While it has caused a few odd pieces of code, it has helped me stay sane throughout the debug phase, so overall I think it&#x27;s a win.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, while I was working on this library, I was also learning &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt; as a hobby and precisely the idea of composition over inheritance resonated with me. That, together with a few other concepts I integrated into the library might lead to some unusual coding styles, but I personally really like the way it turned out.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;decentralised-communication-loops&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#decentralised-communication-loops&quot;
   aria-label=&quot;Anchor link for: decentralised-communication-loops&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Decentralised communication loops&lt;&#x2F;h4&gt;
&lt;p&gt;Because the research group I was working with did much work on coalitional and decentralised settings, there was quite a bit of talk about integrating this work into different projects along the way. For example, there was the idea that I might collaborate on a Reinforcement Learning project, one of my colleagues, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lauradarcy&quot;&gt;Laura D&#x27;Arcy&lt;&#x2F;a&gt; was developing. That meant that fairly early on, I decided that I wanted the communication loop to be decentralised. What I mean by that is that there is no external structure that has to manage the communication between the agents actively. All the outer system did was set up the negotiations, set up the agents and tell them to start the negotiation. While I didn&#x27;t have time to implement it, this has the nice perk that it would be relatively easy to extend the current code to be able to handle multi-to-multi party negotiations or let the negotiation agents work asynchronously.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;composition-over-inheritance&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#composition-over-inheritance&quot;
   aria-label=&quot;Anchor link for: composition-over-inheritance&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Composition over inheritance&lt;&#x2F;h4&gt;
&lt;p&gt;I tend to think in a very object-oriented way, which has its drawbacks. For example, in the library, there are many different kinds of tasks an agent can and can&#x27;t do, but here I will focus on three specific ones:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Base (B) vs Constraint aware (C)&lt;&#x2F;li&gt;
&lt;li&gt;Probabilistic (P) vs Deterministic (D)&lt;&#x2F;li&gt;
&lt;li&gt;Linear (L) vs Non-Linear&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If you want to make any pair of combinations of those traits an option, you almost inevitably end up with a dependency tree that looks a bit like this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;..&#x2F;pyneg-diagram.svg&quot; alt=&quot;A tree visualising the inheritance&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The biggest problems with this is that:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The tree will grow exponentially as you add more traits&lt;&#x2F;li&gt;
&lt;li&gt;You either end up with unnecessary duplication (&lt;code&gt;L+C+D&lt;&#x2F;code&gt; vs &lt;code&gt;C+L+D&lt;&#x2F;code&gt;), or you have to make a
very arbitrary decision about what lives where.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;That is where the idea of composition instead of inheritance comes into play. Instead of building agents into a rigid dependency tree like that, we define components that can or can&#x27;t do certain things. Rust has an elegant &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;riptutorial.com&#x2F;rust&#x2F;example&#x2F;22917&#x2F;inheritance-with-traits&quot;&gt;&lt;code&gt;Trait&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; system to deal with this. I tried to emulate that to a certain degree, though it was a bit harder to do that in Python. The idea is that an &lt;code&gt;Agent&lt;&#x2F;code&gt; has an &lt;code&gt;Engine&lt;&#x2F;code&gt; that does all of the reasoning, while the &lt;code&gt;Agent&lt;&#x2F;code&gt; itself only has to deal with the communication. We can then build different &lt;code&gt;Engine&lt;&#x2F;code&gt; classes that can be any of the combinations above, instead of having to make an entirely separate class for these kinds of agents we implement the pieces into an engine, and that can work with any of the other components within the library. It did mean I had to make a few empty passthrough classes to make them play nicely with MyPy, but overall I like the result.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;easy-extendibility&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#easy-extendibility&quot;
   aria-label=&quot;Anchor link for: easy-extendibility&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Easy extendibility&lt;&#x2F;h4&gt;
&lt;p&gt;This part is a bit of an extension to the previous point, but because of the kinds of comparisons that I wanted to do, I also wanted to make sure that it was as easy as possible to create new types of agents with different kinds of properties. If someone wants to make another type of agent, all they have to do is provide an implementation for the &lt;code&gt;Engine&lt;&#x2F;code&gt; class, which is what they&#x27;d have to do and make a simple factory function, and that&#x27;s it! Pretty neat right?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>This website</title>
        <published>2020-02-15T00:00:00+00:00</published>
        <updated>2020-02-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slowcoder.org/projects/this-website/"/>
        <id>https://slowcoder.org/projects/this-website/</id>
        
        <content type="html" xml:base="https://slowcoder.org/projects/this-website/">&lt;p&gt;&lt;strong&gt;TL;DR this website = A rust static site generator + S3 + CloudFront&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This website turned out to be quite the project for me, so on this page, I&#x27;ll give you a bit
of a behind-the-scenes.&lt;&#x2F;p&gt;
&lt;p&gt;When I began dreaming this place up, I had a few things that I wanted to keep in mind:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cost.&lt;&#x2F;strong&gt; I don&#x27;t have a lot of money or income right now, and I don&#x27;t expect the website to
get much traffic, so keeping costs down was an absolute must. 8£ a month for a traditional
hosting solution might not sound that bad, except for something that I expect to be visited
maybe a couple of times a month when I don&#x27;t have an income it kind of is.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Customisability.&lt;&#x2F;strong&gt; I&#x27;m a tinkerer, and I like things to be the way I like them.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;No ads or unwanted popups.&lt;&#x2F;strong&gt; I value experience and aesthetics and ads, and popups make
that impossible. I also think good content is its marketing, so I don&#x27;t think I need them.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Blog (optional).&lt;&#x2F;strong&gt; I&#x27;ve tried to keep a blog once or twice before and while I enjoyed it,
and keep thinking of things I want to write about, I also really struggled to stay consistent
on that front. Therefore, if it would be possible to have a blog with this website, that would
be a nice bonus, but not a deal-breaker.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backend&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#backend&quot;
   aria-label=&quot;Anchor link for: backend&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Backend&lt;&#x2F;h2&gt;
&lt;p&gt;Given the criteria above, I decided pretty quickly that this website was going to be a static
one since it is pretty much the only solution that fits the above criteria. Since I do everything
locally and upload the result, I can set up whatever toolchain I want as long at it all outputs
valid HTML at the end. I&#x27;ll talk more about the one I picked in the next section, but suffice
to say I&#x27;m thrilled with it.&lt;&#x2F;p&gt;
&lt;p&gt;Static websites are also much cheaper to maintain than traditional dynamic websites. Partly
because of size, partly because they don&#x27;t need any computing resources. This website is, at
time of writing, around 8.3 MB, with the vast majority of that consisting of logos, pictures
and other static resources like PDFs. Another point is that I only need to pay for storage
instead of a whole server. All you&#x27;re doing when you visit this website is requesting a file,
instead of having a server do all sorts of calculations and creating the files it sends you on
the fly. That also has the added benefit that the site loads fast!&lt;&#x2F;p&gt;
&lt;p&gt;It also came with a lot of other added benefits. First of all, privacy and security, mainly
yours to be specific. I wanted something that would log as little as possible. There are many
reasons for this, such as &quot;You can&#x27;t leak any data, when you don&#x27;t have any data&quot;. For example,
GDPR is enforcing stricter regulations on websites, keeping logs and other data costs money,
and the more moving parts you have to a website, the harder it is to make it secure. I don&#x27;t
want to be implicated in another security scandal, and I don&#x27;t have enough working hours to
monitor this space actively. But I also wanted this because I believe in only collecting what
that you need. One of the oldest adages in both computer science and statistics is:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Garbage in, garbage out&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This website has a very minimal amount of javascript that all runs in your browser, and at the
moment, it doesn&#x27;t take any input or log anything. If you do those things that give hackers
more opportunity to do weird things you didn&#x27;t consider, so my best defence is just not doing
any of that.&lt;&#x2F;p&gt;
&lt;p&gt;That is all part of a sort of life philosophy I try to follow.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Get what you need, but not more than that&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;That makes things easier to maintain, (though I have been known to overengineer thing from time to
time I&#x27;ll admit) and is overall better for the environment. Technology is still advancing rapidly,
but I don&#x27;t think that the way we treat things like storage and computation is sustainable. Let
us start looking at things like efficiency again instead of just raw performance.&lt;&#x2F;p&gt;
&lt;p&gt;This static website is all I need, and so I wanted to limit myself to that. That helps me
maintain the darn thing, keep costs low, and make sure I don&#x27;t become part of the next privacy
scandal. Pretty good deal, right?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;picking-a-static-site-generator&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#picking-a-static-site-generator&quot;
   aria-label=&quot;Anchor link for: picking-a-static-site-generator&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Picking a static site-generator&lt;&#x2F;h3&gt;
&lt;p&gt;So now that I&#x27;d decided to use a static site generator, I had to pick one. Can&#x27;t be that hard,
right? Well, not exactly. I went through quite a few options. There are a lot of them out
there such as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jekyllrb.com&#x2F;&quot;&gt;Jekyll&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sphinx-doc.org&#x2F;en&#x2F;master&#x2F;&quot;&gt;Sphinx&lt;&#x2F;a&gt;,
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ghost.org&#x2F;&quot;&gt;Ghost&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.gatsbyjs.org&#x2F;&quot;&gt;Gatsby&lt;&#x2F;a&gt;,  &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gohugo.io&#x2F;&quot;&gt;Hugo&lt;&#x2F;a&gt;
and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.getzola.org&#x2F;&quot;&gt;Zola&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;My first consideration was that I wanted a stack that I knew somewhat. I knew I was going to
customise pretty much everything heavily. Therefore knew I&#x27;d already had to dive back into HTML
and CSS, so I wanted to spend as little time as possible learning new languages&#x2F;toolchains. That
already cut out Ghost, Jekyll and Gatsby.&lt;&#x2F;p&gt;
&lt;p&gt;Secondly, I wanted something with a healthy ecosystem. Because this is just a side project,
I can&#x27;t spend too much time on it, so while I often don&#x27;t mind taking a DIY approach to stuff,
I knew that that would prove fatal for a project like this. That limited my options quite a
bit since healthy ecosystems are rare, especially when you&#x27;re a hipster like me.&lt;&#x2F;p&gt;
&lt;p&gt;Sphinx I already had some experience with, since that is what I&#x27;m using to document my python
project PyNeg @&#x2F;blog&#x2F;pyneg&#x2F;index.md. Still, I find it very cumbersome to use, especially if
customisation is involved. It&#x27;s hard to get at the internals or interact with it in different ways
than strictly intended, and I got put off by that prospect. Additionally, I find it relatively
slow and let&#x27;s be honest; I don&#x27;t want to have to wait for my dopamine thank you very much.&lt;&#x2F;p&gt;
&lt;p&gt;That left me pretty much with Hugo and Zola. Hugo, I liked it. I had already used it once before
to make another website. It was fast, customisable, has a healthy ecosystem with lots of themes
and extensions and some excellent QoL features. Initially, I thought I&#x27;d go with that and started
my work with it. I&#x27;m not super familiar with Go, but enough that I was willing to give it a try.&lt;&#x2F;p&gt;
&lt;p&gt;Overall I liked Hugo, except for one thing. The templating engine it uses drove me crazy. Mostly
the inconsistent scoping and the weird prefix syntax that was applied very selectively put me off.&lt;&#x2F;p&gt;
&lt;p&gt;So I finally settled on Zola, and so far I&#x27;m pleased with it. It&#x27;s written in
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt;, which means that it&#x27;s pretty darn fast. I&#x27;ve also been
interested in Rust for a while now, so I figured making this in something that uses Rust might
help me get into that more. What&#x27;s more, the community and documentation are good enough that
I find it very usable, and the templating engine is robust and consistent sufficient for my
liking. So there we go, Zola, it is!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hosing&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot;
   href=&quot;#hosing&quot;
   aria-label=&quot;Anchor link for: hosing&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Hosing&lt;&#x2F;h3&gt;
&lt;p&gt;Next was the hosting. I knew this was going to be the most significant source of cost, so I
took quite a while to decide on this. I thought about self-hosting for a bit, but I eventually
decided that would mean too much overhead and too little downtime. I also didn&#x27;t want to go
with any of the free hosting services because of my concerns mentioned above about security,
privacy, ads and popups. If you put your stuff on someone else&#x27;s platform that is generally
very hard to control, ask any Youtuber about COPPA. I also still believe in the saying that
&quot;if you don&#x27;t pay for something, you&#x27;re the product&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;I also wanted something away from recommendation algorithms. Just something I can point to
when someone asks me about my work. I don&#x27;t expect to build a following, and that is what most
services are focused on.&lt;&#x2F;p&gt;
&lt;p&gt;That leads me quite quickly to cloud hosting. For this, I had three main
contenders. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;&quot;&gt;AWS&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.digitalocean.com&#x2F;&quot;&gt;DigitalOcean&lt;&#x2F;a&gt; and
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.exoscale.com&#x2F;&quot;&gt;ExoScale&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;ExoScale is a relatively small (relatively mind you) Swiss competitor to AWS. The advantage
of them is that they are an EU based company, meaning they are bound by EU regulations and at
least theoretically not bound by foreign governments. The problem with them was that I couldn&#x27;t
figure out how to host a static website on it, which was a bit of a problem. Another problem was
that their pricing came in tiers, meaning that if I wanted to upgrade from one website to two,
I&#x27;d have to spring for a lot more infrastructure which I didn&#x27;t like. The&lt;&#x2F;p&gt;
&lt;p&gt;So the final race was between DigitalOcean and AWS. With this, it ultimately came down to
pricing. DigitalOcean has reasonable pricing, but they start you off at a minimum of 5$ per
month for 250GB, which is astronomically more than I need. In contrast, AWS has pay-as-you-go,
so that&#x27;s what I eventually decided on. Right now, this website is served from a simple S3
bucket which costs me less than a dollar per month, pretty neat right?&lt;&#x2F;p&gt;
&lt;p&gt;The final piece of the puzzle is that I added AWS&#x27; CloudFront, a content delivery network. I
would have just not taken this step since I don&#x27;t expect the demand for this website to be that
high or widely spread, but using CloudFront was the only way I could have the website be served
over HTTPS instead of HTTP and I was quite adamant that I wanted HTTPS.&lt;&#x2F;p&gt;
&lt;p&gt;One added benefit of using AWS is that it&#x27;s an industry standard so that can go on my CV as
well. It also gives me easy integration with other AWS services such as AWS Lambda, which I am
planning to use to have this website also serve content security policies, but that is a story
for another day.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
